Skip to content

Instantly share code, notes, and snippets.

@nico
Created September 8, 2020 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nico/3a0340ff233b3d1c8299533188038645 to your computer and use it in GitHub Desktop.
Save nico/3a0340ff233b3d1c8299533188038645 to your computer and use it in GitHub Desktop.
commit 0c783ec6a639401153d96de1f4bc6ec8117c409c
Author: Nico Weber <thakis@chromium.org>
Date: Sun Jul 19 19:49:54 2020 -0400
fix one ppm fuzzer issue and two jpeg issues, all harmless DoS
diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp
index 57772534d..03f7b2822 100644
--- a/Libraries/LibGfx/JPGLoader.cpp
+++ b/Libraries/LibGfx/JPGLoader.cpp
@@ -293,9 +293,16 @@ bool build_macroblocks(JPGLoadingContext& context, Vector<Macroblock>& macrobloc
{
for (u32 cindex = 0; cindex < context.component_count; cindex++) {
auto& component = context.components[cindex];
+
+ if (component.dc_destination_id >= context.dc_tables.size())
+ return false;
+ if (component.ac_destination_id >= context.ac_tables.size())
+ return false;
for (u8 vfactor_i = 0; vfactor_i < component.vsample_factor; vfactor_i++) {
for (u8 hfactor_i = 0; hfactor_i < component.hsample_factor; hfactor_i++) {
u32 mb_index = (vcursor + vfactor_i) * context.mblock_meta.hpadded_count + (hfactor_i + hcursor);
+ //if (mb_index >= macroblocks.size())
+ //return false;
Macroblock& block = macroblocks[mb_index];
auto& dc_table = context.dc_tables[component.dc_destination_id];
@@ -573,6 +580,8 @@ static bool read_reset_marker(BufferStream& stream, JPGLoadingContext& context)
return false;
}
context.dc_reset_interval = read_be_word(stream);
+ if (stream.handle_read_failure())
+ return false;
return true;
}
@@ -619,6 +628,8 @@ static bool read_huffman_table(BufferStream& stream, JPGLoadingContext& context)
for (u32 i = 0; i < total_codes; i++) {
u8 symbol = 0;
stream >> symbol;
+ if (stream.handle_read_failure())
+ return false;
table.symbols.append(symbol);
}
@@ -680,13 +691,19 @@ static bool read_start_of_frame(BufferStream& stream, JPGLoadingContext& context
return false;
stream >> context.frame.precision;
+ if (stream.handle_read_failure())
+ return false;
if (context.frame.precision != 8) {
dbg() << stream.offset() << ": SOF precision != 8!";
return false;
}
context.frame.height = read_be_word(stream);
+ if (stream.handle_read_failure())
+ return false;
context.frame.width = read_be_word(stream);
+ if (stream.handle_read_failure())
+ return false;
if (!context.frame.width || !context.frame.height) {
dbg() << stream.offset() << ": ERROR! Image height: " << context.frame.height << ", Image width: "
<< context.frame.width << "!";
@@ -695,6 +712,8 @@ static bool read_start_of_frame(BufferStream& stream, JPGLoadingContext& context
set_macroblock_metadata(context);
stream >> context.component_count;
+ if (stream.handle_read_failure())
+ return false;
if (context.component_count != 1 && context.component_count != 3) {
dbg() << stream.offset() << ": Unsupported number of components in SOF: "
<< context.component_count << "!";
@@ -705,6 +724,8 @@ static bool read_start_of_frame(BufferStream& stream, JPGLoadingContext& context
ComponentSpec& component = context.components[i];
stream >> component.id;
+ if (stream.handle_read_failure())
+ return false;
if (i == 0)
context.has_zero_based_ids = component.id == 0;
component.id += context.has_zero_based_ids ? 1 : 0;
@@ -733,6 +754,8 @@ static bool read_start_of_frame(BufferStream& stream, JPGLoadingContext& context
}
stream >> component.qtable_id;
+ if (stream.handle_read_failure())
+ return false;
if (component.qtable_id > 1) {
dbg() << stream.offset() << ": Unsupported quantization table id: "
<< component.qtable_id << "!";
@@ -771,6 +794,8 @@ static bool read_quantization_table(BufferStream& stream, JPGLoadingContext& con
if (element_unit_hint == 0) {
u8 tmp = 0;
stream >> tmp;
+ if (stream.handle_read_failure())
+ return false;
table[zigzag_map[i]] = tmp;
} else
table[zigzag_map[i]] = read_be_word(stream);
@@ -1123,6 +1148,8 @@ static bool scan_huffman_stream(BufferStream& stream, JPGLoadingContext& context
continue;
if (current_byte == 0x00) {
stream >> current_byte;
+ if (stream.handle_read_failure())
+ return false;
context.huffman_stream.stream.append(last_byte);
continue;
}
@@ -1132,6 +1159,8 @@ static bool scan_huffman_stream(BufferStream& stream, JPGLoadingContext& context
if (marker >= JPG_RST0 && marker <= JPG_RST7) {
context.huffman_stream.stream.append(marker);
stream >> current_byte;
+ if (stream.handle_read_failure())
+ return false;
continue;
}
dbg() << stream.offset() << String::format(": Invalid marker: %x!", marker);
commit 2ce32012acc59c9d2e21db3bc88159ec613e3e7c
Author: Nico Weber <thakis@chromium.org>
Date: Sun Jul 19 20:38:30 2020 -0400
fix 3 more jpeg DoSs (all harmless), now ooms after a while of fuzzing
diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp
index 03f7b2822..788e75919 100644
--- a/Libraries/LibGfx/JPGLoader.cpp
+++ b/Libraries/LibGfx/JPGLoader.cpp
@@ -588,6 +589,8 @@ static bool read_reset_marker(BufferStream& stream, JPGLoadingContext& context)
static bool read_huffman_table(BufferStream& stream, JPGLoadingContext& context)
{
i32 bytes_to_read = read_be_word(stream);
+ if (stream.handle_read_failure())
+ return false;
if (!bounds_okay(stream.offset(), bytes_to_read, context.data_size))
return false;
bytes_to_read -= 2;
@@ -661,6 +664,8 @@ static inline bool validate_luma_and_modify_context(const ComponentSpec& luma, J
context.vsample_factor = luma.vsample_factor;
jpg_dbg(String::format("Horizontal Subsampling Factor: %i", luma.hsample_factor));
jpg_dbg(String::format("Vertical Subsampling Factor: %i", luma.vsample_factor));
+ if (context.mblock_meta.padded_total > 1 << 22)
+ return false;
return true;
}
return false;
@@ -797,8 +802,11 @@ static bool read_quantization_table(BufferStream& stream, JPGLoadingContext& con
if (stream.handle_read_failure())
return false;
table[zigzag_map[i]] = tmp;
- } else
+ } else {
table[zigzag_map[i]] = read_be_word(stream);
+ if (stream.handle_read_failure())
+ return false;
+ }
}
if (stream.handle_read_failure())
return false;
@@ -1073,6 +1081,8 @@ static bool parse_header(BufferStream& stream, JPGLoadingContext& context)
}
for (;;) {
marker = read_marker_at_cursor(stream);
+ if (stream.handle_read_failure())
+ return false;
// Set frame type if the marker marks a new frame.
if (marker >= 0xFFC0 && marker <= 0xFFCF) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment