[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
1 changed files with 13 additions and 12 deletions

View File

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