|
1 diff --git a/include/glibc-glob.h b/include/glibc-glob.h |
|
2 index 422089a..a55899a 100644 |
|
3 --- a/include/glibc-glob.h |
|
4 +++ b/include/glibc-glob.h |
|
5 @@ -85,6 +85,7 @@ extern "C" { |
|
6 #define GLOB_ABORTED 2 /* Read error. */ |
|
7 #define GLOB_NOMATCH 3 /* No matches found. */ |
|
8 #define GLOB_NOSYS 4 /* Not implemented. */ |
|
9 +#define GLOB_LIMIT 5 /* MAX_RESULTS limit reached */ |
|
10 #ifdef _GNU_SOURCE |
|
11 /* Previous versions of this file defined GLOB_ABEND instead of |
|
12 GLOB_ABORTED. Provide a compatibility definition here. */ |
|
13 diff --git a/lib/glibc-glob.c b/lib/glibc-glob.c |
|
14 index 43b02bc..92c2b94 100644 |
|
15 --- a/lib/glibc-glob.c |
|
16 +++ b/lib/glibc-glob.c |
|
17 @@ -40,6 +40,15 @@ char *alloca (); |
|
18 #define MAX_RECURSION PR_TUNABLE_GLOBBING_MAX_RECURSION |
|
19 #define MAX_RESULTS PR_TUNABLE_GLOBBING_MAX_MATCHES |
|
20 |
|
21 +unsigned long GlobMaxResults = 0; |
|
22 + |
|
23 +static unsigned long get_globmaxresults(void) |
|
24 +{ |
|
25 + if (GlobMaxResults > 0) |
|
26 + return GlobMaxResults; |
|
27 + return MAX_RESULTS; |
|
28 +} |
|
29 + |
|
30 /* Enable GNU extensions in glob.h. */ |
|
31 #ifndef _GNU_SOURCE |
|
32 # define _GNU_SOURCE 1 |
|
33 @@ -239,8 +248,6 @@ extern void bcopy (); |
|
34 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) |
|
35 #endif |
|
36 |
|
37 -static unsigned long nbresults; |
|
38 - |
|
39 #ifndef __GNU_LIBRARY__ |
|
40 # ifdef __GNUC__ |
|
41 __inline |
|
42 @@ -1157,7 +1164,6 @@ int |
|
43 glob (const char *pattern, int flags, int (*errfunc) __P((const char *, int)), |
|
44 glob_t *pglob) |
|
45 { |
|
46 - nbresults = 0UL; |
|
47 return glob_limited(0U, pattern, flags, errfunc, pglob); |
|
48 } |
|
49 |
|
50 @@ -1318,6 +1324,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, |
|
51 size_t nfound; |
|
52 int meta; |
|
53 int save; |
|
54 + int ret_glob_limit = 0; |
|
55 |
|
56 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); |
|
57 if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) |
|
58 @@ -1428,10 +1435,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, |
|
59 #endif |
|
60 if (d == NULL) |
|
61 break; |
|
62 - if (nbresults > MAX_RESULTS) { |
|
63 - break; |
|
64 - } |
|
65 - nbresults++; |
|
66 if (! REAL_DIR_ENTRY (d)) |
|
67 continue; |
|
68 |
|
69 @@ -1463,6 +1466,14 @@ glob_in_dir (const char *pattern, const char *directory, int flags, |
|
70 new->next = names; |
|
71 names = new; |
|
72 ++nfound; |
|
73 + |
|
74 + if (nfound > get_globmaxresults()) { |
|
75 + for (; names != NULL; names = names->next) |
|
76 + free(names->name); |
|
77 + nfound = 0; |
|
78 + ret_glob_limit = 1; |
|
79 + break; |
|
80 + } |
|
81 } |
|
82 } |
|
83 } |
|
84 @@ -1516,6 +1527,9 @@ glob_in_dir (const char *pattern, const char *directory, int flags, |
|
85 } |
|
86 __set_errno (save); |
|
87 |
|
88 + if (ret_glob_limit) |
|
89 + return GLOB_LIMIT; |
|
90 + |
|
91 return nfound == 0 ? GLOB_NOMATCH : 0; |
|
92 |
|
93 memory_error: |
|
94 diff --git a/modules/mod_core.c b/modules/mod_core.c |
|
95 index e33ee11..1f6da19 100644 |
|
96 --- a/modules/mod_core.c |
|
97 +++ b/modules/mod_core.c |
|
98 @@ -973,6 +973,26 @@ MODRET set_maxconnrate(cmd_rec *cmd) { |
|
99 return PR_HANDLED(cmd); |
|
100 } |
|
101 |
|
102 +extern unsigned long GlobMaxResults; |
|
103 + |
|
104 +MODRET set_globmaxresults(cmd_rec *cmd) { |
|
105 + unsigned long max; |
|
106 + char *endp; |
|
107 + |
|
108 + CHECK_ARGS(cmd,1); |
|
109 + CHECK_CONF(cmd,CONF_ROOT); |
|
110 + |
|
111 + max = strtoul(cmd->argv[1], &endp, 10); |
|
112 + |
|
113 + if ((endp && *endp) || max == 0) |
|
114 + CONF_ERROR(cmd, "argument must be greater than 0"); |
|
115 + |
|
116 + pr_log_debug(DEBUG1, "setting GlobMaxResults to %lu", max); |
|
117 + |
|
118 + GlobMaxResults = max; |
|
119 + return PR_HANDLED(cmd); |
|
120 +} |
|
121 + |
|
122 MODRET set_timeoutidle(cmd_rec *cmd) { |
|
123 int timeout = -1; |
|
124 config_rec *c = NULL; |
|
125 @@ -6108,6 +6128,7 @@ static conftable core_conftab[] = { |
|
126 { "DisplayConnect", set_displayconnect, NULL }, |
|
127 { "DisplayQuit", set_displayquit, NULL }, |
|
128 { "From", add_from, NULL }, |
|
129 + { "GlobMaxResults", set_globmaxresults, NULL }, |
|
130 { "Group", set_group, NULL }, |
|
131 { "GroupOwner", add_groupowner, NULL }, |
|
132 { "HideFiles", set_hidefiles, NULL }, |
|
133 diff --git a/modules/mod_ls.c b/modules/mod_ls.c |
|
134 index 5b95d2b..e8bbb74 100644 |
|
135 --- a/modules/mod_ls.c |
|
136 +++ b/modules/mod_ls.c |
|
137 @@ -2015,6 +2015,8 @@ static int dolist(cmd_rec *cmd, const char *opt, int clearflags) { |
|
138 pr_response_add(R_226, _("Read error during globbing of %s"), |
|
139 pr_fs_encode_path(cmd->tmp_pool, arg)); |
|
140 |
|
141 + } else if (a == GLOB_LIMIT) { |
|
142 + pr_response_add(R_226, _("Too many files")); |
|
143 } else if (a != GLOB_NOMATCH) { |
|
144 pr_response_add(R_226, _("Unknown error during globbing of %s"), |
|
145 pr_fs_encode_path(cmd->tmp_pool, arg)); |
|
146 @@ -2837,7 +2839,10 @@ MODRET ls_nlst(cmd_rec *cmd) { |
|
147 return PR_HANDLED(cmd); |
|
148 } |
|
149 |
|
150 - pr_response_add_err(R_450, _("No files found")); |
|
151 + if (res == GLOB_LIMIT) |
|
152 + pr_response_add_err(R_451, _("Too many files")); |
|
153 + else |
|
154 + pr_response_add_err(R_450, _("No files found")); |
|
155 return PR_ERROR(cmd); |
|
156 } |
|
157 } |