Source-Changes-HG archive

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

[src/netbsd-1-5]: src/lib/libc/gen pull up revs 1.13 - 1.20 (for christos):



details:   https://anonhg.NetBSD.org/src/rev/311742f351c5
branches:  netbsd-1-5
changeset: 490968:311742f351c5
user:      lukem <lukem%NetBSD.org@localhost>
date:      Thu Mar 29 13:03:58 2001 +0000

description:
pull up revs 1.13 - 1.20 (for christos):
        * deal with buffer overflows for fixed length buffers
        * set gl_pathv to NULL after we free it
        * implement GLOB_LIMIT to limit the amount of memory used to ARG_MAX
        * squash lint errors by using size_t instead of u_int

diffstat:

 lib/libc/gen/__glob13.c |  168 ++++++++++++++++++++++++++++--------------------
 1 files changed, 98 insertions(+), 70 deletions(-)

diffs (truncated from 438 to 300 lines):

diff -r e7cf33255ae7 -r 311742f351c5 lib/libc/gen/__glob13.c
--- a/lib/libc/gen/__glob13.c   Thu Mar 29 13:01:38 2001 +0000
+++ b/lib/libc/gen/__glob13.c   Thu Mar 29 13:03:58 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: __glob13.c,v 1.13 2000/01/22 22:19:09 mycroft Exp $    */
+/*     $NetBSD: __glob13.c,v 1.13.4.1 2001/03/29 13:03:58 lukem Exp $  */
 
 /*
  * Copyright (c) 1989, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)glob.c     8.3 (Berkeley) 10/13/93";
 #else
-__RCSID("$NetBSD: __glob13.c,v 1.13 2000/01/22 22:19:09 mycroft Exp $");
+__RCSID("$NetBSD: __glob13.c,v 1.13.4.1 2001/03/29 13:03:58 lukem Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -89,6 +89,13 @@
 #endif /* __LIBC12_SOURCE__ */
 #endif /* __weak_alias */
 
+/*
+ * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)
+ */
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(a)
+#endif
+
 #ifdef __LIBC12_SOURCE__
 #define        STAT    stat12
 #else
@@ -153,20 +160,18 @@
 
 
 static int      compare __P((const void *, const void *));
-static void     g_Ctoc __P((const Char *, char *));
+static int      g_Ctoc __P((const Char *, char *, size_t));
 static int      g_lstat __P((Char *, struct STAT *, glob_t *));
 static DIR     *g_opendir __P((Char *, glob_t *));
 static Char    *g_strchr __P((const Char *, int));
-#ifdef notdef
-static Char    *g_strcat __P((Char *, const Char *));
-#endif
 static int      g_stat __P((Char *, struct STAT *, glob_t *));
 static int      glob0 __P((const Char *, glob_t *));
-static int      glob1 __P((Char *, glob_t *));
-static int      glob2 __P((Char *, Char *, Char *, glob_t *));
-static int      glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
-static int      globextend __P((const Char *, glob_t *));
-static const Char *     globtilde __P((const Char *, Char *, glob_t *));
+static int      glob1 __P((Char *, glob_t *, size_t *));
+static int      glob2 __P((Char *, Char *, Char *, glob_t *, size_t *));
+static int      glob3 __P((Char *, Char *, Char *, Char *, glob_t *,
+    size_t *));
+static int      globextend __P((const Char *, glob_t *, size_t *));
+static const Char *     globtilde __P((const Char *, Char *, size_t, glob_t *));
 static int      globexp1 __P((const Char *, glob_t *));
 static int      globexp2 __P((const Char *, const Char *, glob_t *, int *));
 static int      match __P((Char *, Char *, Char *));
@@ -200,8 +205,8 @@
        bufnext = patbuf;
        bufend = bufnext + MAXPATHLEN;
        if (flags & GLOB_NOESCAPE) {
-           while (bufnext < bufend && (c = *patnext++) != EOS) 
-                   *bufnext++ = c;
+               while (bufnext < bufend && (c = *patnext++) != EOS) 
+                       *bufnext++ = c;
        } else {
                /* Protect the quoted characters. */
                while (bufnext < bufend && (c = *patnext++) != EOS) 
@@ -305,7 +310,7 @@
                return 0;
        }
 
-       for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+       for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
                switch (*pm) {
                case LBRACKET:
                        /* Ignore everything between [] */
@@ -326,8 +331,8 @@
 
                case RBRACE:
                        if (i) {
-                           i--;
-                           break;
+                               i--;
+                               break;
                        }
                        /* FALLTHROUGH */
                case COMMA:
@@ -358,6 +363,7 @@
                default:
                        break;
                }
+       }
        *rv = 0;
        return 0;
 }
@@ -368,9 +374,10 @@
  * expand tilde from the passwd file.
  */
 static const Char *
-globtilde(pattern, patbuf, pglob)
+globtilde(pattern, patbuf, patsize, pglob)
        const Char *pattern;
        Char *patbuf;
+       size_t patsize;
        glob_t *pglob;
 {
        struct passwd *pwd;
@@ -378,6 +385,9 @@
        const Char *p;
        Char *b;
        char *d;
+       Char *pend = &patbuf[patsize];
+
+       pend--;
 
        _DIAGASSERT(pattern != NULL);
        _DIAGASSERT(patbuf != NULL);
@@ -387,10 +397,14 @@
                return pattern;
 
        /* Copy up to the end of the string or / */
-       for (p = pattern + 1, d = (char *)(void *)patbuf; *p && *p != SLASH; 
+       for (p = pattern + 1, d = (char *)(void *)patbuf; 
+            d < (char *)(void *)pend && *p && *p != SLASH; 
             *d++ = *p++)
                continue;
 
+       if (d == (char *)(void *)pend)
+               return NULL;
+
        *d = EOS;
        d = (char *)(void *)patbuf;
 
@@ -417,13 +431,19 @@
        }
 
        /* Copy the home directory */
-       for (b = patbuf; *h; *b++ = *h++)
+       for (b = patbuf; b < pend && *h; *b++ = *h++)
                continue;
+
+       if (b == pend)
+               return NULL;
        
        /* Append the rest of the pattern */
-       while ((*b++ = *p++) != EOS)
+       while (b < pend && (*b++ = *p++) != EOS)
                continue;
 
+       if (b == pend)
+               return NULL;
+
        return patbuf;
 }
        
