summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/glob.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-03-19 19:10:06 +0000
committerjlemon <jlemon@FreeBSD.org>2001-03-19 19:10:06 +0000
commitb7db4c94c39d3b8f980a3c3f3ce1166ce5c3004e (patch)
tree11eade290d26f8295a18604584895a81c44ad608 /lib/libc/gen/glob.c
parent5070a55a811bdaef9f6ed3c09aa7e24c47dd3f34 (diff)
downloadFreeBSD-src-b7db4c94c39d3b8f980a3c3f3ce1166ce5c3004e.zip
FreeBSD-src-b7db4c94c39d3b8f980a3c3f3ce1166ce5c3004e.tar.gz
Introduce the GLOB_MAXPATH flag, which allows the user to limit the
number of paths which glob(3) will return. Remove the hardcoded limit from the last commit, which restores the previous unbounded behavior. Document the new flag in the manual page.
Diffstat (limited to 'lib/libc/gen/glob.c')
-rw-r--r--lib/libc/gen/glob.c81
1 files changed, 42 insertions, 39 deletions
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
index 5ed8be4..1c1d8e0 100644
--- a/lib/libc/gen/glob.c
+++ b/lib/libc/gen/glob.c
@@ -80,14 +80,6 @@ static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#include "collate.h"
-/*
- * XXX
- * Arbitrarily limit the number of pathnames that glob may
- * return, to prevent DoS attacks. This should probably be
- * configurable by the user.
- */
-#define MAX_GLOBENTRIES 16384
-
#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
@@ -147,14 +139,14 @@ static Char *g_strchr __P((Char *, int));
static Char *g_strcat __P((Char *, const Char *));
#endif
static int g_stat __P((Char *, struct stat *, glob_t *));
-static int glob0 __P((const Char *, glob_t *));
-static int glob1 __P((Char *, glob_t *));
-static int glob2 __P((Char *, Char *, Char *, glob_t *));
-static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
-static int globextend __P((const Char *, glob_t *));
+static int glob0 __P((const Char *, glob_t *, int *));
+static int glob1 __P((Char *, glob_t *, int *));
+static int glob2 __P((Char *, Char *, Char *, glob_t *, int *));
+static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *, int *));
+static int globextend __P((const Char *, glob_t *, int *));
static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *));
-static int globexp1 __P((const Char *, glob_t *));
-static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
+static int globexp1 __P((const Char *, glob_t *, int *));
+static int globexp2 __P((const Char *, const Char *, glob_t *, int *, int *));
static int match __P((Char *, Char *, Char *));
#ifdef DEBUG
static void qprintf __P((const char *, Char *));
@@ -167,7 +159,7 @@ glob(pattern, flags, errfunc, pglob)
glob_t *pglob;
{
const u_char *patnext;
- int c;
+ int c, limit;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
patnext = (u_char *) pattern;
@@ -177,6 +169,10 @@ glob(pattern, flags, errfunc, pglob)
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
+ if (flags & GLOB_MAXPATH)
+ limit = pglob->gl_matchc;
+ else
+ limit = 0;
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
@@ -202,9 +198,9 @@ glob(pattern, flags, errfunc, pglob)
*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);
}
/*
@@ -212,22 +208,23 @@ glob(pattern, flags, errfunc, pglob)
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
-static int globexp1(pattern, pglob)
+static int globexp1(pattern, pglob, limit)
const Char *pattern;
glob_t *pglob;
+ int *limit;
{
const Char* ptr = pattern;
int rv;
/* 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((Char *) 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);
}
@@ -236,10 +233,10 @@ static int globexp1(pattern, pglob)
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
-static int globexp2(ptr, pattern, pglob, rv)
+static int globexp2(ptr, pattern, pglob, rv, limit)
const Char *ptr, *pattern;
glob_t *pglob;
- int *rv;
+ int *rv, *limit;
{
int i;
Char *lm, *ls;
@@ -275,7 +272,7 @@ static int globexp2(ptr, pattern, pglob, rv)
/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == EOS) {
- *rv = glob0(patbuf, pglob);
+ *rv = glob0(patbuf, pglob, limit);
return 0;
}
@@ -322,7 +319,7 @@ static int globexp2(ptr, pattern, pglob, rv)
#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;
@@ -416,9 +413,10 @@ globtilde(pattern, patbuf, patbuf_len, pglob)
* to find no matches.
*/
static int
-glob0(pattern, pglob)
+glob0(pattern, pglob, limit)
const Char *pattern;
glob_t *pglob;
+ int *limit;
{
const Char *qpatnext;
int c, err, oldpathc;
@@ -481,7 +479,7 @@ glob0(pattern, pglob)
qprintf("glob0:", patbuf);
#endif
- if ((err = glob1(patbuf, pglob)) != 0)
+ if ((err = glob1(patbuf, pglob, limit)) != 0)
return(err);
/*
@@ -494,7 +492,7 @@ glob0(pattern, pglob)
((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
- return(globextend(pattern, pglob));
+ return(globextend(pattern, pglob, limit));
else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
@@ -509,16 +507,17 @@ compare(p, q)
}
static int
-glob1(pattern, pglob)
+glob1(pattern, pglob, limit)
Char *pattern;
glob_t *pglob;
+ int *limit;
{
Char pathbuf[MAXPATHLEN+1];
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
- return(glob2(pathbuf, pathbuf, pattern, pglob));
+ return(glob2(pathbuf, pathbuf, pattern, pglob, limit));
}
/*
@@ -527,9 +526,10 @@ glob1(pattern, pglob)
* meta characters.
*/
static int
-glob2(pathbuf, pathend, pattern, pglob)
+glob2(pathbuf, pathend, pattern, pglob, limit)
Char *pathbuf, *pathend, *pattern;
glob_t *pglob;
+ int *limit;
{
struct stat sb;
Char *p, *q;
@@ -554,7 +554,7 @@ glob2(pathbuf, pathend, pattern, pglob)
*pathend = EOS;
}
++pglob->gl_matchc;
- return(globextend(pathbuf, pglob));
+ return(globextend(pathbuf, pglob, limit));
}
/* Find end of next segment, copy tentatively to pathend. */
@@ -572,15 +572,17 @@ glob2(pathbuf, pathend, pattern, pglob)
while (*pattern == SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
- return(glob3(pathbuf, pathend, pattern, p, pglob));
+ return(glob3(pathbuf, pathend, pattern, p, pglob,
+ limit));
}
/* NOTREACHED */
}
static int
-glob3(pathbuf, pathend, pattern, restpattern, pglob)
+glob3(pathbuf, pathend, pattern, restpattern, pglob, limit)
Char *pathbuf, *pathend, *pattern, *restpattern;
glob_t *pglob;
+ int *limit;
{
register struct dirent *dp;
DIR *dirp;
@@ -630,7 +632,7 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob)
*pathend = EOS;
continue;
}
- err = glob2(pathbuf, --dc, restpattern, pglob);
+ err = glob2(pathbuf, --dc, restpattern, pglob, limit);
if (err)
break;
}
@@ -658,9 +660,10 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob)
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
-globextend(path, pglob)
+globextend(path, pglob, limit)
const Char *path;
glob_t *pglob;
+ int *limit;
{
register char **pathv;
register int i;
@@ -668,8 +671,8 @@ globextend(path, pglob)
char *copy;
const Char *p;
- if (pglob->gl_pathc > MAX_GLOBENTRIES)
- return (GLOB_ABEND);
+ if (*limit && pglob->gl_pathc > *limit)
+ return (GLOB_LIMIT);
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
OpenPOWER on IntegriCloud