Module Name:    src
Committed By:   christos
Date:           Tue Jul  6 14:59:22 UTC 2010

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

Log Message:
Apply more limits to GLOB_LIMIT, number of stat(2) calls from me and number
of readdir(3) calls from Maksymilian Arciemowicz. Also reduce the memory
used by matches strings from Maksymilian Arciemowicz.


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/lib/libc/gen/glob.3
cvs rdiff -u -r1.25 -r1.26 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.3
diff -u src/lib/libc/gen/glob.3:1.36 src/lib/libc/gen/glob.3:1.37
--- src/lib/libc/gen/glob.3:1.36	Mon Mar 22 15:30:54 2010
+++ src/lib/libc/gen/glob.3	Tue Jul  6 10:59:22 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: glob.3,v 1.36 2010/03/22 19:30:54 joerg Exp $
+.\"	$NetBSD: glob.3,v 1.37 2010/07/06 14:59:22 christos Exp $
 .\"
 .\" Copyright (c) 1989, 1991, 1993, 1994
 .\"	The Regents of the University of California.  All rights reserved.
@@ -31,7 +31,7 @@
 .\"
 .\"     @(#)glob.3	8.3 (Berkeley) 4/16/94
 .\"
-.Dd April 8, 2009
+.Dd July 6, 2010
 .Dt GLOB 3
 .Os
 .Sh NAME
@@ -256,8 +256,13 @@
 .Ql ~
 to user name home directories.
 .It Dv GLOB_LIMIT
-Limit the amount of memory used by matches to
-.Li ARG_MAX .
+Limit the amount of memory used to store matched strings to
+.Li 64K ,
+the number of
+.Xr stat 2
+calls to 128, and the number of
+.Xr readdir 3
+calls to 16K.
 This option should be set for programs that can be coerced to a denial of
 service attack via patterns that expand to a very large number of matches,
 such as a long string of

Index: src/lib/libc/gen/glob.c
diff -u src/lib/libc/gen/glob.c:1.25 src/lib/libc/gen/glob.c:1.26
--- src/lib/libc/gen/glob.c:1.25	Fri Jul  2 17:13:10 2010
+++ src/lib/libc/gen/glob.c	Tue Jul  6 10:59:22 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: glob.c,v 1.25 2010/07/02 21:13:10 christos Exp $	*/
+/*	$NetBSD: glob.c,v 1.26 2010/07/06 14:59:22 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.25 2010/07/02 21:13:10 christos Exp $");
+__RCSID("$NetBSD: glob.c,v 1.26 2010/07/06 14:59:22 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -87,10 +87,13 @@
 #define NO_GETPW_R
 #endif
 
-#if !defined(ARG_MAX)
-#include <limits.h>
-#define	ARG_MAX	_POSIX_ARG_MAX
-#endif
+#define	GLOB_LIMIT_MALLOC	65536
+#define	GLOB_LIMIT_STAT		128
+#define	GLOB_LIMIT_READDIR	16384
+
+#define	GLOB_INDEX_MALLOC	0
+#define	GLOB_INDEX_STAT		1
+#define	GLOB_INDEX_READDIR	2
 
 /*
  * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)
@@ -178,7 +181,8 @@
 	const u_char *patnext;
 	int c;
 	Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
-	size_t limit = 0;
+	/* 0 = malloc(), 1 = stat(), 2 = readdir() */
+	size_t limit[] = { 0, 0, 0 };
 
 	_DIAGASSERT(pattern != NULL);
 
@@ -214,9 +218,9 @@
 	*bufnext = EOS;
 
 	if (flags & GLOB_BRACE)
-	    return globexp1(patbuf, pglob, &limit);
+	    return globexp1(patbuf, pglob, limit);
 	else
-	    return glob0(patbuf, pglob, &limit);
+	    return glob0(patbuf, pglob, limit);
 }
 
 /*
@@ -612,6 +616,13 @@
 			if (g_lstat(pathbuf, &sb, pglob))
 				return 0;
 		
+			if ((pglob->gl_flags & GLOB_LIMIT) &&
+			    limit[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) {
+				errno = 0;
+				*pathend++ = SEP;
+				*pathend = EOS;
+				return GLOB_NOSPACE;
+			}
 			if (((pglob->gl_flags & GLOB_MARK) &&
 			    pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
 			    (S_ISLNK(sb.st_mode) &&
@@ -728,6 +739,14 @@
 		u_char *sc;
 		Char *dc;
 
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit[GLOB_INDEX_READDIR]++ >= GLOB_LIMIT_READDIR) {
+			errno = 0;
+			*pathend++ = SEP;
+			*pathend = EOS;
+			return GLOB_NOSPACE;
+		}
+
 		/*
 		 * Initial DOT must be matched literally, unless we have
 		 * GLOB_PERIOD set.
@@ -774,7 +793,8 @@
 			*pathend = EOS;
 			continue;
 		}
-		error = glob2(pathbuf, --dc, pathlim, restpattern, pglob, limit);
+		error = glob2(pathbuf, --dc, pathlim, restpattern, pglob,
+		    limit);
 		if (error)
 			break;
 	}
@@ -836,7 +856,7 @@
 	for (p = path; *p++;)
 		continue;
 	len = (size_t)(p - path);
-	*limit += len;
+	limit[GLOB_INDEX_MALLOC] += len;
 	if ((copy = malloc(len)) != NULL) {
 		if (g_Ctoc(path, copy, len)) {
 			free(copy);
@@ -846,7 +866,8 @@
 	}
 	pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
 
-	if ((pglob->gl_flags & GLOB_LIMIT) && (newsize + *limit) >= ARG_MAX) {
+	if ((pglob->gl_flags & GLOB_LIMIT) &&
+	    (newsize + limit[GLOB_INDEX_MALLOC]) >= GLOB_LIMIT_MALLOC) {
 		errno = 0;
 		return GLOB_NOSPACE;
 	}

Reply via email to