ref: 6e1f2259115efac14cd6c7ad9d119b43013a32a1
parent: d6dcc6bd175300af5cc71c8395207a4ec67c2d0c
author: Simon Bünzli <[email protected]>
date: Tue Jan 14 17:45:49 EST 2014
Bug 694949: prevent denial of service with arithmetic decoding Badly constructed Jbig2 images using arithmetic decoding may result in a denial of service attack by causing huge images to be created and initialized from no data at all (at EOS, the arithmetic decoder always returns the same values instead of failing). Two cases are prevented with this patch: * huge generic regions with barely any data to decode it from * a huge list of height classes with no data at all to decode it from This can be seen e.g. in: b534b5caad95dd405735ec9a079fd43b_asan_heap-oob_14bf3ce_6977_5690.pdf Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security Team for providing the example files.
--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -379,6 +379,12 @@
}
}
+int
+jbig2_arith_get_offset(Jbig2ArithState *as)
+{
+ return as->offset;
+}
+
#ifdef TEST
static int
--- a/jbig2_arith.h
+++ b/jbig2_arith.h
@@ -33,4 +33,6 @@
bool
jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx);
-
+/* return the state's offset (for sanity checks) */
+int
+jbig2_arith_get_offset(Jbig2ArithState *as);
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -760,6 +760,12 @@
{
const int8_t *gbat = params->gbat;
+ if (image->stride * image->height > (1 << 24) && segment->data_length < image->stride * image->height / 256) {
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "region is far larger than data provided (%d << %d), aborting to prevent DOS",
+ segment->data_length, image->stride * image->height);
+ }
+
if (!params->MMR && params->TPGDON)
return jbig2_decode_generic_region_TPGDON(ctx, segment, params,
as, image, GB_stats);
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -361,6 +361,12 @@
"error or OOB decoding height class delta (%d)\n", code);
}
+ if (!params->SDHUFF && jbig2_arith_get_offset(as) >= size) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "prevent DOS while decoding height classes");
+ goto cleanup2;
+ }
+
/* 6.5.5 (4b) */
HCHEIGHT = HCHEIGHT + HCDH;
SYMWIDTH = 0;