LibGUI+LibGfx+WindowServer: Sanity check window size dimensions

Previous to this commit, if a `Window` wanted to set its width or height
greater than `INT16_MAX` (32768), both the application owning the Window
and the WindowServer would crash.

The root of this issue is that `size_would_overflow` check in `Bitmap`
has checks for `INT16_MAX`, and `Window.cpp:786` that is called by
`Gfx::Bitmap::create_with_anonymous_buffer` would get null back, then
causing a chain of events resulting in crashes.

Crashes can still occur but with `VERIFY` and `did_misbehave` the
causes of the crash can be more readily identified.
This commit is contained in:
Matthew Jones 2021-06-02 15:06:59 -06:00 committed by Linus Groh
parent 839aad6e5b
commit ea4116f5bd
Notes: sideshowbarker 2024-07-18 16:59:16 +09:00
3 changed files with 9 additions and 2 deletions

View file

@ -788,8 +788,11 @@ OwnPtr<WindowBackingStore> Window::create_backing_store(const Gfx::IntSize& size
// FIXME: Plumb scale factor here eventually.
auto bitmap = Gfx::Bitmap::create_with_anonymous_buffer(format, buffer, size, 1, {});
if (!bitmap)
if (!bitmap) {
VERIFY(size.width() <= INT16_MAX);
VERIFY(size.height() <= INT16_MAX);
return {};
}
return make<WindowBackingStore>(bitmap.release_nonnull());
}

View file

@ -58,7 +58,7 @@ static bool size_would_overflow(BitmapFormat format, const IntSize& size, int sc
if (size.width() < 0 || size.height() < 0)
return true;
// This check is a bit arbitrary, but should protect us from most shenanigans:
if (size.width() >= 32768 || size.height() >= 32768 || scale_factor < 1 || scale_factor > 4)
if (size.width() >= INT16_MAX || size.height() >= INT16_MAX || scale_factor < 1 || scale_factor > 4)
return true;
// In contrast, this check is absolutely necessary:
size_t pitch = Bitmap::minimum_pitch(size.width() * scale_factor, format);

View file

@ -363,6 +363,10 @@ Messages::WindowServer::SetWindowRectResponse ClientConnection::set_window_rect(
dbgln("ClientConnection: Ignoring SetWindowRect request for fullscreen window");
return nullptr;
}
if (rect.width() > INT16_MAX || rect.height() > INT16_MAX) {
did_misbehave(String::formatted("SetWindowRect: Bad window sizing(width={}, height={}), dimension exceeds INT16_MAX", rect.width(), rect.height()).characters());
return nullptr;
}
if (rect.location() != window.rect().location()) {
window.set_default_positioned(false);