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: ph10@???
Reporter: clickwithsk@???
CC: pcre-dev@???
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.