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