summaryrefslogtreecommitdiff
path: root/Libraries/LibGfx
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-11-19 12:13:30 -0500
committerAndreas Kling <kling@serenityos.org>2020-11-19 21:21:45 +0100
commita8318b15a70b12aa298a7fab264275dd1f41b256 (patch)
tree38191854b9d932caf8dbf144ad266cf6ad004f9c /Libraries/LibGfx
parent129a0666cb407f0657354022b0946afc1340ce66 (diff)
downloadserenity-a8318b15a70b12aa298a7fab264275dd1f41b256.zip
LibGfx: Check for read failures after every read in jpg loader
This doesn't fix all the issues found by the fuzzer, but it fixes many of them. When running this Meta/Lagom/Fuzzers/FuzzJPGLoader -jobs=24 -workers=24 \ ../Base/res/html/misc/jpgsuite_files/ for 10 minutes on my machine, the fuzzer foudn 2 crashers, but after this change it finds just ... 2. But with different stacks! This just fixes ASSERT()s, so it's not security critical, but ASSERT()s still crash the programs decoding JPGs, and crashing less is nice even if it's not a security concern.
Diffstat (limited to 'Libraries/LibGfx')
-rw-r--r--Libraries/LibGfx/JPGLoader.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp
index f990ed05f4..69569322ff 100644
--- a/Libraries/LibGfx/JPGLoader.cpp
+++ b/Libraries/LibGfx/JPGLoader.cpp
@@ -629,6 +629,8 @@ static bool read_reset_marker(InputMemoryStream& stream, JPGLoadingContext& cont
return false;
}
context.dc_reset_interval = read_be_word(stream);
+ if (stream.handle_any_error())
+ return false;
return true;
}
@@ -667,6 +669,8 @@ static bool huffman_table_reset_helper(HuffmanTableSpec& src, JPGLoadingContext&
static bool read_huffman_table(InputMemoryStream& stream, JPGLoadingContext& context)
{
i32 bytes_to_read = read_be_word(stream);
+ if (stream.handle_any_error())
+ return false;
if (!bounds_okay(stream.offset(), bytes_to_read, context.data_size))
return false;
bytes_to_read -= 2;
@@ -711,6 +715,8 @@ static bool read_huffman_table(InputMemoryStream& stream, JPGLoadingContext& con
for (u32 i = 0; i < total_codes; i++) {
u8 symbol = 0;
stream >> symbol;
+ if (stream.handle_any_error())
+ return false;
table.symbols.append(symbol);
}
@@ -777,6 +783,8 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
return false;
stream >> context.frame.precision;
+ if (stream.handle_any_error())
+ return false;
if (context.frame.precision != 8) {
#ifdef JPG_DEBUG
dbg() << stream.offset() << ": SOF precision != 8!";
@@ -785,7 +793,11 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
}
context.frame.height = read_be_word(stream);
+ if (stream.handle_any_error())
+ return false;
context.frame.width = read_be_word(stream);
+ if (stream.handle_any_error())
+ return false;
if (!context.frame.width || !context.frame.height) {
#ifdef JPG_DEBUG
dbg() << stream.offset() << ": ERROR! Image height: " << context.frame.height << ", Image width: "
@@ -796,6 +808,8 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
set_macroblock_metadata(context);
stream >> context.component_count;
+ if (stream.handle_any_error())
+ return false;
if (context.component_count != 1 && context.component_count != 3) {
#ifdef JPG_DEBUG
dbg() << stream.offset() << ": Unsupported number of components in SOF: "
@@ -808,6 +822,8 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
ComponentSpec& component = context.components[i];
stream >> component.id;
+ if (stream.handle_any_error())
+ return false;
if (i == 0)
context.has_zero_based_ids = component.id == 0;
component.id += context.has_zero_based_ids ? 1 : 0;
@@ -840,6 +856,8 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
}
stream >> component.qtable_id;
+ if (stream.handle_any_error())
+ return false;
if (component.qtable_id > 1) {
#ifdef JPG_DEBUG
dbg() << stream.offset() << ": Unsupported quantization table id: "
@@ -884,9 +902,14 @@ static bool read_quantization_table(InputMemoryStream& stream, JPGLoadingContext
if (element_unit_hint == 0) {
u8 tmp = 0;
stream >> tmp;
+ if (stream.handle_any_error())
+ return false;
table[zigzag_map[i]] = tmp;
- } else
+ } else {
table[zigzag_map[i]] = read_be_word(stream);
+ if (stream.handle_any_error())
+ return false;
+ }
}
if (stream.handle_any_error())
return false;
@@ -1165,6 +1188,8 @@ static bool parse_header(InputMemoryStream& stream, JPGLoadingContext& context)
}
for (;;) {
marker = read_marker_at_cursor(stream);
+ if (stream.handle_any_error())
+ return false;
// Set frame type if the marker marks a new frame.
if (marker >= 0xFFC0 && marker <= 0xFFCF) {
@@ -1246,6 +1271,8 @@ static bool scan_huffman_stream(InputMemoryStream& stream, JPGLoadingContext& co
continue;
if (current_byte == 0x00) {
stream >> current_byte;
+ if (stream.handle_any_error())
+ return false;
context.huffman_stream.stream.append(last_byte);
continue;
}
@@ -1255,6 +1282,8 @@ static bool scan_huffman_stream(InputMemoryStream& stream, JPGLoadingContext& co
if (marker >= JPG_RST0 && marker <= JPG_RST7) {
context.huffman_stream.stream.append(marker);
stream >> current_byte;
+ if (stream.handle_any_error())
+ return false;
continue;
}
#ifdef JPG_DEBUG