1
Description: fix denial of service via crafted glob expressions
2
Origin: upstream, from 2.3.3 and 2.3.4 releases
4
diff -Nur vsftpd-2.2.0/access.c vsftpd-2.2.0.new/access.c
5
--- vsftpd-2.2.0/access.c 2008-02-01 20:30:41.000000000 -0500
6
+++ vsftpd-2.2.0.new/access.c 2011-03-25 14:52:17.963109891 -0400
8
vsf_access_check_file(const struct mystr* p_filename_str)
10
static struct mystr s_access_str;
11
+ unsigned int iters = 0;
13
if (!tunable_deny_file)
17
str_alloc_text(&s_access_str, tunable_deny_file);
19
- if (vsf_filename_passes_filter(p_filename_str, &s_access_str))
20
+ if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
25
vsf_access_check_file_visible(const struct mystr* p_filename_str)
27
static struct mystr s_access_str;
28
+ unsigned int iters = 0;
30
if (!tunable_hide_file)
34
str_alloc_text(&s_access_str, tunable_hide_file);
36
- if (vsf_filename_passes_filter(p_filename_str, &s_access_str))
37
+ if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
41
diff -Nur vsftpd-2.2.0/defs.h vsftpd-2.2.0.new/defs.h
42
--- vsftpd-2.2.0/defs.h 2009-01-07 15:22:22.000000000 -0500
43
+++ vsftpd-2.2.0.new/defs.h 2011-03-25 14:52:17.963109891 -0400
45
#define VSFTP_MAX_COMMAND_LINE 4096
46
#define VSFTP_DATA_BUFSIZE 65536
47
#define VSFTP_DIR_BUFSIZE 16384
48
+#define VSFTP_MATCHITERS_MAX 1000
49
#define VSFTP_PATH_MAX 4096
50
#define VSFTP_CONF_FILE_MAX 100000
51
#define VSFTP_LISTEN_BACKLOG 32
52
diff -Nur vsftpd-2.2.0/ls.c vsftpd-2.2.0.new/ls.c
53
--- vsftpd-2.2.0/ls.c 2008-02-01 20:30:41.000000000 -0500
54
+++ vsftpd-2.2.0.new/ls.c 2011-03-25 14:52:17.963109891 -0400
64
/* If we have an ls option which is a filter, apply it */
65
if (!str_isempty(p_filter_str))
67
- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str))
68
+ unsigned int iters = 0;
69
+ if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str,
77
vsf_filename_passes_filter(const struct mystr* p_filename_str,
78
- const struct mystr* p_filter_str)
79
+ const struct mystr* p_filter_str,
80
+ unsigned int* iters)
82
/* A simple routine to match a filename against a pattern.
83
* This routine is used instead of e.g. fnmatch(3), because we should be
85
str_copy(&filter_remain_str, p_filter_str);
86
str_copy(&name_remain_str, p_filename_str);
88
- while (!str_isempty(&filter_remain_str))
89
+ while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
91
static struct mystr s_match_needed_str;
92
/* Locate next special token */
93
struct str_locate_result locate_result =
94
str_locate_chars(&filter_remain_str, "*?{");
96
/* Isolate text leading up to token (if any) - needs to be matched */
97
if (locate_result.found)
101
str_copy(&new_filter_str, &brace_list_str);
102
str_append_str(&new_filter_str, &filter_remain_str);
103
- if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str))
104
+ if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str,
113
+ if (*iters == VSFTP_MATCHITERS_MAX) {
117
str_free(&filter_remain_str);
118
str_free(&name_remain_str);
119
diff -Nur vsftpd-2.2.0/ls.h vsftpd-2.2.0.new/ls.h
120
--- vsftpd-2.2.0/ls.h 2008-02-01 20:30:41.000000000 -0500
121
+++ vsftpd-2.2.0.new/ls.h 2011-03-25 14:52:17.963109891 -0400
124
* p_filename_str - the filename to match
125
* p_filter_str - the filter to match against
126
+ * iters - pointer to a zero-seeded int which prevents the match
127
+ * loop from running an excessive number of times
129
* Returns 1 if there is a match, 0 otherwise.
131
int vsf_filename_passes_filter(const struct mystr* p_filename_str,
132
- const struct mystr* p_filter_str);
133
+ const struct mystr* p_filter_str,
134
+ unsigned int* iters);
136
#endif /* VSF_LS_H */