bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

glob() bug when expanding braces


From: Flavio Veloso
Subject: glob() bug when expanding braces
Date: Thu, 29 Nov 2001 08:33:58 -0200 (BRST)

Hi.

There's a bug in the current implementation of the glob() function. It
may access invalid memory regions if faced with a glob pattern ending
with "{" and if GLOB_BRACE was used. It is very rare to see the bug in
action (the function most likely find a "}" before reaching the bottom
of the stack).

Here's a small test program:

#include <stdio.h>
#include <string.h>
#include <glob.h>
main()
{
        glob_t gl;
        char pattern[] = "{";
        memset(&gl, 0, sizeof(gl));
        glob(pattern, GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE, NULL, &gl);
}

(If it does not core dump, try "./././././a.out", or else link it with
-lefence.)

The problem is that next_brace_sub() (sysdeps/generic/glob.c) may
return a pointer to the final NUL, making glob() start to read memory
after it. This may make the function access memory pages it's not
supposed to, which eventually result in a crash.

A patch is provided below. It also cleans up the next_brace_sub()
function a little. As a side effect it will make glob constructs like
"{{a,b},c}" expand to "a b c". Previously it would return an unmatched
"{{a,b},c}". Any feedback is welcome.


2001-11-28  Flavio Veloso  <address@hidden>

        * sysdeps/generic/glob.c (next_brace_sub): Fix return of pointer
        to NUL char if opening brace is the last character in the
        string.
        Make "{{a,b},c}" expand to "a", "b", and "c".
        Cleanups.

--- sysdeps/generic/glob.c.orig Wed Nov 28 18:31:21 2001
+++ sysdeps/generic/glob.c      Wed Nov 28 19:15:33 2001
@@ -359,38 +359,22 @@
      const char *begin;
 {
   unsigned int depth = 0;
-  const char *cp = begin;

-  while (1)
+  while (*begin)
     {
-      if (depth == 0)
-       {
-         if (*cp != ',' && *cp != '}' && *cp != '\0')
-           {
-             if (*cp == '{')
-               ++depth;
-             ++cp;
-             continue;
-           }
+      if (*begin == '}' || *begin == ',')
+       {
+         if (depth == 0)
+           break;
+         if (*begin == '}')
+           depth--;
        }
-      else
-       {
-         while (*cp != '\0' && (*cp != '}' || depth > 0))
-           {
-             if (*cp == '}')
-               --depth;
-             ++cp;
-           }
-         if (*cp == '\0')
-           /* An incorrectly terminated brace expression.  */
-           return NULL;
-
-         continue;
-       }
-      break;
+      else if (*begin == '{')
+         depth++;
+      begin++;
     }

-  return cp;
+   return (*begin && depth == 0) ? begin : NULL;
 }

 #endif /* !GLOB_ONLY_P */


-- 
Flávio





reply via email to

[Prev in Thread] Current Thread [Next in Thread]