diff options
author | Damien Miller <djm@mindrot.org> | 2011-09-22 21:21:48 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2011-09-22 21:21:48 +1000 |
commit | c4bf7dde9231194f4e38140a46e9957758317cb5 (patch) | |
tree | a1762d118f47f2ec8024d84600d76c342900a5f9 /openbsd-compat | |
parent | e01a6270477bc4037ec8b48c5c19caf6be0818c6 (diff) |
- 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
Diffstat (limited to 'openbsd-compat')
-rw-r--r-- | openbsd-compat/glob.c | 22 |
1 files changed, 17 insertions, 5 deletions
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); |