sh: Fix out of bounds read when there is no ] after a [:class:].

The initial check for a matching ] was incorrect if a ] may be consumed by a
[:class:]. The subsequent loop assumed that there must be a ].

Remove the initial check and make the loop cope with a missing ].

Found with afl-fuzz.

MFC after:	1 week
This commit is contained in:
Jilles Tjoelker 2015-08-25 21:55:15 +00:00
parent 1e415e2992
commit 4a4867d667
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287148
3 changed files with 17 additions and 12 deletions

View File

@ -1464,21 +1464,11 @@ patmatch(const char *pattern, const char *string, int squoted)
bt_q = q; bt_q = q;
break; break;
case '[': { case '[': {
const char *endp; const char *savep, *saveq;
int invert, found; int invert, found;
wchar_t chr; wchar_t chr;
endp = p; savep = p, saveq = q;
if (*endp == '!' || *endp == '^')
endp++;
do {
while (*endp == CTLQUOTEMARK)
endp++;
if (*endp == 0)
goto dft; /* no matching ] */
if (*endp == CTLESC)
endp++;
} while (*++endp != ']');
invert = 0; invert = 0;
if (*p == '!' || *p == '^') { if (*p == '!' || *p == '^') {
invert++; invert++;
@ -1497,6 +1487,11 @@ patmatch(const char *pattern, const char *string, int squoted)
chr = (unsigned char)*q++; chr = (unsigned char)*q++;
c = *p++; c = *p++;
do { do {
if (c == '\0') {
p = savep, q = saveq;
c = '[';
goto dft;
}
if (c == CTLQUOTEMARK) if (c == CTLQUOTEMARK)
continue; continue;
if (c == '[' && *p == ':') { if (c == '[' && *p == ':') {

View File

@ -39,6 +39,7 @@ FILES+= case16.0
FILES+= case17.0 FILES+= case17.0
FILES+= case18.0 FILES+= case18.0
FILES+= case19.0 FILES+= case19.0
FILES+= case20.0
FILES+= cd1.0 FILES+= cd1.0
FILES+= cd2.0 FILES+= cd2.0
FILES+= cd3.0 FILES+= cd3.0

View File

@ -0,0 +1,9 @@
# $FreeBSD$
# Shells do not agree about what this pattern should match, but it is
# certain that it must not crash and the missing close bracket must not
# be simply ignored.
case B in
[[:alpha:]) echo bad ;;
esac