[glob.c]
     In glob(3), limit recursion during matching attempts. Similar to
     fnmatch fix. Also collapse consecutive '*' (from NetBSD).
     ok miod deraadt
This commit is contained in:
Damien Miller 2011-09-22 21:21:48 +10:00
parent e01a627047
commit c4bf7dde92
2 changed files with 22 additions and 5 deletions

View File

@ -6,6 +6,11 @@
an error is returned but closedir() is not called. an error is returned but closedir() is not called.
spotted and fix provided by Frank Denis obsd-tech@pureftpd.org spotted and fix provided by Frank Denis obsd-tech@pureftpd.org
ok otto@, millert@ ok otto@, millert@
- stsp@cvs.openbsd.org 2011/09/20 10:18:46
[glob.c]
In glob(3), limit recursion during matching attempts. Similar to
fnmatch fix. Also collapse consecutive '*' (from NetBSD).
ok miod deraadt
20110909 20110909
- (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From

View File

@ -1,4 +1,4 @@
/* $OpenBSD: glob.c,v 1.36 2011/05/12 07:15:10 pyr Exp $ */ /* $OpenBSD: glob.c,v 1.37 2011/09/20 10:18:46 stsp Exp $ */
/* /*
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
@ -66,6 +66,7 @@
#include <dirent.h> #include <dirent.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#include <pwd.h> #include <pwd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -138,6 +139,9 @@ struct glob_lim {
size_t glim_readdir; size_t glim_readdir;
}; };
/* Limit of recursion during matching attempts. */
#define GLOB_LIMIT_RECUR 64
static int compare(const void *, const void *); static int compare(const void *, const void *);
static int g_Ctoc(const Char *, char *, u_int); static int g_Ctoc(const Char *, char *, u_int);
static int g_lstat(Char *, struct stat *, glob_t *); static int g_lstat(Char *, struct stat *, glob_t *);
@ -158,7 +162,7 @@ static const Char *
static int globexp1(const Char *, glob_t *, struct glob_lim *); static int globexp1(const Char *, glob_t *, struct glob_lim *);
static int globexp2(const Char *, const Char *, glob_t *, static int globexp2(const Char *, const Char *, glob_t *,
struct glob_lim *); struct glob_lim *);
static int match(Char *, Char *, Char *); static int match(Char *, Char *, Char *, int);
#ifdef DEBUG #ifdef DEBUG
static void qprintf(const char *, Char *); static void qprintf(const char *, Char *);
#endif #endif
@ -172,6 +176,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
Char *bufnext, *bufend, patbuf[MAXPATHLEN]; Char *bufnext, *bufend, patbuf[MAXPATHLEN];
struct glob_lim limit = { 0, 0, 0 }; struct glob_lim limit = { 0, 0, 0 };
if (strnlen(pattern, PATH_MAX) == PATH_MAX)
return(GLOB_NOMATCH);
patnext = (u_char *) pattern; patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) { if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0; pglob->gl_pathc = 0;
@ -714,7 +721,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
break; break;
} }
if (!match(pathend, pattern, restpattern)) { if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) {
*pathend = EOS; *pathend = EOS;
continue; continue;
} }
@ -851,19 +858,24 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
* pattern causes a recursion level. * pattern causes a recursion level.
*/ */
static int static int
match(Char *name, Char *pat, Char *patend) match(Char *name, Char *pat, Char *patend, int recur)
{ {
int ok, negate_range; int ok, negate_range;
Char c, k; Char c, k;
if (recur-- == 0)
return(GLOB_NOSPACE);
while (pat < patend) { while (pat < patend) {
c = *pat++; c = *pat++;
switch (c & M_MASK) { switch (c & M_MASK) {
case M_ALL: case M_ALL:
while (pat < patend && (*pat & M_MASK) == M_ALL)
pat++; /* eat consecutive '*' */
if (pat == patend) if (pat == patend)
return(1); return(1);
do { do {
if (match(name, pat, patend)) if (match(name, pat, patend, recur))
return(1); return(1);
} while (*name++ != EOS); } while (*name++ != EOS);
return(0); return(0);