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;
}