@@ -443,11 +463,13 @@
        const Char *qpatnext;
        int c, err, oldpathc;
        Char *bufnext, patbuf[MAXPATHLEN+1];
+       size_t limit = 0;
 
        _DIAGASSERT(pattern != NULL);
        _DIAGASSERT(pglob != NULL);
 
-       qpatnext = globtilde(pattern, patbuf, pglob);
+       if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf), pglob)) == NULL)
+               return GLOB_ABEND;
        oldpathc = pglob->gl_pathc;
        bufnext = patbuf;
 
@@ -491,7 +513,7 @@
                         * to avoid exponential behavior
                         */
                        if (bufnext == patbuf || bufnext[-1] != M_ALL)
-                           *bufnext++ = M_ALL;
+                               *bufnext++ = M_ALL;
                        break;
                default:
                        *bufnext++ = CHAR(c);
@@ -503,7 +525,7 @@
        qprintf("glob0:", patbuf);
 #endif
 
-       if ((err = glob1(patbuf, pglob)) != 0)
+       if ((err = glob1(patbuf, pglob, &limit)) != 0)
                return(err);
 
        if (pglob->gl_pathc == oldpathc) {      
@@ -517,7 +539,7 @@
                if ((pglob->gl_flags & GLOB_NOCHECK) ||
                    ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))
                     == GLOB_NOMAGIC)) {
-                       if ((err = globextend(pattern, pglob)) != 0)
+                       if ((err = globextend(pattern, pglob, &limit)) != 0)
                                return (err);
                } else {
                        return (GLOB_NOMATCH);
@@ -543,9 +565,10 @@
 }
 
 static int
-glob1(pattern, pglob)
+glob1(pattern, pglob, limit)
        Char *pattern;
        glob_t *pglob;
+       size_t *limit;
 {
        Char pathbuf[MAXPATHLEN+1];
 
@@ -555,7 +578,7 @@
        /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
        if (*pattern == EOS)
                return(0);
-       return(glob2(pathbuf, pathbuf, pattern, pglob));
+       return(glob2(pathbuf, pathbuf, pattern, pglob, limit));
 }
 
 /*
@@ -564,9 +587,10 @@
  * meta characters.
  */
 static int
-glob2(pathbuf, pathend, pattern, pglob)
+glob2(pathbuf, pathend, pattern, pglob, limit)
        Char *pathbuf, *pathend, *pattern;
        glob_t *pglob;
+       size_t *limit;
 {
        struct STAT sb;
        Char *p, *q;
@@ -588,15 +612,15 @@
                                return(0);
                
                        if (((pglob->gl_flags & GLOB_MARK) &&
-                           pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
-                           || (S_ISLNK(sb.st_mode) &&
+                           pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
+                           (S_ISLNK(sb.st_mode) &&
                            (g_stat(pathbuf, &sb, pglob) == 0) &&
                            S_ISDIR(sb.st_mode)))) {
                                *pathend++ = SEP;
                                *pathend = EOS;
                        }
                        ++pglob->gl_matchc;
-                       return(globextend(pathbuf, pglob));
+                       return(globextend(pathbuf, pglob, limit));
                }
 
                /* Find end of next segment, copy tentatively to pathend. */
@@ -614,15 +638,17 @@
                        while (*pattern == SEP)
                                *pathend++ = *pattern++;
                } else                  /* Need expansion, recurse. */
-                       return(glob3(pathbuf, pathend, pattern, p, pglob));
+                       return(glob3(pathbuf, pathend, pattern, p, pglob,
+                           limit));
        }
        /* NOTREACHED */
 }
 
 static int
-glob3(pathbuf, pathend, pattern, restpattern, pglob)
+glob3(pathbuf, pathend, pattern, restpattern, pglob, limit)
        Char *pathbuf, *pathend, *pattern, *restpattern;
        glob_t *pglob;
+       size_t *limit;
 {
        struct dirent *dp;
        DIR *dirp;
@@ -649,7 +675,8 @@
        if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
                /* TODO: don't call for ENOENT or ENOTDIR? */
                if (pglob->gl_errfunc) {
-                       g_Ctoc(pathbuf, buf);
+                       if (g_Ctoc(pathbuf, buf, sizeof(buf)))
+                               return (GLOB_ABORTED);
                        if (pglob->gl_errfunc(buf, errno) ||
                            pglob->gl_flags & GLOB_ERR)
                                return (GLOB_ABORTED);
@@ -678,7 +705,7 @@
                        *pathend = EOS;
                        continue;
                }
-               err = glob2(pathbuf, --dc, restpattern, pglob);
+               err = glob2(pathbuf, --dc, restpattern, pglob, limit);
                if (err)
                        break;
        }
@@ -706,13 +733,14 @@
  *     gl_pathv points to (gl_offs + gl_pathc + 1) items.
  */
 static int
-globextend(path, pglob)
+globextend(path, pglob, limit)
        const Char *path;
        glob_t *pglob;



Home | Main Index | Thread Index | Old Index