[pcre-dev] [Bug 2479] New: Heap buffer overflow vulnerabilit…

Top Page
Delete this message
Author: admin
Date:  
To: pcre-dev
Subject: [pcre-dev] [Bug 2479] New: Heap buffer overflow vulnerability in GETCHARINC() (pcre2_match.c)
https://bugs.exim.org/show_bug.cgi?id=2479

            Bug ID: 2479
           Summary: Heap buffer overflow vulnerability in GETCHARINC()
                    (pcre2_match.c)
           Product: PCRE
           Version: 10.34 (PCRE2)
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: security
          Priority: medium
         Component: Code
          Assignee: ph10@???
          Reporter: clickwithsk@???
                CC: pcre-dev@???


Created attachment 1234
--> https://bugs.exim.org/attachment.cgi?id=1234&action=edit
Crash input 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 GETCHARINC()
(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_1
--------------------

==37552==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x629000004200 at pc 0x5555555f5f64 bp 0x7fffffff7ba0 sp 0x7fffffff7b90
READ of size 1 at 0x629000004200 thread T0
    #0 0x5555555f5f63 in match src/pcre2_match.c:1550
    #1 0x5555555f5f63 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:1550 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
==37552==ABORTING


=====================
valgrind output:
    valgrind -v --leak-check=full crashes/crash_file_1
--------------------


==8564== HEAP SUMMARY:
==8564==     in use at exit: 117,819 bytes in 14 blocks
==8564==   total heap usage: 18 allocs, 4 frees, 123,233 bytes allocated
==8564==
==8564== Searching for pointers to 14 not-freed blocks


==8564== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8564==
==8564== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
==8564==
==8564== 1 errors in context 1 of 4:
==8564== Invalid read of size 1
==8564==    at 0x140629: pcre2_match_8 (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==  Address 0x524b472 is 2 bytes after a block of size 16,384 alloc'd
==8564==    at 0x4C2FA3F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x4C31D84: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x110283: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==
==8564==
==8564== 1 errors in context 2 of 4:
==8564== Invalid read of size 1
==8564==    at 0x14061B: pcre2_match_8 (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==  Address 0x524b471 is 1 bytes after a block of size 16,384 alloc'd
==8564==    at 0x4C2FA3F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x4C31D84: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x110283: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==
==8564==
==8564== 1 errors in context 3 of 4:
==8564== Invalid read of size 1
==8564==    at 0x14060D: pcre2_match_8 (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==  Address 0x524b470 is 0 bytes after a block of size 16,384 alloc'd
==8564==    at 0x4C2FA3F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x4C31D84: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x110283: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==
==8564==
==8564== 1 errors in context 4 of 4:
==8564== Invalid read of size 1
==8564==    at 0x140604: pcre2_match_8 (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x111C49: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==  Address 0x524b473 is 3 bytes after a block of size 16,384 alloc'd
==8564==    at 0x4C2FA3F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x4C31D84: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8564==    by 0x110283: process_data (in pcre-10.34-RC1/pcre2test)
==8564==    by 0x115703: main (in pcre-10.34-RC1/pcre2test)
==8564==
==8564== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)



====================
Crash triage:
--------------------

Function: GETCHARINC(d, Feptr);     //  F->eptr = (PCRE2_SPTR8) 0x6290000041fe
"\377}"
                                    //0x6290000041fe: 0xff    0x7d    0x00   
0x00    0x00


GETCHARINC(d, Feptr) {               
    d = *F->eptr++;                  //d = 0xff, F->eptr = (PCRE2_SPTR8)
0x6290000041ff "}"
    if (d >= 0xc0u) {                //executes this condition
        if ((d & 0x20u) == 0) 
            d = ((d & 0x1fu) << 6) | (*F->eptr++ & 0x3fu); 
        else if ((d & 0x10u) == 0) { 
            d = ((d & 0x0fu) << 12) | ((*F->eptr & 0x3fu) << 6) | (F->eptr[1] &
0x3fu); 
            F->eptr += 2; 
        } else if ((d & 0x08u) == 0) {
            d = ((d & 0x07u) << 18) | ((*F->eptr & 0x3fu) << 12) | ((F->eptr[1]
& 0x3fu) << 6) | (F->eptr[2] & 0x3fu); 
            F->eptr += 3; 
        } else if ((d & 0x04u) == 0) { 
            d = ((d & 0x03u) << 24) | ((*F->eptr & 0x3fu) << 18) | ((F->eptr[1]
& 0x3fu) << 12) | ((F->eptr[2] & 0x3fu) << 6) | (F->eptr[3] & 0x3fu); 
            F->eptr += 4;
        } else {                   //executes this condition


            d = ((d & 0x01u) << 30) | ((*F->eptr & 0x3fu) << 24) | ((F->eptr[1]
& 0x3fu) << 18) | ((F->eptr[2] & 0x3fu) << 12) | ((F->eptr[3] & 0x3fu) << 6) |
(F->eptr[4] & 0x3fu); 
            F->eptr += 5;           //F->eptr[1] leads to heap-buffer overflow,
here the size of Feptr is only 1 byte ("}")
    }
}
=====================xx=====================


--
You are receiving this mail because:
You are on the CC list for the bug.