Module Name:    src
Committed By:   christos
Date:           Fri Jul  2 21:13:10 UTC 2010

Modified Files:
        src/lib/libc/gen: glob.c

Log Message:
Avoid DoS attacks for patterns that have braces. Noted by Maksymilian
Arciemowicz.
XXX: Pullup to 5.x


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/lib/libc/gen/glob.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/glob.c
diff -u src/lib/libc/gen/glob.c:1.24 src/lib/libc/gen/glob.c:1.25
--- src/lib/libc/gen/glob.c:1.24	Wed Apr  8 12:28:50 2009
+++ src/lib/libc/gen/glob.c	Fri Jul  2 17:13:10 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: glob.c,v 1.24 2009/04/08 16:28:50 christos Exp $	*/
+/*	$NetBSD: glob.c,v 1.25 2010/07/02 21:13:10 christos Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)glob.c	8.3 (Berkeley) 10/13/93";
 #else
-__RCSID("$NetBSD: glob.c,v 1.24 2009/04/08 16:28:50 christos Exp $");
+__RCSID("$NetBSD: glob.c,v 1.25 2010/07/02 21:13:10 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -155,7 +155,7 @@
 static DIR	*g_opendir(Char *, glob_t *);
 static Char	*g_strchr(const Char *, int);
 static int	 g_stat(Char *, __gl_stat_t *, glob_t *);
-static int	 glob0(const Char *, glob_t *);
+static int	 glob0(const Char *, glob_t *, size_t *);
 static int	 glob1(Char *, glob_t *, size_t *);
 static int	 glob2(Char *, Char *, Char *, Char *, glob_t *,
     size_t *);
@@ -163,8 +163,9 @@
     size_t *);
 static int	 globextend(const Char *, glob_t *, size_t *);
 static const Char *globtilde(const Char *, Char *, size_t, glob_t *);
-static int	 globexp1(const Char *, glob_t *);
-static int	 globexp2(const Char *, const Char *, glob_t *, int *);
+static int	 globexp1(const Char *, glob_t *, size_t *);
+static int	 globexp2(const Char *, const Char *, glob_t *, int *,
+    size_t *);
 static int	 match(Char *, Char *, Char *);
 #ifdef DEBUG
 static void	 qprintf(const char *, Char *);
@@ -177,6 +178,7 @@
 	const u_char *patnext;
 	int c;
 	Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
+	size_t limit = 0;
 
 	_DIAGASSERT(pattern != NULL);
 
@@ -212,9 +214,9 @@
 	*bufnext = EOS;
 
 	if (flags & GLOB_BRACE)
-	    return globexp1(patbuf, pglob);
+	    return globexp1(patbuf, pglob, &limit);
 	else
-	    return glob0(patbuf, pglob);
+	    return glob0(patbuf, pglob, &limit);
 }
 
 /*
@@ -223,7 +225,7 @@
  * characters
  */
 static int
-globexp1(const Char *pattern, glob_t *pglob)
+globexp1(const Char *pattern, glob_t *pglob, size_t *limit)
 {
 	const Char* ptr = pattern;
 	int rv;
@@ -233,13 +235,13 @@
 
 	/* Protect a single {}, for find(1), like csh */
 	if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
-		return glob0(pattern, pglob);
+		return glob0(pattern, pglob, limit);
 
 	while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
-		if (!globexp2(ptr, pattern, pglob, &rv))
+		if (!globexp2(ptr, pattern, pglob, &rv, limit))
 			return rv;
 
-	return glob0(pattern, pglob);
+	return glob0(pattern, pglob, limit);
 }
 
 
@@ -249,7 +251,8 @@
  * If it fails then it tries to glob the rest of the pattern and returns.
  */
 static int
-globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv,
+    size_t *limit)
 {
 	int     i;
 	Char   *lm, *ls;
@@ -294,7 +297,7 @@
 		 * we use `pattern', not `patbuf' here so that that
 		 * unbalanced braces are passed to the match
 		 */
-		*rv = glob0(pattern, pglob);
+		*rv = glob0(pattern, pglob, limit);
 		return 0;
 	}
 
@@ -341,7 +344,7 @@
 #ifdef DEBUG
 				qprintf("globexp2:", patbuf);
 #endif
-				*rv = globexp1(patbuf, pglob);
+				*rv = globexp1(patbuf, pglob, limit);
 
 				/* move after the comma, to the next string */
 				pl = pm + 1;
@@ -454,13 +457,12 @@
  * to find no matches.
  */
 static int
-glob0(const Char *pattern, glob_t *pglob)
+glob0(const Char *pattern, glob_t *pglob, size_t *limit)
 {
 	const Char *qpatnext;
 	int c, error;
 	__gl_size_t oldpathc;
 	Char *bufnext, patbuf[MAXPATHLEN+1];
-	size_t limit = 0;
 
 	_DIAGASSERT(pattern != NULL);
 	_DIAGASSERT(pglob != NULL);
@@ -523,7 +525,7 @@
 	qprintf("glob0:", patbuf);
 #endif
 
-	if ((error = glob1(patbuf, pglob, &limit)) != 0)
+	if ((error = glob1(patbuf, pglob, limit)) != 0)
 		return error;
 
 	if (pglob->gl_pathc == oldpathc) {	
@@ -537,7 +539,7 @@
 		if ((pglob->gl_flags & GLOB_NOCHECK) ||
 		    ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))
 		     == GLOB_NOMAGIC)) {
-			return globextend(pattern, pglob, &limit);
+			return globextend(pattern, pglob, limit);
 		} else {
 			return GLOB_NOMATCH;
 		}

Reply via email to