Browse code

fuzz - 12149 - Fix for out of bounds read in PDF object stream parsing code.

Micah Snyder authored on 2019/01/23 03:53:29
Showing 1 changed files
... ...
@@ -345,6 +345,13 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
345 345
         goto done;
346 346
     }
347 347
 
348
+    if ((size_t)objstm->first + (size_t)objoff > objstm->streambuf_len) {
349
+        /* Alleged obj location is further than the length of the stream */
350
+        cli_dbgmsg("pdf_findobj_in_objstm: obj offset found is greater than the length of the stream.\n");
351
+        status = CL_EPARSE;
352
+        goto done;
353
+    }
354
+
348 355
     objstm->current = objstm->first + objoff;
349 356
 
350 357
     obj->id = (objid << 8) | (0 & 0xff);
... ...
@@ -2054,16 +2061,32 @@ void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
2054 2054
     json_object *pdfobj=NULL, *jsonobj=NULL;
2055 2055
 #endif
2056 2056
 
2057
-    q = (obj->objstm) ? (const char *)(obj->start + obj->objstm->streambuf)
2058
-                      : (const char *)(obj->start + pdf->map);
2057
+    if (obj->objstm) {
2058
+        if ((size_t)obj->start > obj->objstm->streambuf_len) {
2059
+            cli_dbgmsg("pdf_parseobj: %u %u obj: obj start (%u) is greater than size of object stream (%zu).\n",
2060
+                obj->id >> 8, obj->id & 0xff, obj->start, obj->objstm->streambuf_len);
2061
+            return;
2062
+        }
2063
+        q = (const char *)(obj->start + obj->objstm->streambuf);
2064
+    } else {
2065
+        if ((size_t)obj->start > pdf->size) {
2066
+            cli_dbgmsg("pdf_parseobj: %u %u obj: obj start (%u) is greater than size of PDF (%lld).\n",
2067
+                obj->id >> 8, obj->id & 0xff, obj->start, (long long)pdf->size);
2068
+            return;
2069
+        }
2070
+        q = (const char *)(obj->start + pdf->map);
2071
+    }
2072
+    start = q;
2059 2073
 
2060 2074
     objsize = obj_size(pdf, obj, 1);
2061
-
2062 2075
     if (objsize < 0)
2063 2076
         return;
2064 2077
 
2065
-    start = q;
2066
-    bytesleft = objsize;
2078
+    if (obj->objstm) {
2079
+        bytesleft = MIN(objsize, obj->objstm->streambuf_len - obj->start);
2080
+    } else {
2081
+        bytesleft = MIN(objsize, pdf->size - obj->start);
2082
+    }
2067 2083
 
2068 2084
     /* find start of dictionary */
2069 2085
     do {