From 2311e28d63acc8cce8fcfe3c2fa1d721a7c66c82 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 19 Oct 2023 22:10:53 +0100 Subject: [PATCH] LibGfx/BMPLoader: Mitigate potential overflows when decoding bitmap DIB --- Tests/LibGfx/TestImageDecoder.cpp | 3 ++- .../test-inputs/ico/oss-fuzz-testcase-63357.ico | Bin 0 -> 63 bytes .../Libraries/LibGfx/ImageFormats/BMPLoader.cpp | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 Tests/LibGfx/test-inputs/ico/oss-fuzz-testcase-63357.ico diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index b0071da3199..35f2915ba10 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -73,7 +73,8 @@ TEST_CASE(test_ico_malformed_frame) { Array test_inputs = { TEST_INPUT("ico/oss-fuzz-testcase-62541.ico"sv), - TEST_INPUT("ico/oss-fuzz-testcase-63177.ico"sv) + TEST_INPUT("ico/oss-fuzz-testcase-63177.ico"sv), + TEST_INPUT("ico/oss-fuzz-testcase-63357.ico"sv) }; for (auto test_input : test_inputs) { diff --git a/Tests/LibGfx/test-inputs/ico/oss-fuzz-testcase-63357.ico b/Tests/LibGfx/test-inputs/ico/oss-fuzz-testcase-63357.ico new file mode 100644 index 0000000000000000000000000000000000000000..8e0374d49610276eaf9dc5c035afe63d6c5a8902 GIT binary patch literal 63 lcmZQzU<5)1D9~hJU=Rah4IqYzF)}DHFeCB7;vhZ<0|17;1a1HT literal 0 HcmV?d00001 diff --git a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp index 0122ddd726b..86bd6b32a8e 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp @@ -820,12 +820,12 @@ static ErrorOr decode_bmp_dib(BMPLoadingContext& context) u8 header_size = context.is_included_in_ico ? 0 : bmp_header_size; - if (context.file_size < (u8)(header_size + 4)) + if (context.file_size < header_size + 4u) return Error::from_string_literal("File size too short"); InputStreamer streamer(context.file_bytes + header_size, 4); - u32 dib_size = streamer.read_u32(); + u64 dib_size = streamer.read_u32(); if (context.file_size < header_size + dib_size) return Error::from_string_literal("File size too short"); @@ -837,7 +837,7 @@ static ErrorOr decode_bmp_dib(BMPLoadingContext& context) // NOTE: If this is a headless BMP (embedded on ICO files), then we can only infer the data_offset after we know the data table size. // We are also assuming that no Extra bit masks are present - u32 dib_offset = dib_size; + u64 dib_offset = dib_size; if (!context.is_included_in_ico) { if (context.data_offset < header_size + 4u) return Error::from_string_literal("Data offset too small");