This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug regex/21442] New: Crash in re_search_stub


https://sourceware.org/bugzilla/show_bug.cgi?id=21442

            Bug ID: 21442
           Summary: Crash in re_search_stub
           Product: glibc
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: regex
          Assignee: unassigned at sourceware dot org
          Reporter: boehme.marcel at gmail dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

Dear all,

We found a null pointer dereference resulting in a segmentation fault, that
might be a bug in diffutils or a bug in GLIBC depending on the perspective one
takes. The patch can be in GLIBC (introducing a simple null pointer check) or
in Diffutils (preventing the null pointer dereference altogether). We already
reported the bug downstream at
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26690. Below we provide a quick
analysis. We think, it is actually an incorrect use of GLIBC. However, since it
can be easily prevented in GLIBC, we thought we should report it here as well.

This bug was found with AFLGo, a directed version of AFL/AFLFast. Thanks also
to Van-Thuan Pham.

How to reproduce:
$ diff -Ia -I\\ <(printf "") <(echo a)
diff: \: Trailing backslash
diff: stack overflow

ASAN says:
ASAN:DEADLYSIGNAL
=================================================================
==74668==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000000d8 (pc
0x7f0670589bad bp 0x000000000000 sp 0x7ffefbed15b0 T0)
   #0 0x7f0670589bac in re_search_stub
/build/eglibc-MjiXCM/eglibc-2.19/posix/regexec.c:414
   #1 0x7f067058a527 in re_search
/build/eglibc-MjiXCM/eglibc-2.19/posix/regexec.c:312
   #2 0x555bfc in analyze_hunk
/home/ubuntu/diffutils-analysis/diffutils/obj-asan/src/../../src/util.c:1522:8
   #3 0x4f91dd in diff_2_files
/home/ubuntu/diffutils-analysis/diffutils/obj-asan/src/../../src/analyze.c:620:12
   #4 0x528971 in compare_files
/home/ubuntu/diffutils-analysis/diffutils/obj-asan/src/../../src/diff.c:1434:11
   #5 0x51882c in main
/home/ubuntu/diffutils-analysis/diffutils/obj-asan/src/../../src/diff.c:800:18
   #6 0x7f06704c4f44 in __libc_start_main
/build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287
   #7 0x41bac5 in _start
(/home/ubuntu/diffutils-analysis/diffutils/obj-asan/src/diff+0x41bac5)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV
/build/eglibc-MjiXCM/eglibc-2.19/posix/regexec.c:414 in re_search_stub

This is our analysis:
For the diff-tool the argument -I<regexp> specifies the changed lines to
exclude. For each such argument, the function add_regexp in diff.c is called.
This function uses re_compile_pattern to successfully compile the first
pattern. However, it fails to compile the second pattern, giving the error
“Trailing backslash”. In both cases, the function uses the re_pattern_buffer
*ignore_regexp. However, the failed compilation corrupts *ignore_regexp,
setting ignore_regexp->buffer=0x0 and ignore_regexp->allocated=0. Later, in
function summarize_regexp_list, it is established that at least one pattern was
successfully compiled and ignore_regexp->fastmap is set, indicating that
re_search is being called in utils.c:1501. Unfortunately, it is being called on
the corrupted ignore_regexp where ignore_regexp->buf = 0x0. GLIBC does not
check for a null-pointer when derefencing the buffer in regexec.c:413.

GDB says:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7af5056 in re_search_stub (bufp=0x6228a0 <ignore_regexp>,
string=string@entry=0x62a050 "a\n", length=1, start=start@entry=0, range=1,
stop=1, regs=0x0, ret_len=0) at regexec.c:413
413     in regexec.c
(gdb) p *bufp
$1 = {buffer = 0x0, allocated = 0, used = 224, syntax = 330310, fastmap =
0x6271f0 "\330\036\335\367\377\177", translate = 0x0, re_nsub = 0, can_be_null
= 0, regs_allocated = 0, fastmap_accurate = 0, no_sub = 0, not_bol = 0, not_eol
= 0, newline_anchor = 1}
(gdb) bt
#0  0x00007ffff7af5056 in re_search_stub (bufp=0x6228a0 <ignore_regexp>,
string=string@entry=0x62a050 "a\n", length=1, start=start@entry=0, range=1,
stop=1, regs=0x0, ret_len=0) at regexec.c:413
#1  0x00007ffff7af5a70 in __re_search (bufp=<optimized out>,
string=string@entry=0x62a050 "a\n", length=<optimized out>,
start=start@entry=0, range=<optimized out>, regs=regs@entry=0x0) at
regexec.c:317
#2  0x000000000040ce1e in analyze_hunk (hunk=hunk@entry=0x627340,
first0=first0@entry=0x7fffffffdf80, last0=last0@entry=0x7fffffffdf88,
first1=first1@entry=0x7fffffffdf90, last1=last1@entry=0x7fffffffdf98) at
util.c:1522
#3  0x000000000040507d in diff_2_files (cmp=cmp@entry=0x7fffffffe060) at
analyze.c:620
#4  0x00000000004071f7 in compare_files (parent=parent@entry=0x0,
name0=0x7fffffffe6ec "/dev/fd/63", name1=<optimized out>) at diff.c:1434
#5  0x000000000040387e in main (argc=<optimized out>, argv=<optimized out>) at
diff.c:800

VALGRIND says:
==103798== Memcheck, a memory error detector
==103798== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==103798== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==103798== Command: src/diff -Ia -I\\ /dev/fd/63 /dev/fd/62
==103798== 
src/diff: \: Trailing backslash
==103798== Invalid read of size 4
==103798==    at 0x4F21056: re_search_stub (regexec.c:413)
==103798==    by 0x4F21A6F: re_search (regexec.c:317)
==103798==    by 0x40CE1D: analyze_hunk (util.c:1522)
==103798==    by 0x40507C: diff_2_files (analyze.c:620)
==103798==    by 0x4071F6: compare_files (diff.c:1434)
==103798==    by 0x40387D: main (diff.c:800)
==103798==  Address 0xd8 is not stack'd, malloc'd or (recently) free'd
==103798== 
diff: stack overflow
==103798== 
==103798== HEAP SUMMARY:
==103798==     in use at exit: 4,970 bytes in 25 blocks
==103798==   total heap usage: 75 allocs, 50 frees, 28,030 bytes allocated
==103798== 
==103798== LEAK SUMMARY:
==103798==    definitely lost: 136 bytes in 5 blocks
==103798==    indirectly lost: 120 bytes in 6 blocks
==103798==      possibly lost: 0 bytes in 0 blocks
==103798==    still reachable: 4,714 bytes in 14 blocks
==103798==         suppressed: 0 bytes in 0 blocks
==103798== Rerun with --leak-check=full to see details of leaked memory
==103798== 
==103798== For counts of detected and suppressed errors, rerun with: -v
==103798== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Best regards,
- Marcel

---
Marcel Böhme
Senior Research Fellow
TSUNAMi Security Research Centre
National University of Singapore

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]