Bugzilla – Bug 11942
Heap overflow in handle_pdfname (pdf.c)
Last modified: 2021-09-23 16:35:27 EDT
Created attachment 7307 [details] poc, pass is virus There a heap buffer overflow in ClamAV while analyzing a PDF file. The bug happens when a PDF file contains a filter cascade larger than the designed size. The vulnerability is at `pdf.c:1242` inside the function `handle_pdfname`: ```c 1215 static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj, const char *pdfname, int escapes, enum objstate *state) 1216 { 1217 struct pdfname_action *act = NULL; 1218 unsigned j; 1219 1220 obj->statsflags |= OBJ_FLAG_PDFNAME_DONE; 1221 1222 for (j=0;j<sizeof(pdfname_actions)/sizeof(pdfname_actions[0]);j++) { 1223 if (!strcmp(pdfname, pdfname_actions[j].pdfname)) { 1224 act = &pdfname_actions[j]; 1225 break; 1226 } 1227 } .... 1240 /* record filter order */ 1241 if ((*state == STATE_FILTER) && ((1 << act->set_objflag) & KNOWN_FILTERS)) 1242 obj->filterlist[obj->numfilters++] = act->set_objflag; ``` `filterlist` is an array of 64 elements. ```c 25 #define PDF_FILTERLIST_MAX 64 ... 27 struct pdf_obj { 28 uint32_t start; 29 uint32_t id; 30 uint32_t flags; 31 uint32_t statsflags; 32 uint32_t numfilters; 33 uint32_t filterlist[PDF_FILTERLIST_MAX]; 34 char *path; 35 }; ``` When more than 64 encoding filters are used in cascade the variable `obj->numfilters` takes values greater than `64` and the buffer is overflown. A filter cascade looks like this: ``` 1 0 obj << /Filter /ASCII85Decode /FlateDecode /ASCIIHEXDecode /Fl /Fl /Fl >> stream ... endstream endobj ``` More information: https://blog.didierstevens.com/2008/05/19/pdf-stream-objects/ It is not possible to control the data being written. ```c 1242 obj->filterlist[obj->numfilters++] = act->set_objflag; ``` The variable `act->set_objflag` contains a static identifier for the different encodings: ```c OBJ_FILTER_AH 3 OBJ_FILTER_RL 7 OBJ_FILTER_A85 4 OBJ_FILTER_FLATE 5 OBJ_FILTER_LZW 6 OBJ_FILTER_FAX 8 OBJ_FILTER_DCT 10 OBJ_FILTER_JPX 11 OBJ_FILTER_CRYPT 12 ``` The bug could be used to corrupt the heap, generating a Denial of Service or perhaps remote code execution. A possible solution is to verify that the variable `numfilters` does not take a value higher than `64`: ```c 1241 if (obj->numfilters < PDF_FILTERLIST_MAX && (*state == STATE_FILTER) && ((1 << act->set_objflag) & KNOWN_FILTERS)) 1242 obj->filterlist[obj->numfilters++] = act->set_objflag; ``` Backtrace: ```c #0 0x82ad1ee in handle_pdfname /tmp/clamav-devel/libclamav/pdf.c:1241:9 #1 0x82ad1ee in pdf_parseobj /tmp/clamav-devel/libclamav/pdf.c:1536 #2 0x82b3bce in cli_pdf /tmp/clamav-devel/libclamav/pdf.c:2458:9 #3 0x8183656 in cli_scanpdf /tmp/clamav-devel/libclamav/scanners.c:1925:11 #4 0x816cb15 in magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3389:19 #5 0x8167904 in cli_base_scandesc /tmp/clamav-devel/libclamav/scanners.c:3616:11 #6 0x8176391 in cli_magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3625:12 #7 0x8176391 in scan_common /tmp/clamav-devel/libclamav/scanners.c:3891 #8 0x8177162 in cl_scandesc_callback /tmp/clamav-devel/libclamav/scanners.c:4032:12 #9 0x8177162 in cl_scanfile_callback /tmp/clamav-devel/libclamav/scanners.c:4099 #10 0x8177162 in cl_scanfile /tmp/clamav-devel/libclamav/scanners.c:4082 ```
Wrong attachment, forgot to update template. This vulnerability has been found by Offensive Research at Salesforce.com: Alberto Garcia (@algillera), Francisco Oca (@francisco_oca) & Suleman Ali (@Salbei_)
Created attachment 7308 [details] poc, pass is virus
Thank you very much for reporting these issues. If possible, we'd like to gather some initial first details from you on these. First, can you tell us what version of ClamAV you are reporting against? I notice that you have our git-repository name in the reports, is this a fresh check out of git?
Went with the proposed solution here, tested with heuristic filter checks set above and below the max filter limit. https://github.com/vrtadmin/clamav-devel/commit/c8ba4ae2e47a4f49add3e85ef7041b166be6bfdb