Source-Changes-HG archive

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

[src/netbsd-1-4]: src/lib/libc/gen Pull up revisions 1.11-1.20 (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/2282bd0dcd0c
branches:  netbsd-1-4
changeset: 471277:2282bd0dcd0c
user:      he <he%NetBSD.org@localhost>
date:      Sun Apr 01 16:07:40 2001 +0000

description:
Pull up revisions 1.11-1.20 (requested by christos):
  Fixes buffer overflow problems in glob(3).  Adds and uses GLOB_LIMIT
  to prevent denial of service attacks.
(syncs to current head of trunk).

diffstat:

 lib/libc/gen/__glob13.c |  240 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 169 insertions(+), 71 deletions(-)

diffs (truncated from 585 to 300 lines):

diff -r 0ca18ab625df -r 2282bd0dcd0c lib/libc/gen/__glob13.c
--- a/lib/libc/gen/__glob13.c   Sun Apr 01 16:07:04 2001 +0000
+++ b/lib/libc/gen/__glob13.c   Sun Apr 01 16:07:40 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: __glob13.c,v 1.10 1999/02/07 12:19:37 lukem Exp $      */
+/*     $NetBSD: __glob13.c,v 1.10.2.1 2001/04/01 16:07:40 he 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.10 1999/02/07 12:19:37 lukem Exp $");
+__RCSID("$NetBSD: __glob13.c,v 1.10.2.1 2001/04/01 16:07:40 he Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -71,6 +71,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
@@ -83,11 +84,18 @@
 
 #ifdef __weak_alias
 #ifdef __LIBC12_SOURCE__
-__weak_alias(glob,_glob);
-__weak_alias(globfree,_globfree);
+__weak_alias(glob,_glob)
+__weak_alias(globfree,_globfree)
 #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
@@ -152,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 *));
@@ -183,6 +189,8 @@
        int c;
        Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
 
+       _DIAGASSERT(pattern != NULL);
+
        patnext = (const u_char *) pattern;
        if (!(flags & GLOB_APPEND)) {
                pglob->gl_pathc = 0;
@@ -197,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) 
@@ -225,13 +233,17 @@
  * invoke the standard globbing routine to glob the rest of the magic
  * characters
  */
-static int globexp1(pattern, pglob)
+static int
+globexp1(pattern, pglob)
        const Char *pattern;
        glob_t *pglob;
 {
        const Char* ptr = pattern;
        int rv;
 
+       _DIAGASSERT(pattern != NULL);
+       _DIAGASSERT(pglob != NULL);
+
        /* Protect a single {}, for find(1), like csh */
        if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
                return glob0(pattern, pglob);
@@ -249,7 +261,8 @@
  * If it succeeds then it invokes globexp1 with the new pattern.
  * If it fails then it tries to glob the rest of the pattern and returns.
  */
-static int globexp2(ptr, pattern, pglob, rv)
+static int
+globexp2(ptr, pattern, pglob, rv)
        const Char *ptr, *pattern;
        glob_t *pglob;
        int *rv;
@@ -259,6 +272,11 @@
        const Char *pe, *pm, *pl;
        Char    patbuf[MAXPATHLEN + 1];
 
+       _DIAGASSERT(ptr != NULL);
+       _DIAGASSERT(pattern != NULL);
+       _DIAGASSERT(pglob != NULL);
+       _DIAGASSERT(rv != NULL);
+
        /* copy part up to the brace */
        for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
                continue;
@@ -292,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 [] */
@@ -313,8 +331,8 @@
 
                case RBRACE:
                        if (i) {
-                           i--;
-                           break;
+                               i--;
+                               break;
                        }
                        /* FALLTHROUGH */
                case COMMA:
@@ -345,6 +363,7 @@
                default:
                        break;
                }
+       }
        *rv = 0;
        return 0;
 }
@@ -355,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;
@@ -365,15 +385,26 @@
        const Char *p;
        Char *b;
        char *d;
+       Char *pend = &patbuf[patsize];
+
+       pend--;
+
+       _DIAGASSERT(pattern != NULL);
+       _DIAGASSERT(patbuf != NULL);
+       _DIAGASSERT(pglob != NULL);
 
        if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
                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;
 
@@ -400,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;
 }
        
@@ -426,8 +463,13 @@
        const Char *qpatnext;
        int c, err, oldpathc;
        Char *bufnext, patbuf[MAXPATHLEN+1];
+       size_t limit = 0;
 
-       qpatnext = globtilde(pattern, patbuf, pglob);
+       _DIAGASSERT(pattern != NULL);
+       _DIAGASSERT(pglob != NULL);
+
+       if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf), pglob)) == NULL)
+               return GLOB_ABEND;
        oldpathc = pglob->gl_pathc;
        bufnext = patbuf;
 
@@ -471,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);
@@ -483,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) {      
@@ -497,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);
@@ -515,20 +557,28 @@
 compare(p, q)
        const void *p, *q;
 {
+
+       _DIAGASSERT(p != NULL);
+       _DIAGASSERT(q != NULL);
+
        return(strcoll(*(const char * const *)p, *(const char * const *)q));
 }
 
 static int
-glob1(pattern, pglob)
+glob1(pattern, pglob, limit)
        Char *pattern;
        glob_t *pglob;
+       size_t *limit;
 {
        Char pathbuf[MAXPATHLEN+1];
 
+       _DIAGASSERT(pattern != NULL);
+       _DIAGASSERT(pglob != NULL);
+
        /* 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));
 }
 
 /*
@@ -537,14 +587,20 @@



Home | Main Index | Thread Index | Old Index