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