>Number: 42032
>Category: lib
>Synopsis: libc/string/bm.c:bm_exec --> overrun
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Sep 10 03:00:01 +0000 2009
>Originator: B K
>Release: 5.0
>Organization:
home
>Environment:
found via code reuse
>Description:
There's a potential crash bug in the initial loop in bm_exec.c. If k is never
set to zero prior to overrunning e, you'll crash as you'll keep adding
pat->patlen onto s in perpetuity while eventually trying to dereference a bad
pointer.
/* fast loop up to n - 3 * patlen */
e = base + n - 3 * pat->patlen;
while (s < e) {
k = d0[*s]; /* ufast skip loop */
while (k) {
k = d0[*(s += k)];
k = d0[*(s += k)];
}
I checked the OpenBSD implementation and it also has this bug.
>How-To-Repeat:
Create data where the terminal character in pattern is never found in
pat->patlen's position. You should also ensure the length of the buffer is >
3*pat->patlen as you'll enter the slowpath otherwise.
>Fix:
I did a simple fixup with:
while(k && s < e)
I spent some time in the debugger and I don't believe bm_comp is the culprit as
the lookup table looked fine to me.
Finally, reading the code, it seems the bm_comp/bm_free stuff could be
simplified and made more reliable with a single malloc/free instead of three.