From e6c14293111b4bc286c127bc37587ea978d6bc49 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Sun, 1 Oct 2023 19:45:19 +0100 Subject: [PATCH] LibGfx: Check bounds of color table accesses in BMPLoader Previously, it was possible to crash the decoder by crafting a file with invalid color table index values. --- Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp index 0f87c8b44d..4a6d4c39b0 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp @@ -1292,8 +1292,10 @@ static ErrorOr decode_bmp_pixel_data(BMPLoadingContext& context) u8 mask = 8; while (column < width && mask > 0) { mask -= 1; - auto color_idx = (byte >> mask) & 0x1; + size_t color_idx = (byte >> mask) & 0x1; if (context.is_included_in_ico) { + if (color_idx >= context.color_table.size()) + return Error::from_string_literal("Invalid color table index"); auto color = context.color_table[color_idx]; context.bitmap->scanline(row)[column++] = color; } else { @@ -1309,8 +1311,10 @@ static ErrorOr decode_bmp_pixel_data(BMPLoadingContext& context) u8 mask = 8; while (column < width && mask > 0) { mask -= 2; - auto color_idx = (byte >> mask) & 0x3; + size_t color_idx = (byte >> mask) & 0x3; if (context.is_included_in_ico) { + if (color_idx >= context.color_table.size()) + return Error::from_string_literal("Invalid color table index"); auto color = context.color_table[color_idx]; context.bitmap->scanline(row)[column++] = color; } else { @@ -1329,6 +1333,8 @@ static ErrorOr decode_bmp_pixel_data(BMPLoadingContext& context) u32 low_color_idx = byte & 0xf; if (context.is_included_in_ico) { + if (high_color_idx >= context.color_table.size() || low_color_idx >= context.color_table.size()) + return Error::from_string_literal("Invalid color table index"); auto high_color = context.color_table[high_color_idx]; auto low_color = context.color_table[low_color_idx]; context.bitmap->scanline(row)[column++] = high_color; @@ -1348,6 +1354,8 @@ static ErrorOr decode_bmp_pixel_data(BMPLoadingContext& context) u8 byte = streamer.read_u8(); if (context.is_included_in_ico) { + if (byte >= context.color_table.size()) + return Error::from_string_literal("Invalid color table index"); auto color = context.color_table[byte]; context.bitmap->scanline(row)[column++] = color; } else {