diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | openbsd-compat/glob.c | 22 |
2 files changed, 22 insertions, 5 deletions
@@ -6,6 +6,11 @@ | |||
6 | an error is returned but closedir() is not called. | 6 | an error is returned but closedir() is not called. |
7 | spotted and fix provided by Frank Denis obsd-tech@pureftpd.org | 7 | spotted and fix provided by Frank Denis obsd-tech@pureftpd.org |
8 | ok otto@, millert@ | 8 | ok otto@, millert@ |
9 | - stsp@cvs.openbsd.org 2011/09/20 10:18:46 | ||
10 | [glob.c] | ||
11 | In glob(3), limit recursion during matching attempts. Similar to | ||
12 | fnmatch fix. Also collapse consecutive '*' (from NetBSD). | ||
13 | ok miod deraadt | ||
9 | 14 | ||
10 | 20110909 | 15 | 20110909 |
11 | - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From | 16 | - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From |
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index ebb7aa805..85fccf4d1 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: glob.c,v 1.36 2011/05/12 07:15:10 pyr Exp $ */ | 1 | /* $OpenBSD: glob.c,v 1.37 2011/09/20 10:18:46 stsp Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1989, 1993 | 3 | * Copyright (c) 1989, 1993 |
4 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -66,6 +66,7 @@ | |||
66 | #include <dirent.h> | 66 | #include <dirent.h> |
67 | #include <ctype.h> | 67 | #include <ctype.h> |
68 | #include <errno.h> | 68 | #include <errno.h> |
69 | #include <limits.h> | ||
69 | #include <pwd.h> | 70 | #include <pwd.h> |
70 | #include <stdlib.h> | 71 | #include <stdlib.h> |
71 | #include <string.h> | 72 | #include <string.h> |
@@ -138,6 +139,9 @@ struct glob_lim { | |||
138 | size_t glim_readdir; | 139 | size_t glim_readdir; |
139 | }; | 140 | }; |
140 | 141 | ||
142 | /* Limit of recursion during matching attempts. */ | ||
143 | #define GLOB_LIMIT_RECUR 64 | ||
144 | |||
141 | static int compare(const void *, const void *); | 145 | static int compare(const void *, const void *); |
142 | static int g_Ctoc(const Char *, char *, u_int); | 146 | static int g_Ctoc(const Char *, char *, u_int); |
143 | static int g_lstat(Char *, struct stat *, glob_t *); | 147 | static int g_lstat(Char *, struct stat *, glob_t *); |
@@ -158,7 +162,7 @@ static const Char * | |||
158 | static int globexp1(const Char *, glob_t *, struct glob_lim *); | 162 | static int globexp1(const Char *, glob_t *, struct glob_lim *); |
159 | static int globexp2(const Char *, const Char *, glob_t *, | 163 | static int globexp2(const Char *, const Char *, glob_t *, |
160 | struct glob_lim *); | 164 | struct glob_lim *); |
161 | static int match(Char *, Char *, Char *); | 165 | static int match(Char *, Char *, Char *, int); |
162 | #ifdef DEBUG | 166 | #ifdef DEBUG |
163 | static void qprintf(const char *, Char *); | 167 | static void qprintf(const char *, Char *); |
164 | #endif | 168 | #endif |
@@ -172,6 +176,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), | |||
172 | Char *bufnext, *bufend, patbuf[MAXPATHLEN]; | 176 | Char *bufnext, *bufend, patbuf[MAXPATHLEN]; |
173 | struct glob_lim limit = { 0, 0, 0 }; | 177 | struct glob_lim limit = { 0, 0, 0 }; |
174 | 178 | ||
179 | if (strnlen(pattern, PATH_MAX) == PATH_MAX) | ||
180 | return(GLOB_NOMATCH); | ||
181 | |||
175 | patnext = (u_char *) pattern; | 182 | patnext = (u_char *) pattern; |
176 | if (!(flags & GLOB_APPEND)) { | 183 | if (!(flags & GLOB_APPEND)) { |
177 | pglob->gl_pathc = 0; | 184 | pglob->gl_pathc = 0; |
@@ -714,7 +721,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, | |||
714 | break; | 721 | break; |
715 | } | 722 | } |
716 | 723 | ||
717 | if (!match(pathend, pattern, restpattern)) { | 724 | if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) { |
718 | *pathend = EOS; | 725 | *pathend = EOS; |
719 | continue; | 726 | continue; |
720 | } | 727 | } |
@@ -851,19 +858,24 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, | |||
851 | * pattern causes a recursion level. | 858 | * pattern causes a recursion level. |
852 | */ | 859 | */ |
853 | static int | 860 | static int |
854 | match(Char *name, Char *pat, Char *patend) | 861 | match(Char *name, Char *pat, Char *patend, int recur) |
855 | { | 862 | { |
856 | int ok, negate_range; | 863 | int ok, negate_range; |
857 | Char c, k; | 864 | Char c, k; |
858 | 865 | ||
866 | if (recur-- == 0) | ||
867 | return(GLOB_NOSPACE); | ||
868 | |||
859 | while (pat < patend) { | 869 | while (pat < patend) { |
860 | c = *pat++; | 870 | c = *pat++; |
861 | switch (c & M_MASK) { | 871 | switch (c & M_MASK) { |
862 | case M_ALL: | 872 | case M_ALL: |
873 | while (pat < patend && (*pat & M_MASK) == M_ALL) | ||
874 | pat++; /* eat consecutive '*' */ | ||
863 | if (pat == patend) | 875 | if (pat == patend) |
864 | return(1); | 876 | return(1); |
865 | do { | 877 | do { |
866 | if (match(name, pat, patend)) | 878 | if (match(name, pat, patend, recur)) |
867 | return(1); | 879 | return(1); |
868 | } while (*name++ != EOS); | 880 | } while (*name++ != EOS); |
869 | return(0); | 881 | return(0); |