chiark / gitweb /
[PATCH] fix possible buffer overflow
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Thu, 29 Jan 2004 03:00:51 +0000 (19:00 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:13:20 +0000 (21:13 -0700)
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].

namedev.c

index de7f7c1b88e3c4196269385d9fd40af868645647..6685596479ac14102246ab40c555b51886ceb303 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -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;
        }