https://bugs.exim.org/show_bug.cgi?id=2481
Bug ID: 2481 Summary: Heap buffer overflow vulnerability in GETCHARLENTEST() (pcre2_match.c) Product: PCRE Version: 10.34 (PCRE2) Hardware: x86-64 OS: All Status: NEW Severity: security Priority: medium Component: Code Assignee: p...@hermes.cam.ac.uk Reporter: clickwit...@gmail.com CC: pcre-dev@exim.org Created attachment 1236 --> https://bugs.exim.org/attachment.cgi?id=1236&action=edit Crash input file that triggers the bug The latest version of PCRE (pcre2-10.34-RC1, pcre2-10.33) is prone to a Heap Overflow vulnerability which can be triggered using a crafted regular expression. It could allow a remote attacker to obtain sensitive information, or cause denial of service. This vulnerability occurs because the library fails to perform adequate boundary-checks on user-supplied data in GETCHARLENTEST() (pcre2_match.c), which leads to a heap buffer overflow, causing an out of bounds memory read, and subsequently resulting into a crash. ==================== Output of ASAN compiled library (-fsanitize=address) Run as: ./pcre2test crashes/crash_file_3 --------------------- ==14275==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000004200 at pc 0x5555555ff72f bp 0x7fffffff7b50 sp 0x7fffffff7b40 READ of size 1 at 0x629000004200 thread T0 #0 0x5555555ff72e in match src/pcre2_match.c:2128 #1 0x5555555ff72e in pcre2_match_8 src/pcre2_match.c:6968 #2 0x555555576c41 in process_data src/pcre2test.c:7537 #3 0x55555557cd61 in main src/pcre2test.c:9004 #4 0x7ffff681db96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) #5 0x55555557dbf9 in _start (pcre-10.34-RC1/pcre2test-addrsan-fno-omit-gdwarf-g3+0x29bf9) 0x629000004200 is located 0 bytes to the right of 16384-byte region [0x629000000200,0x629000004200) allocated by thread T0 here: #0 0x7ffff6ef8f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40) #1 0x555555574899 in process_data src/pcre2test.c:6652 #2 0x55555557cd61 in main src/pcre2test.c:9004 #3 0x7ffff681db96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) SUMMARY: AddressSanitizer: heap-buffer-overflow src/pcre2_match.c:2128 in match Shadow bytes around the buggy address: 0x0c527fff87f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c527fff8800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c527fff8810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c527fff8820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c527fff8830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c527fff8840:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c527fff8850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c527fff8860: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c527fff8870: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c527fff8880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c527fff8890: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==14275==ABORTING ===================== valgrind output: valgrind -v --leak-check=full ./pcre2test $crash_file_3 -------------------- ==37148== HEAP SUMMARY: ==37148== in use at exit: 117,819 bytes in 14 blocks ==37148== total heap usage: 18 allocs, 4 frees, 123,278 bytes allocated ==37148== ==37148== Searching for pointers to 14 not-freed blocks ==37148== Checked 76,080 bytes ==37148== ==37148== LEAK SUMMARY: ==37148== definitely lost: 0 bytes in 0 blocks ==37148== indirectly lost: 0 bytes in 0 blocks ==37148== possibly lost: 0 bytes in 0 blocks ==37148== still reachable: 117,819 bytes in 14 blocks ==37148== suppressed: 0 bytes in 0 blocks ==37148== Reachable blocks (those to which a pointer was found) are not shown. ==37148== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==37148== ==37148== ERROR SUMMARY: 15 errors from 3 contexts (suppressed: 0 from 0) ==37148== ==37148== 5 errors in context 1 of 3: ==37148== Invalid read of size 1 ==37148== at 0x13E6F2: pcre2_match_8 (in pcre-10.34-RC1/pcre2test) ==37148== by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== Address 0x524b491 is 1 bytes after a block of size 16,384 alloc'd ==37148== at 0x4C2FA3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x4C31D84: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x110283: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== ==37148== ==37148== 5 errors in context 2 of 3: ==37148== Invalid read of size 1 ==37148== at 0x13E6E4: pcre2_match_8 (in pcre-10.34-RC1/pcre2test) ==37148== by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== Address 0x524b490 is 0 bytes after a block of size 16,384 alloc'd ==37148== at 0x4C2FA3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x4C31D84: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x110283: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== ==37148== ==37148== 5 errors in context 3 of 3: ==37148== Invalid read of size 1 ==37148== at 0x13E6CB: pcre2_match_8 (in pcre-10.34-RC1/pcre2test) ==37148== by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== Address 0x524b492 is 2 bytes after a block of size 16,384 alloc'd ==37148== at 0x4C2FA3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x4C31D84: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==37148== by 0x110283: process_data (in pcre-10.34-RC1/pcre2test) ==37148== by 0x115703: main (in pcre-10.34-RC1/pcre2test) ==37148== ==37148== ERROR SUMMARY: 15 errors from 3 contexts (suppressed: 0 from 0) ==================== Crash triage: -------------------- Function: GETCHARLENTEST(fc, Feptr, len); //F->eptr = (PCRE2_SPTR8) 0x6290000041fd "\377" //0x6290000041fd: 0xff 0x00 0x7d 0x00 0x00 GETCHARLENTEST(fc, Feptr, len){ fc = *F->eptr; //fc = 0xff if (utf && fc >= 0xc0u) { if ((fc & 0x20u) == 0) { fc = ((fc & 0x1fu) << 6) | (F->eptr[1] & 0x3fu); len++; } else if ((fc & 0x10u) == 0) { fc = ((fc & 0x0fu) << 12) | ((F->eptr[1] & 0x3fu) << 6) | (F->eptr[2] & 0x3fu); len += 2; } else if ((fc & 0x08u) == 0) { fc = ((fc & 0x07u) << 18) | ((F->eptr[1] & 0x3fu) << 12) | ((F->eptr[2] & 0x3fu) << 6) | (F->eptr[3] & 0x3fu); len += 3; } else if ((fc & 0x04u) == 0) { fc = ((fc & 0x03u) << 24) | ((F->eptr[1] & 0x3fu) << 18) | ((F->eptr[2] & 0x3fu) << 12) | ((F->eptr[3] & 0x3fu) << 6) | (F->eptr[4] & 0x3fu); len += 4; } else { //executes this block fc = ((fc & 0x01u) << 30) | ((F->eptr[1] & 0x3fu) << 24) | ((F->eptr[2] & 0x3fu) << 18) | ((F->eptr[3] & 0x3fu) << 12) | ((F->eptr[4] & 0x3fu) << 6) | (F->eptr[5] & 0x3fu); // F->eptr[3] leads to a heap buffer overflow len += 5; } } } ===================== -- You are receiving this mail because: You are on the CC list for the bug. -- ## List details at https://lists.exim.org/mailman/listinfo/pcre-dev