Summary: | opname Out-of-Bounds read in jsC_dumpfunction function | ||
---|---|---|---|
Product: | MuJS | Reporter: | Shi Ji <puzzorsj> |
Component: | general | Assignee: | Tor Andersson <tor.andersson> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | tor.andersson |
Priority: | P4 | ||
Version: | unspecified | ||
Hardware: | PC | ||
OS: | Windows NT | ||
Customer: | Word Size: | --- | |
Attachments: | poc and stack trace |
commit a5c747f1d40e8d6659a37a8d25f13fb5acf8e767 Author: Tor Andersson <tor.andersson@artifex.com> Date: Tue Oct 25 14:08:27 2016 +0200 Fix 697171: missed an operand in the bytecode debugger dump. |
Created attachment 12976 [details] poc and stack trace # Vulnerability opname Out-of-Bounds read in jsC_dumpfunction function # Version git head version # Address Sanitizer Output ================================================================= ==14609== ERROR: AddressSanitizer: global-buffer-overflow on address 0x080c784c at pc 0x8089aa1 bp 0xbffff0b8 sp 0xbffff0ac READ of size 4 at 0x080c784c thread T0 #0 0x8089aa0 in jsC_dumpfunction /home/puzzor/puzzor/mujs/jsdump.c:734 #1 0x805bdf0 in js_trap /home/puzzor/puzzor/mujs/jsrun.c:1252 #2 0x805e6ea in jsR_run /home/puzzor/puzzor/mujs/jsrun.c:1685 #3 0x80594c1 in jsR_callscript /home/puzzor/puzzor/mujs/jsrun.c:998 #4 0x8059f7b in js_call /home/puzzor/puzzor/mujs/jsrun.c:1053 #5 0x805f31b in js_dofile /home/puzzor/puzzor/mujs/jsstate.c:152 #6 0x8049fbb in main /home/puzzor/puzzor/mujs/main.c:175 #7 0xb6804a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82) #8 0x8049560 in _start (/home/puzzor/puzzor/mujs/build/mujs+0x8049560) 0x080c784c is located 32 bytes to the right of global variable 'opname (jsdump.c)' (0x80c76c0) of size 364 0x080c784c is located 20 bytes to the left of global variable 'HEX (jsdump.c)' (0x80c7860) of size 4 SUMMARY: AddressSanitizer: global-buffer-overflow /home/puzzor/puzzor/mujs/jsdump.c:734 jsC_dumpfunction Shadow bytes around the buggy address: 0x21018eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018ed0: 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00 0x21018ee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018ef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x21018f00: 00 00 00 00 00 04 f9 f9 f9[f9]f9 f9 04 f9 f9 f9 0x21018f10: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 0x21018f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x21018f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap righ redzone: fb Freed Heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==14609== ABORTING # PoC See poc # Analysis The variable of opname is defined as: "static const char *opname[] = { /#include "opnames.h" };" And it has 91 items. but with this poc, the "c" variable is some kind of a higher value with 99,as follow: (gdb) list 728 729 printf("{\n"); 730 while (p < end) { 731 int c = *p++; 732 733 printf("% 5d: ", (int)(p - F->code) - 1); 734 ps(opname[c]); 735 736 switch (c) { 737 case OP_NUMBER: (gdb) print c $14 = 99 (gdb) print p $15 = (js_Instruction *) 0xb640672e (gdb) print end $16 = (js_Instruction *) 0xb6406748 (gdb) x /16x p-1 0xb640672c: 0x00300063 0x0064000b 0x00580045 0x00000623 0xb640673c: 0x0063001e 0x002e0010 0x00590000 0x00000000 0xb640674c: 0x00000000 0x00000000 0x00000000 0x00000000 0xb640675c: 0x00000000 0x00000000 0x00000000 0x00000000 This causes a oob read and may cause a info leak. # Report Timeline 2016.09.30: Shi Ji(@Puzzor) discovered this issue # Credit Shi Ji(@Puzzor) of VARAS@IIE # Repro build with asan, run the poc with ./mujs poc