Source-Changes-HG archive

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

[src/trunk]: src/lib/libc/gen Apply more limits to GLOB_LIMIT, number of stat...



details:   https://anonhg.NetBSD.org/src/rev/2db96ff07977
branches:  trunk
changeset: 756089:2db96ff07977
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Jul 06 14:59:22 2010 +0000

description:
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.

diffstat:

 lib/libc/gen/glob.3 |  13 +++++++++----
 lib/libc/gen/glob.c |  45 +++++++++++++++++++++++++++++++++------------
 2 files changed, 42 insertions(+), 16 deletions(-)

diffs (150 lines):

diff -r 3bd8bff371d2 -r 2db96ff07977 lib/libc/gen/glob.3
--- a/lib/libc/gen/glob.3       Tue Jul 06 14:47:48 2010 +0000
+++ b/lib/libc/gen/glob.3       Tue Jul 06 14:59:22 2010 +0000
@@ -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
diff -r 3bd8bff371d2 -r 2db96ff07977 lib/libc/gen/glob.c
--- a/lib/libc/gen/glob.c       Tue Jul 06 14:47:48 2010 +0000
+++ b/lib/libc/gen/glob.c       Tue Jul 06 14:59:22 2010 +0000
@@ -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;
        }



Home | Main Index | Thread Index | Old Index