[PATCH] fix possible buffer overflow

On Tue, Jan 27, 2004 at 11:02:25AM -0800, Greg KH wrote:
> On Mon, Jan 26, 2004 at 07:28:03PM -0500, Adrian Drzewiecki wrote:
> > Looking over the code, I noticed something odd in
> > namedev.c:strcmp_pattern() --
> >
> > 	while (*p && (*p != ']'))
> > 		p ++;
> > 	return strcmp_pattern(p+1, s+1);
> >
> > If the pattern string is invalid, and is not terminated by a ']', then 'p'
> > will point at \0 and p+1 will be beyond the string.
>
> Yes, I think you are correct.
>
> Hm, Kay, any idea of the proper way to fix this?  I've attached a patch
> below, but I don't think it is correct.
>
>  					while (*p && (*p != ']'))
>  						p++;
> -					return strcmp_pattern(p+1, s+1);
> +					if (*p)
> +						return strcmp_pattern(p+1, s+1);
> +					else
> +						return 1;
>  				}
>  			}


Sure, it's perfectly correct. I'm wondering how Adrian found this.

We can use the return 1 at the end of the whole function, and asking
for the closing ']' is more descriptive, but it does the same.

-					return strcmp_pattern(p+1, s+1);
+					if (*p == ']')
+						return strcmp_pattern(p+1, s+1);

Patch is attached, that also replaces all the *s with s[0].
This commit is contained in:
kay.sievers@vrfy.org 2004-01-28 19:00:51 -08:00 committed by Greg KH
parent bc59f0167a
commit 8a08e4b190

View File

@ -47,33 +47,34 @@ LIST_HEAD(perm_device_list);
/* compare string with pattern (supports * ? [0-9] [!A-Z]) */ /* compare string with pattern (supports * ? [0-9] [!A-Z]) */
static int strcmp_pattern(const char *p, const char *s) static int strcmp_pattern(const char *p, const char *s)
{ {
if (*s == '\0') { if (s[0] == '\0') {
while (*p == '*') while (p[0] == '*')
p++; p++;
return (*p != '\0'); return (p[0] != '\0');
} }
switch (*p) { switch (p[0]) {
case '[': case '[':
{ {
int not = 0; int not = 0;
p++; p++;
if (*p == '!') { if (p[0] == '!') {
not = 1; not = 1;
p++; p++;
} }
while (*p && (*p != ']')) { while ((p[0] != '\0') && (p[0] != ']')) {
int match = 0; int match = 0;
if (p[1] == '-') { if (p[1] == '-') {
if ((*s >= *p) && (*s <= p[2])) if ((s[0] >= p[0]) && (s[0] <= p[2]))
match = 1; match = 1;
p += 3; p += 3;
} else { } else {
match = (*p == *s); match = (p[0] == s[0]);
p++; p++;
} }
if (match ^ not) { if (match ^ not) {
while (*p && (*p != ']')) while ((p[0] != '\0') && (p[0] != ']'))
p++; p++;
if (p[0] == ']')
return strcmp_pattern(p+1, s+1); return strcmp_pattern(p+1, s+1);
} }
} }
@ -84,12 +85,12 @@ static int strcmp_pattern(const char *p, const char *s)
return strcmp_pattern(p+1, s); return strcmp_pattern(p+1, s);
return 0; return 0;
case '\0': case '\0':
if (*s == '\0') { if (s[0] == '\0') {
return 0; return 0;
} }
break; break;
default: default:
if ((*p == *s) || (*p == '?')) if ((p[0] == s[0]) || (p[0] == '?'))
return strcmp_pattern(p+1, s+1); return strcmp_pattern(p+1, s+1);
break; break;
} }