Bug 472279 - egrep: double free on when using >2 backreferences
egrep: double free on when using >2 backreferences
Status: CLOSED UPSTREAM
Product: Fedora
Classification: Fedora
Component: grep (Show other bugs)
9
All Linux
medium Severity high
: ---
: ---
Assigned To: Stepan Kasal
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2008-11-19 14:11 EST by Doncho N. Gunchev
Modified: 2008-12-08 04:58 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-11-20 01:03:23 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Doncho N. Gunchev 2008-11-19 14:11:13 EST
Description of problem:
From the grep info page under "Usage -> 12. How to express palindromes in a regular expression?":
egrep -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1$' /usr/share/dict/linux.words
results in
*** glibc detected *** egrep: double free or corruption (out): 0x0000003965767a70 ***

Version-Release number of selected component (if applicable):
grep-2.5.1-59.fc9.x86_64

How reproducible:
Always

Steps to Reproduce:
1. egrep -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1$' /usr/share/dict/linux.words
  
Actual results:
*** glibc detected *** egrep: double free or corruption (out): 0x0000003965767a70 ***                                                                          
======= Backtrace: =========                                                                                                                                   
/lib64/libc.so.6[0x3965478228]                                                                                                                                 
/lib64/libc.so.6(cfree+0x76)[0x396547a866]                                                                                                                     
/lib64/libc.so.6[0x39654b5d6b]                                                                                                                                 
/lib64/libc.so.6[0x39654c676e]                                                                                                                                 
/lib64/libc.so.6[0x39654c806f]
/lib64/libc.so.6(re_search+0x18)[0x39654c8468]
egrep[0x40e36f]
egrep[0x4031d8]
egrep[0x4039e5]
egrep[0x404e68]
/lib64/libc.so.6(__libc_start_main+0xfa)[0x396541e32a]
egrep[0x402289]
======= Memory map: ========
00400000-00415000 r-xp 00000000 fd:01 82067                              /bin/grep
00614000-00617000 rw-p 00014000 fd:01 82067                              /bin/grep
01e75000-01eb7000 rw-p 01e75000 00:00 0                                  [heap]
3243800000-3243816000 r-xp 00000000 fd:01 795108                         /lib64/libgcc_s-4.3.0-20080428.so.1
3243816000-3243a15000 ---p 00016000 fd:01 795108                         /lib64/libgcc_s-4.3.0-20080428.so.1
3243a15000-3243a16000 rw-p 00015000 fd:01 795108                         /lib64/libgcc_s-4.3.0-20080428.so.1
3965000000-396501d000 r-xp 00000000 fd:01 794750                         /lib64/ld-2.8.so
396521c000-396521d000 r--p 0001c000 fd:01 794750                         /lib64/ld-2.8.so
396521d000-396521e000 rw-p 0001d000 fd:01 794750                         /lib64/ld-2.8.so
3965400000-3965562000 r-xp 00000000 fd:01 794846                         /lib64/libc-2.8.so
3965562000-3965762000 ---p 00162000 fd:01 794846                         /lib64/libc-2.8.so
3965762000-3965766000 r--p 00162000 fd:01 794846                         /lib64/libc-2.8.so
3965766000-3965767000 rw-p 00166000 fd:01 794846                         /lib64/libc-2.8.so
3965767000-396576c000 rw-p 3965767000 00:00 0
397ec00000-397ec28000 r-xp 00000000 fd:01 794889                         /lib64/libpcre.so.0.0.1
397ec28000-397ee28000 ---p 00028000 fd:01 794889                         /lib64/libpcre.so.0.0.1
397ee28000-397ee29000 rw-p 00028000 fd:01 794889                         /lib64/libpcre.so.0.0.1
7f0790000000-7f0790021000 rw-p 7f0790000000 00:00 0
7f0790021000-7f0794000000 ---p 7f0790021000 00:00 0
7f0795a5c000-7f079a60d000 r--p 00000000 fd:01 256953                     /usr/lib/locale/locale-archive
7f079a60d000-7f079a60f000 rw-p 7f079a60d000 00:00 0
7f079a635000-7f079a63c000 r--s 00000000 fd:01 147811                     /usr/lib64/gconv/gconv-modules.cache
7f079a63c000-7f079a63e000 rw-p 7f079a63c000 00:00 0
7fffa2628000-7fffa263d000 rw-p 7ffffffea000 00:00 0                      [stack]
7fffa27fe000-7fffa27ff000 r-xp 7fffa27fe000 00:00 0                      [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted


Expected results:
Find all palindromes in linux.words :-D


Additional info:
I was able to reproduce this on RHEL 5, CentOS 5 and a few other linux systems (all failed).
Using one or two backreferences works fine. Using three results in segmentation fault.

Here's a backtrace from gdb on fedora 9 x86_64:
#0  0x0000003965432215 in raise (sig=<value optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x0000003965433d83 in abort () at abort.c:88
#2  0x0000003965472928 in __libc_message (do_abort=<value optimized out>, fmt=<value optimized out>) at ../sysdeps/unix/sysv/linux/libc_fatal.c:170
#3  0x0000003965478228 in malloc_printerr (action=<value optimized out>, str=<value optimized out>, ptr=<value optimized out>) at malloc.c:5949
#4  0x000000396547a866 in __libc_free (mem=<value optimized out>) at malloc.c:3625
#5  0x00000039654b5d6b in set_regs (preg=<value optimized out>, mctx=<value optimized out>, nmatch=<value optimized out>, pmatch=<value optimized out>, fl_backtrack=<value optimized out>) at regexec.c:1376
#6  0x00000039654c676e in re_search_internal (preg=<value optimized out>, string=<value optimized out>, length=<value optimized out>, start=<value optimized out>, range=<value optimized out>, stop=<value optimized out>, nmatch=<value optimized out>, pmatch=Could not find the frame base for "re_search_internal".) at regexec.c:883
#7  0x00000039654c806f in re_search_stub (bufp=<value optimized out>, string=<value optimized out>, length=<value optimized out>, start=<value optimized out>, range=<value optimized out>, stop=<value optimized out>, regs=<value optimized out>, ret_len=Could not find the frame base for "re_search_stub".) at regexec.c:466
#8  0x00000039654c8468 in __re_search (bufp=<value optimized out>, string=<value optimized out>, length=<value optimized out>, start=<value optimized out>, range=<value optimized out>, regs=<value optimized out>) at regexec.c:326
#9  0x000000000040e36f in EGexecute (buf=0x8ef000 "1080\n10-point\n10th\n11-point\n12-point\n16-point\n18-point\n1st\n2\n20-point\n2,4,5-t\n2,4-d\n2D\n2nd\n30-30\n3-D\n3-d\n3D\n3M\n3rd\n48-point\n4-D\n4GL\n4H\n4th\n5-point\n5-T\n5th\n6-point\n6th\n7-point\n7th\n8-point\n8th\n9-point\n9"..., size=32765, match_size=0x7fff35ea8d18, exact=0) at search.c:498
#10 0x00000000004031d8 in grepbuf (beg=<value optimized out>, lim=0x8f6ffd "acr") at grep.c:684
#11 0x00000000004039e5 in grepfile (file=0x7fff35ea9475 "/usr/share/dict/linux.words", stats=0x615200) at grep.c:803
#12 0x0000000000404e68 in main (argc=4, argv=0x7fff35ea8f98) at grep.c:1745
Comment 1 Doncho N. Gunchev 2008-11-19 14:18:15 EST
btw: 'grep -P' works fine with the same regular expression pattern.
Comment 2 Lubomir Rintel 2008-11-20 01:03:23 EST
Your regular expression is wrong. Unlike in Perl regexps, in traditional and extended regular expressions, you need to escape the brackets surrounding the match:

egrep -e '^\(.?\)\(.?\)\(.?\)\(.?\)\(.?\)\(.?\)\(.?\)\(.?\)\(.?\).?\9\8\7\6\5\4\3\2\1$' /usr/share/dict/linux.words

Unfortunately, due to a bug you reported, this won't work in grep versions in Fedora. Update to grep 2.5.3, which is tracked by bug #471187 will solve the issue.
Comment 3 Doncho N. Gunchev 2008-12-08 04:58:17 EST
This will not fix it for RHEL and...

$ egrep -e '^\(.?\)\(.?\).\2\1$' /usr/share/dict/linux.words | head
egrep: Invalid back reference

$ egrep -e '^(.?)(.?).\2\1$' /usr/share/dict/linux.words | head
2
A
a
AAA
aaa
ABA
aba
ADA
addda
AEA

... or the man page and the implementation are wrong ...

Note You need to log in before you can comment on or make changes to this bug.