https://bugs.exim.org/show_bug.cgi?id=1901
Bug ID: 1901 Summary: PCRE2 10.23-RC1 Stack Buffer Overflow Vulnerability Product: PCRE Version: N/A Hardware: x86-64 OS: Linux Status: NEW Severity: bug Priority: critical Component: Code Assignee: p...@hermes.cam.ac.uk Reporter: fumfi....@gmail.com CC: pcre-dev@exim.org Created attachment 931 --> https://bugs.exim.org/attachment.cgi?id=931&action=edit POC to trigger buffer overflow (pcre2test) PCRE2 library is prone to a vulnerability which leads to stack buffer overflow. Affected: - PCRE2 version 10.23-RC1 2016-08-01 (SVN rev: 563) To reproduce the problem (pcre2test): pcre2test buffover /dev/null ASAN output: ==123925==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffbd8a3630 at pc 0x7f15cf495937 bp 0x7fffbd8a1c20 sp 0x7fffbd8a1c18 READ of size 4 at 0x7fffbd8a3630 thread T0 #0 0x7f15cf495936 in parsed_skip /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8152:10 #1 0x7f15cf494fb9 in get_branchlength /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8496:15 #2 0x7f15cf494137 in set_lookbehind_lengths /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8625:18 #3 0x7f15cf48f3c3 in check_lookbehinds /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8761:10 #4 0x7f15cf4820e5 in pcre2_compile_8 /home/kamil/Pulpit/pcre/src/pcre2_compile.c:9160:15 #5 0x4f0e98 in process_pattern /home/kamil/Pulpit/pcre/src/pcre2test.c:5033:1 #6 0x4e8333 in main /home/kamil/Pulpit/pcre/src/pcre2test.c:7739:10 #7 0x7f15ce37f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #8 0x41a828 in _start (/usr/local/bin/pcre2test+0x41a828) Address 0x7fffbd8a3630 is located in stack of thread T0 at offset 5840 in frame #0 0x7f15cf480d0f in pcre2_compile_8 /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8794 This frame has 16 object(s): [32, 36) 'has_lookbehind' [48, 344) 'cb' [416, 424) 'code' [448, 456) 'pptr' [480, 488) 'length' [512, 516) 'firstcuflags' [528, 532) 'reqcuflags' [544, 548) 'firstcu' [560, 564) 'reqcu' [576, 580) 'errorcode' [592, 1616) 'stack_groupinfo' [1744, 5840) 'stack_parsed_pattern' <== Memory access at offset 5840 overflows this variable [5968, 6288) 'named_groups' [6352, 14544) 'c16workspace' [14800, 14928) 'rc' [14960, 14964) 'count' HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /home/kamil/Pulpit/pcre/src/pcre2_compile.c:8152:10 in parsed_skip Shadow bytes around the buggy address: 0x100077b0c670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100077b0c680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100077b0c690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100077b0c6a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100077b0c6b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x100077b0c6c0: 00 00 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 0x100077b0c6d0: f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 0x100077b0c6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100077b0c6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 0x100077b0c700: f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 0x100077b0c710: 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 right 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 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==123925==ABORTING Valgrind output: ==15700== Memcheck, a memory error detector ==15700== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==15700== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==15700== Command: pcre2test buffover /dev/null ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61F53: parsed_skip (pcre2_compile.c:8152) ==15700== by 0x4E61F53: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61F95: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E61F95: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61FE5: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E61FE5: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E62022: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E62022: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E62029: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E62029: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E62030: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E62030: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61FEC: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E61FEC: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E62051: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E62051: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E62058: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E62058: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61F5A: parsed_skip (pcre2_compile.c:8152) ==15700== by 0x4E61F5A: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Conditional jump or move depends on uninitialised value(s) ==15700== at 0x4E61FD5: parsed_skip (pcre2_compile.c:8155) ==15700== by 0x4E61FD5: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== ==15700== Invalid read of size 4 ==15700== at 0x4E61F46: parsed_skip (pcre2_compile.c:8150) ==15700== by 0x4E61F46: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== Address 0xfff001000 is not stack'd, malloc'd or (recently) free'd ==15700== ==15700== ==15700== Process terminating with default action of signal 11 (SIGSEGV) ==15700== Access not within mapped region at address 0xFFF001000 ==15700== at 0x4E61F46: parsed_skip (pcre2_compile.c:8150) ==15700== by 0x4E61F46: get_branchlength (pcre2_compile.c:8496) ==15700== by 0x4E4FAF2: set_lookbehind_lengths (pcre2_compile.c:8625) ==15700== by 0x4E4FAF2: check_lookbehinds (pcre2_compile.c:8761) ==15700== by 0x4E4FAF2: pcre2_compile_8 (pcre2_compile.c:9160) ==15700== by 0x40DCAD: process_pattern (pcre2test.c:5033) ==15700== by 0x40DCAD: main (pcre2test.c:7739) ==15700== If you believe this happened as a result of a stack ==15700== overflow in your program's main thread (unlikely but ==15700== possible), you can try to increase the size of the ==15700== main thread stack using the --main-stacksize= flag. ==15700== The main thread stack size used in this run was 8388608. ==15700== ==15700== HEAP SUMMARY: ==15700== in use at exit: 118,224 bytes in 12 blocks ==15700== total heap usage: 861 allocs, 849 frees, 451,216 bytes allocated ==15700== ==15700== LEAK SUMMARY: ==15700== definitely lost: 0 bytes in 0 blocks ==15700== indirectly lost: 0 bytes in 0 blocks ==15700== possibly lost: 0 bytes in 0 blocks ==15700== still reachable: 118,224 bytes in 12 blocks ==15700== suppressed: 0 bytes in 0 blocks ==15700== Rerun with --leak-check=full to see details of leaked memory ==15700== ==15700== For counts of detected and suppressed errors, rerun with: -v ==15700== Use --track-origins=yes to see where uninitialised values come from ==15700== ERROR SUMMARY: 21526 errors from 12 contexts (suppressed: 0 from 0) Segmentation fault Regards, Kamil Frankowicz -- 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