From c67fd3688c30ec6ba5fc22694607f3ce5c7aa9e95bb6ed7dc6089f26e04ff8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Mon, 23 Mar 2015 19:57:06 +0000 Subject: [PATCH 1/9] - Work on the filter patch and split out the normalisation of the path to separate str function, currently commented out so I avoid huge diffing. * vsftpd-2.1.0-filter.patch OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=74 --- vsftpd-2.1.0-filter.patch | 130 ++++++++++++++++++++++++++------------ vsftpd.changes | 8 +++ 2 files changed, 97 insertions(+), 41 deletions(-) diff --git a/vsftpd-2.1.0-filter.patch b/vsftpd-2.1.0-filter.patch index c9d622e..8a19045 100644 --- a/vsftpd-2.1.0-filter.patch +++ b/vsftpd-2.1.0-filter.patch @@ -2,73 +2,75 @@ Index: vsftpd-3.0.2/ls.c =================================================================== --- vsftpd-3.0.2.orig/ls.c +++ vsftpd-3.0.2/ls.c -@@ -7,6 +7,7 @@ - * Would you believe, code to handle directory listing. - */ - -+#include - #include "ls.h" - #include "access.h" - #include "defs.h" -@@ -243,11 +244,42 @@ vsf_filename_passes_filter(const struct - struct mystr temp_str = INIT_MYSTR; - struct mystr brace_list_str = INIT_MYSTR; - struct mystr new_filter_str = INIT_MYSTR; -+ struct mystr normalize_filename_str = INIT_MYSTR; -+ const char *normname; -+ const char *path; +@@ -121,7 +121,10 @@ vsf_ls_populate_dir_list(struct mystr_li + if (!str_isempty(p_filter_str)) + { + unsigned int iters = 0; +- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str, ++ static struct mystr normalize_filename_str; ++ str_copy(&normalize_filename_str, &s_next_filename_str); ++ //str_normalize_filepath(&normalize_filename_str); ++ if (!vsf_filename_passes_filter(&normalize_filename_str, p_filter_str, + &iters)) + { + continue; +@@ -246,8 +249,30 @@ vsf_filename_passes_filter(const struct int ret = 0; char last_token = 0; int must_match_at_current_pos = 1; ++ + str_copy(&filter_remain_str, p_filter_str); - str_copy(&name_remain_str, p_filename_str); + -+ /* normalize filepath */ -+ path = str_strdup(p_filename_str); -+ normname = realpath(path, NULL); -+ if (normname == NULL) -+ goto out; -+ str_alloc_text(&normalize_filename_str, normname); -+ -+ if (!str_isempty (&filter_remain_str) && !str_isempty(&normalize_filename_str)) { ++ if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { + if (str_get_char_at(p_filter_str, 0) == '/') { -+ if (str_get_char_at(&normalize_filename_str, 0) != '/') { ++ if (str_get_char_at(p_filename_str, 0) != '/') { + str_getcwd (&name_remain_str); + + if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */ + str_append_char (&name_remain_str, '/'); + -+ str_append_str (&name_remain_str, &normalize_filename_str); ++ str_append_str (&name_remain_str, p_filename_str); + } + else -+ str_copy (&name_remain_str, &normalize_filename_str); ++ str_copy (&name_remain_str, p_filename_str); + } else { + if (str_get_char_at(p_filter_str, 0) != '{') -+ str_basename (&name_remain_str, &normalize_filename_str); ++ str_basename (&name_remain_str, p_filename_str); + else -+ str_copy (&name_remain_str, &normalize_filename_str); ++ str_copy (&name_remain_str, p_filename_str); + } + } else -+ str_copy(&name_remain_str, &normalize_filename_str); ++ str_copy(&name_remain_str, p_filename_str); while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) { -@@ -360,6 +392,9 @@ vsf_filename_passes_filter(const struct - ret = 0; - } - out: -+ free(normname); -+ free(path); -+ str_free(&normalize_filename_str); - str_free(&filter_remain_str); - str_free(&name_remain_str); - str_free(&temp_str); Index: vsftpd-3.0.2/str.c =================================================================== --- vsftpd-3.0.2.orig/str.c +++ vsftpd-3.0.2/str.c -@@ -770,3 +770,14 @@ str_replace_unprintable(struct mystr* p_ +@@ -15,6 +15,10 @@ + #define PRIVATE_HANDS_OFF_len len + #define PRIVATE_HANDS_OFF_alloc_bytes alloc_bytes + #include "str.h" ++#include ++#include ++#include ++#include + + /* Ick. Its for die() */ + #include "utility.h" +@@ -479,7 +483,7 @@ str_split_text_common(struct mystr* p_sr + if (indexx + search_len > p_src->len) + { + bug("indexx invalid in str_split_text"); +- } ++ } + /* Build rhs */ + private_str_alloc_memchunk(p_rhs, p_src->p_buf + indexx + search_len, + p_src->len - indexx - search_len); +@@ -770,3 +774,59 @@ str_replace_unprintable(struct mystr* p_ } } @@ -83,15 +85,61 @@ Index: vsftpd-3.0.2/str.c + if (str_isempty(d_str)) + str_copy (d_str, path); +} ++ ++void ++str_normalize_filepath(struct mystr* filepath) ++{ ++ char *path; ++ char *normdir; ++ char *dir; ++ char *filename; ++ static struct mystr tmp; ++ ++ /* normalize filepath */ ++ path = str_strdup(filepath); ++ char *ch1 = strdup(path); ++ char *ch2 = strdup(path); ++ /* we split dir/file as realpath /home/REGEXP is NULL so we need dir ++ * dir only to function correctly, later on we need to glue back the ++ * file if there is some ++ */ ++ dir = dirname(ch1); ++ filename = basename(ch2); ++ normdir = realpath(dir, NULL); ++ if (normdir == NULL) ++ { ++ goto out; ++ } ++ str_alloc_text(&tmp, normdir); ++ /* / is special it ends in both dirname and basename so ignore it here */ ++ unsigned int len = str_getlen(&tmp); ++ if (str_get_char_at(&tmp, len - 1) != '/') ++ { ++ str_append_char(&tmp, '/'); ++ } ++ /* / is special it ends in both dirname and basename so ignore it here */ ++ if (strcmp(filename, "/") != 0) ++ { ++ str_append_text(&tmp, filename); ++ } ++ str_copy(filepath, &tmp); ++out: ++ free(normdir); ++ free(path); ++ free(ch1); ++ free(ch2); ++ str_free(&tmp); ++} Index: vsftpd-3.0.2/str.h =================================================================== --- vsftpd-3.0.2.orig/str.h +++ vsftpd-3.0.2/str.h -@@ -101,6 +101,7 @@ void str_replace_unprintable(struct myst +@@ -101,6 +101,8 @@ void str_replace_unprintable(struct myst int str_atoi(const struct mystr* p_str); filesize_t str_a_to_filesize_t(const struct mystr* p_str); unsigned int str_octal_to_uint(const struct mystr* p_str); +void str_basename (struct mystr* d_str, const struct mystr* path); ++void str_normalize_filepath(struct mystr* filepath); /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string * buffer, starting at character position 'p_pos'. The extracted line will diff --git a/vsftpd.changes b/vsftpd.changes index a644eb4..9c0a468 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Mon Mar 23 19:56:11 UTC 2015 - tchvatal@suse.com + +- Work on the filter patch and split out the normalisation of the + path to separate str function, currently commented out so I + avoid huge diffing. + * vsftpd-2.1.0-filter.patch + ------------------------------------------------------------------- Fri Feb 20 12:13:42 UTC 2015 - tchvatal@suse.com From 8c317ca7360e26d9462c82b9c64da8c942027ed6a3ea097f7971b335dcf73ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Mon, 23 Mar 2015 20:10:51 +0000 Subject: [PATCH 2/9] - Reset filter patch to match fedora, my work will be restarted in one-off patch to make the changes stand out. Add rest of RH filtering patches: * vsftpd-2.2.0-wildchar.patch * vsftpd-2.3.4-sqb.patch * vsftpd-2.1.0-filter.patch OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=75 --- vsftpd-2.1.0-filter.patch | 119 +++------------- vsftpd-2.2.0-wildchar.patch | 24 ++++ vsftpd-2.3.4-sqb.patch | 265 ++++++++++++++++++++++++++++++++++++ vsftpd.changes | 10 ++ vsftpd.spec | 4 + 5 files changed, 323 insertions(+), 99 deletions(-) create mode 100644 vsftpd-2.2.0-wildchar.patch create mode 100644 vsftpd-2.3.4-sqb.patch diff --git a/vsftpd-2.1.0-filter.patch b/vsftpd-2.1.0-filter.patch index 8a19045..c9737b0 100644 --- a/vsftpd-2.1.0-filter.patch +++ b/vsftpd-2.1.0-filter.patch @@ -1,36 +1,24 @@ -Index: vsftpd-3.0.2/ls.c -=================================================================== ---- vsftpd-3.0.2.orig/ls.c -+++ vsftpd-3.0.2/ls.c -@@ -121,7 +121,10 @@ vsf_ls_populate_dir_list(struct mystr_li - if (!str_isempty(p_filter_str)) - { - unsigned int iters = 0; -- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str, -+ static struct mystr normalize_filename_str; -+ str_copy(&normalize_filename_str, &s_next_filename_str); -+ //str_normalize_filepath(&normalize_filename_str); -+ if (!vsf_filename_passes_filter(&normalize_filename_str, p_filter_str, - &iters)) - { - continue; -@@ -246,8 +249,30 @@ vsf_filename_passes_filter(const struct +diff -up vsftpd-2.1.0/ls.c.filter vsftpd-2.1.0/ls.c +--- vsftpd-2.1.0/ls.c.filter 2008-02-02 02:30:41.000000000 +0100 ++++ vsftpd-2.1.0/ls.c 2009-01-08 19:31:15.000000000 +0100 +@@ -239,9 +239,31 @@ vsf_filename_passes_filter(const struct int ret = 0; char last_token = 0; int must_match_at_current_pos = 1; -+ -+ ++ ++ str_copy(&filter_remain_str, p_filter_str); - str_copy(&name_remain_str, p_filename_str); -+ +- ++ + if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { + if (str_get_char_at(p_filter_str, 0) == '/') { + if (str_get_char_at(p_filename_str, 0) != '/') { + str_getcwd (&name_remain_str); -+ ++ + if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */ + str_append_char (&name_remain_str, '/'); -+ ++ + str_append_str (&name_remain_str, p_filename_str); + } + else @@ -43,34 +31,14 @@ Index: vsftpd-3.0.2/ls.c + } + } else + str_copy(&name_remain_str, p_filename_str); - ++ while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) { -Index: vsftpd-3.0.2/str.c -=================================================================== ---- vsftpd-3.0.2.orig/str.c -+++ vsftpd-3.0.2/str.c -@@ -15,6 +15,10 @@ - #define PRIVATE_HANDS_OFF_len len - #define PRIVATE_HANDS_OFF_alloc_bytes alloc_bytes - #include "str.h" -+#include -+#include -+#include -+#include - - /* Ick. Its for die() */ - #include "utility.h" -@@ -479,7 +483,7 @@ str_split_text_common(struct mystr* p_sr - if (indexx + search_len > p_src->len) - { - bug("indexx invalid in str_split_text"); -- } -+ } - /* Build rhs */ - private_str_alloc_memchunk(p_rhs, p_src->p_buf + indexx + search_len, - p_src->len - indexx - search_len); -@@ -770,3 +774,59 @@ str_replace_unprintable(struct mystr* p_ + static struct mystr s_match_needed_str; +diff -up vsftpd-2.1.0/str.c.filter vsftpd-2.1.0/str.c +--- vsftpd-2.1.0/str.c.filter 2008-12-17 06:54:16.000000000 +0100 ++++ vsftpd-2.1.0/str.c 2009-01-08 19:31:15.000000000 +0100 +@@ -680,3 +680,14 @@ str_replace_unprintable(struct mystr* p_ } } @@ -85,61 +53,14 @@ Index: vsftpd-3.0.2/str.c + if (str_isempty(d_str)) + str_copy (d_str, path); +} -+ -+void -+str_normalize_filepath(struct mystr* filepath) -+{ -+ char *path; -+ char *normdir; -+ char *dir; -+ char *filename; -+ static struct mystr tmp; -+ -+ /* normalize filepath */ -+ path = str_strdup(filepath); -+ char *ch1 = strdup(path); -+ char *ch2 = strdup(path); -+ /* we split dir/file as realpath /home/REGEXP is NULL so we need dir -+ * dir only to function correctly, later on we need to glue back the -+ * file if there is some -+ */ -+ dir = dirname(ch1); -+ filename = basename(ch2); -+ normdir = realpath(dir, NULL); -+ if (normdir == NULL) -+ { -+ goto out; -+ } -+ str_alloc_text(&tmp, normdir); -+ /* / is special it ends in both dirname and basename so ignore it here */ -+ unsigned int len = str_getlen(&tmp); -+ if (str_get_char_at(&tmp, len - 1) != '/') -+ { -+ str_append_char(&tmp, '/'); -+ } -+ /* / is special it ends in both dirname and basename so ignore it here */ -+ if (strcmp(filename, "/") != 0) -+ { -+ str_append_text(&tmp, filename); -+ } -+ str_copy(filepath, &tmp); -+out: -+ free(normdir); -+ free(path); -+ free(ch1); -+ free(ch2); -+ str_free(&tmp); -+} -Index: vsftpd-3.0.2/str.h -=================================================================== ---- vsftpd-3.0.2.orig/str.h -+++ vsftpd-3.0.2/str.h -@@ -101,6 +101,8 @@ void str_replace_unprintable(struct myst +diff -up vsftpd-2.1.0/str.h.filter vsftpd-2.1.0/str.h +--- vsftpd-2.1.0/str.h.filter 2008-12-17 06:53:23.000000000 +0100 ++++ vsftpd-2.1.0/str.h 2009-01-08 19:32:14.000000000 +0100 +@@ -100,6 +100,7 @@ void str_replace_unprintable(struct myst int str_atoi(const struct mystr* p_str); filesize_t str_a_to_filesize_t(const struct mystr* p_str); unsigned int str_octal_to_uint(const struct mystr* p_str); +void str_basename (struct mystr* d_str, const struct mystr* path); -+void str_normalize_filepath(struct mystr* filepath); /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string * buffer, starting at character position 'p_pos'. The extracted line will diff --git a/vsftpd-2.2.0-wildchar.patch b/vsftpd-2.2.0-wildchar.patch new file mode 100644 index 0000000..5e4028c --- /dev/null +++ b/vsftpd-2.2.0-wildchar.patch @@ -0,0 +1,24 @@ +diff -up vsftpd-2.3.2/ls.c.tmp vsftpd-2.3.2/ls.c +--- vsftpd-2.3.2/ls.c.tmp 2010-08-20 13:18:54.397583558 +0200 ++++ vsftpd-2.3.2/ls.c 2010-08-20 13:14:59.047831385 +0200 +@@ -305,6 +305,20 @@ vsf_filename_passes_filter(const struct + { + goto out; + } ++ if (!must_match_at_current_pos && last_token == 0) ++ { ++ struct mystr last_str = INIT_MYSTR; ++ str_mid_to_end(&name_remain_str, &last_str, ++ str_getlen(&name_remain_str) - str_getlen(&s_match_needed_str)); ++ locate_result = str_locate_str(&last_str, &s_match_needed_str); ++ str_free(&last_str); ++ ++ if (locate_result.found) ++ { ++ ret = 1; ++ } ++ goto out; ++ } + /* Chop matched string out of remainder */ + str_mid_to_end(&name_remain_str, &temp_str, + indexx + str_getlen(&s_match_needed_str)); diff --git a/vsftpd-2.3.4-sqb.patch b/vsftpd-2.3.4-sqb.patch new file mode 100644 index 0000000..0ad9088 --- /dev/null +++ b/vsftpd-2.3.4-sqb.patch @@ -0,0 +1,265 @@ +diff -up vsftpd-3.0.2/ls.c.sqb vsftpd-3.0.2/ls.c +--- vsftpd-3.0.2/ls.c.sqb 2014-07-04 09:55:57.899506894 +0200 ++++ vsftpd-3.0.2/ls.c 2014-07-04 09:58:02.187569017 +0200 +@@ -246,7 +246,7 @@ vsf_filename_passes_filter(const struct + int ret = 0; + char last_token = 0; + int must_match_at_current_pos = 1; +- ++ int matched = 0; + + str_copy(&filter_remain_str, p_filter_str); + +@@ -276,7 +276,7 @@ vsf_filename_passes_filter(const struct + static struct mystr s_match_needed_str; + /* Locate next special token */ + struct str_locate_result locate_result = +- str_locate_chars(&filter_remain_str, "*?{"); ++ str_locate_chars(&filter_remain_str, "*?{["); + (*iters)++; + /* Isolate text leading up to token (if any) - needs to be matched */ + if (locate_result.found) +@@ -294,94 +294,172 @@ vsf_filename_passes_filter(const struct + str_empty(&filter_remain_str); + last_token = 0; + } +- if (!str_isempty(&s_match_needed_str)) +- { +- /* Need to match something.. could be a match which has to start at +- * current position, or we could allow it to start anywhere +- */ +- unsigned int indexx; +- locate_result = str_locate_str(&name_remain_str, &s_match_needed_str); +- if (!locate_result.found) ++ ++ matched = 0; ++ do { ++ if (!str_isempty(&s_match_needed_str)) + { +- /* Fail */ +- goto out; ++ if (!matched) ++ { ++ matched = 1; ++ } ++ /* Need to match something.. could be a match which has to start at ++ * current position, or we could allow it to start anywhere ++ */ ++ unsigned int indexx; ++ locate_result = str_locate_str(&name_remain_str, &s_match_needed_str); ++ if (!locate_result.found) ++ { ++ /* Fail */ ++ goto out; ++ } ++ indexx = locate_result.index; ++ if (must_match_at_current_pos && indexx > 0) ++ { ++ goto out; ++ } ++ if (!must_match_at_current_pos && last_token == 0) ++ { ++ struct mystr last_str = INIT_MYSTR; ++ str_mid_to_end(&name_remain_str, &last_str, ++ str_getlen(&name_remain_str) - str_getlen(&s_match_needed_str)); ++ locate_result = str_locate_str(&last_str, &s_match_needed_str); ++ str_free(&last_str); ++ ++ if (locate_result.found) ++ { ++ ret = 1; ++ } ++ goto out; ++ } ++ /* Chop matched string out of remainder */ ++ str_mid_to_end(&name_remain_str, &temp_str, ++ indexx + str_getlen(&s_match_needed_str)); ++ str_copy(&name_remain_str, &temp_str); + } +- indexx = locate_result.index; +- if (must_match_at_current_pos && indexx > 0) ++ if (last_token == '?') + { +- goto out; ++ if (str_isempty(&name_remain_str)) ++ { ++ goto out; ++ } ++ str_right(&name_remain_str, &temp_str, str_getlen(&name_remain_str) - 1); ++ str_copy(&name_remain_str, &temp_str); ++ must_match_at_current_pos = 1; + } +- if (!must_match_at_current_pos && last_token == 0) ++ else if (last_token == '{') + { +- struct mystr last_str = INIT_MYSTR; +- str_mid_to_end(&name_remain_str, &last_str, +- str_getlen(&name_remain_str) - str_getlen(&s_match_needed_str)); +- locate_result = str_locate_str(&last_str, &s_match_needed_str); +- str_free(&last_str); ++ struct str_locate_result end_brace = ++ str_locate_char(&filter_remain_str, '}'); ++ must_match_at_current_pos = 1; ++ if (end_brace.found) ++ { ++ int entire = (*iters == 1 && last_token == '{'); + +- if (locate_result.found) ++ str_split_char(&filter_remain_str, &temp_str, '}'); ++ str_copy(&brace_list_str, &filter_remain_str); ++ str_copy(&filter_remain_str, &temp_str); ++ str_split_char(&brace_list_str, &temp_str, ','); ++ while (!str_isempty(&brace_list_str)) ++ { ++ str_empty(&new_filter_str); ++ if (!matched && !entire) ++ { ++ str_append_char(&new_filter_str, '*'); ++ } ++ str_append_str(&new_filter_str, &brace_list_str); ++ str_append_str(&new_filter_str, &filter_remain_str); ++ if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str, ++ iters)) ++ { ++ ret = 1; ++ goto out; ++ } ++ str_copy(&brace_list_str, &temp_str); ++ str_split_char(&brace_list_str, &temp_str, ','); ++ } ++ goto out; ++ } ++ else if (str_isempty(&name_remain_str) || ++ str_get_char_at(&name_remain_str, 0) != '{') + { +- ret = 1; ++ goto out; ++ } ++ else ++ { ++ str_right(&name_remain_str, &temp_str, ++ str_getlen(&name_remain_str) - 1); ++ str_copy(&name_remain_str, &temp_str); + } +- goto out; +- } +- /* Chop matched string out of remainder */ +- str_mid_to_end(&name_remain_str, &temp_str, +- indexx + str_getlen(&s_match_needed_str)); +- str_copy(&name_remain_str, &temp_str); +- } +- if (last_token == '?') +- { +- if (str_isempty(&name_remain_str)) +- { +- goto out; + } +- str_right(&name_remain_str, &temp_str, str_getlen(&name_remain_str) - 1); +- str_copy(&name_remain_str, &temp_str); +- must_match_at_current_pos = 1; +- } +- else if (last_token == '{') +- { +- struct str_locate_result end_brace = +- str_locate_char(&filter_remain_str, '}'); +- must_match_at_current_pos = 1; +- if (end_brace.found) ++ else if (last_token == '[') + { +- str_split_char(&filter_remain_str, &temp_str, '}'); +- str_copy(&brace_list_str, &filter_remain_str); +- str_copy(&filter_remain_str, &temp_str); +- str_split_char(&brace_list_str, &temp_str, ','); +- while (!str_isempty(&brace_list_str)) +- { +- str_copy(&new_filter_str, &brace_list_str); +- str_append_str(&new_filter_str, &filter_remain_str); +- if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str, +- iters)) ++ struct str_locate_result end_sqb = ++ str_locate_char(&filter_remain_str, ']'); ++ must_match_at_current_pos = 1; ++ if (end_sqb.found) ++ { ++ unsigned int cur_pos; ++ char stch, ench; ++ const char *p_brace; ++ ++ str_split_char(&filter_remain_str, &temp_str, ']'); ++ str_copy(&brace_list_str, &filter_remain_str); ++ str_copy(&filter_remain_str, &temp_str); ++ p_brace = str_getbuf(&brace_list_str); ++ for (cur_pos = 0; cur_pos < str_getlen(&brace_list_str);) + { +- ret = 1; +- goto out; ++ stch = p_brace[cur_pos]; ++ // char vers. range ++ if (cur_pos + 2 < str_getlen(&brace_list_str) && ++ p_brace[cur_pos+1] == '-') ++ { ++ ench = p_brace[cur_pos+2]; ++ cur_pos += 3; ++ } ++ else ++ { ++ ench = stch; ++ cur_pos++; ++ } ++ // expand char[s] ++ for (;stch <= ench && !str_isempty(&brace_list_str); stch++) ++ { ++ str_empty(&new_filter_str); ++ if (!matched) ++ { ++ str_append_char(&new_filter_str, '*'); ++ } ++ str_append_char(&new_filter_str, stch); ++ str_append_str(&new_filter_str, &filter_remain_str); ++ if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str, ++ iters)) ++ { ++ ret = 1; ++ goto out; ++ } ++ } + } +- str_copy(&brace_list_str, &temp_str); +- str_split_char(&brace_list_str, &temp_str, ','); ++ goto out; ++ } ++ else if (str_isempty(&name_remain_str) || ++ str_get_char_at(&name_remain_str, 0) != '[') ++ { ++ goto out; ++ } ++ else ++ { ++ str_right(&name_remain_str, &temp_str, ++ str_getlen(&name_remain_str) - 1); ++ str_copy(&name_remain_str, &temp_str); + } +- goto out; +- } +- else if (str_isempty(&name_remain_str) || +- str_get_char_at(&name_remain_str, 0) != '{') +- { +- goto out; + } + else + { +- str_right(&name_remain_str, &temp_str, +- str_getlen(&name_remain_str) - 1); +- str_copy(&name_remain_str, &temp_str); ++ must_match_at_current_pos = 0; + } +- } +- else +- { +- must_match_at_current_pos = 0; +- } ++ } while (locate_result.found && ++ str_getlen(&name_remain_str) > 0 && last_token != '*'); + } + /* Any incoming string left means no match unless we ended on the correct + * type of wildcard. diff --git a/vsftpd.changes b/vsftpd.changes index 9c0a468..5d6dcaa 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Mon Mar 23 20:08:19 UTC 2015 - tchvatal@suse.com + +- Reset filter patch to match fedora, my work will be restarted + in one-off patch to make the changes stand out. Add rest of + RH filtering patches: + * vsftpd-2.2.0-wildchar.patch + * vsftpd-2.3.4-sqb.patch + * vsftpd-2.1.0-filter.patch + ------------------------------------------------------------------- Mon Mar 23 19:56:11 UTC 2015 - tchvatal@suse.com diff --git a/vsftpd.spec b/vsftpd.spec index 9c6f80a..d73975e 100644 --- a/vsftpd.spec +++ b/vsftpd.spec @@ -60,6 +60,8 @@ Patch17: vsftpd-enable-gettimeofday-sec.patch Patch18: vsftpd-3.0.2-s390.patch #PATCH-FIX-UPSTREAM: bnc#900326 deny_file filtering acts weirdly Patch19: vsftpd-2.1.0-filter.patch +Patch20: vsftpd-2.2.0-wildchar.patch +Patch21: vsftpd-2.3.4-sqb.patch BuildRequires: libcap-devel BuildRequires: openssl-devel BuildRequires: pam-devel @@ -101,6 +103,8 @@ tests. %patch17 -p1 %patch18 -p1 %patch19 -p1 +%patch20 -p1 +%patch21 -p1 %build %define seccomp_opts -D_GNU_SOURCE -DUSE_SECCOMP From fa040448aa002a5d5b12a1c6cb3084193dced45c06d19d8d019c564a261fa9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Mon, 23 Mar 2015 20:22:32 +0000 Subject: [PATCH 3/9] - Add back patch attempting to fix bnc#900326 bnc#915522 and bnc#922538: * vsftpd-path-normalize.patch OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=76 --- vsftpd-path-normalize.patch | 93 +++++++++++++++++++++++++++++++++++++ vsftpd.changes | 7 +++ vsftpd.spec | 4 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 vsftpd-path-normalize.patch diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch new file mode 100644 index 0000000..855d66c --- /dev/null +++ b/vsftpd-path-normalize.patch @@ -0,0 +1,93 @@ +Index: vsftpd-3.0.2/ls.c +=================================================================== +--- vsftpd-3.0.2.orig/ls.c ++++ vsftpd-3.0.2/ls.c +@@ -121,7 +121,10 @@ vsf_ls_populate_dir_list(struct mystr_li + if (!str_isempty(p_filter_str)) + { + unsigned int iters = 0; +- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str, ++ struct mystr normalize_filename_str; ++ str_copy(&normalize_filename_str, &s_next_filename_str); ++ str_normalize_filepath(&normalize_filename_str); ++ if (!vsf_filename_passes_filter(&normalize_filename_str, p_filter_str, + &iters)) + { + continue; +Index: vsftpd-3.0.2/str.c +=================================================================== +--- vsftpd-3.0.2.orig/str.c ++++ vsftpd-3.0.2/str.c +@@ -16,6 +16,12 @@ + #define PRIVATE_HANDS_OFF_alloc_bytes alloc_bytes + #include "str.h" + ++/* normalize filepath */ ++#include ++#include ++#include ++#include ++ + /* Ick. Its for die() */ + #include "utility.h" + #include "sysutil.h" +@@ -781,3 +787,47 @@ str_basename (struct mystr* d_str, const + if (str_isempty(d_str)) + str_copy (d_str, path); + } ++ ++void ++str_normalize_filepath(struct mystr* filepath) ++{ ++ char *path; ++ char *normdir; ++ char *dir; ++ char *filename; ++ static struct mystr tmp; ++ ++ /* normalize filepath */ ++ path = str_strdup(filepath); ++ char *ch1 = strdup(path); ++ char *ch2 = strdup(path); ++ /* we split dir/file as realpath /home/REGEXP is NULL so we need dir ++ * dir only to function correctly, later on we need to glue back the ++ * file if there is some ++ */ ++ dir = dirname(ch1); ++ filename = basename(ch2); ++ normdir = realpath(dir, NULL); ++ if (normdir == NULL) ++ { ++ goto out; ++ } ++ str_alloc_text(&tmp, normdir); ++ unsigned int len = str_getlen(&tmp); ++ if (str_get_char_at(&tmp, len - 1) != '/') ++ { ++ str_append_char(&tmp, '/'); ++ } ++ /* / is special it ends in both dirname and basename so ignore it here */ ++ if (strcmp(filename, "/") != 0) ++ { ++ str_append_text(&tmp, filename); ++ } ++ str_copy(filepath, &tmp); ++out: ++ free(normdir); ++ free(path); ++ free(ch1); ++ free(ch2); ++ str_free(&tmp); ++} +Index: vsftpd-3.0.2/str.h +=================================================================== +--- vsftpd-3.0.2.orig/str.h ++++ vsftpd-3.0.2/str.h +@@ -102,6 +102,7 @@ int str_atoi(const struct mystr* p_str); + filesize_t str_a_to_filesize_t(const struct mystr* p_str); + unsigned int str_octal_to_uint(const struct mystr* p_str); + void str_basename (struct mystr* d_str, const struct mystr* path); ++void str_normalize_filepath(struct mystr* filepath); + + /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string + * buffer, starting at character position 'p_pos'. The extracted line will diff --git a/vsftpd.changes b/vsftpd.changes index 5d6dcaa..d9bb242 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Mon Mar 23 20:13:51 UTC 2015 - tchvatal@suse.com + +- Add back patch attempting to fix bnc#900326 bnc#915522 and + bnc#922538: + * vsftpd-path-normalize.patch + ------------------------------------------------------------------- Mon Mar 23 20:08:19 UTC 2015 - tchvatal@suse.com diff --git a/vsftpd.spec b/vsftpd.spec index d73975e..8114bee 100644 --- a/vsftpd.spec +++ b/vsftpd.spec @@ -58,10 +58,11 @@ Patch16: vsftpd-root-squashed-chroot.patch Patch17: vsftpd-enable-gettimeofday-sec.patch #PATCH-FIX-UPSTREAM: bnc#890469 fix broken syscall on s390 Patch18: vsftpd-3.0.2-s390.patch -#PATCH-FIX-UPSTREAM: bnc#900326 deny_file filtering acts weirdly +#PATCH-FIX-UPSTREAM: bnc#900326 deny_file filtering acts weirdly (19-22) Patch19: vsftpd-2.1.0-filter.patch Patch20: vsftpd-2.2.0-wildchar.patch Patch21: vsftpd-2.3.4-sqb.patch +Patch22: vsftpd-path-normalize.patch BuildRequires: libcap-devel BuildRequires: openssl-devel BuildRequires: pam-devel @@ -105,6 +106,7 @@ tests. %patch19 -p1 %patch20 -p1 %patch21 -p1 +%patch22 -p1 %build %define seccomp_opts -D_GNU_SOURCE -DUSE_SECCOMP From 915fc9626d7855b7353d5da43d6770d086e19acbe8e51c73dab43f0fe69843e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Mon, 23 Mar 2015 20:59:56 +0000 Subject: [PATCH 4/9] OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=77 --- vsftpd-path-normalize.patch | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 855d66c..776b400 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -2,18 +2,15 @@ Index: vsftpd-3.0.2/ls.c =================================================================== --- vsftpd-3.0.2.orig/ls.c +++ vsftpd-3.0.2/ls.c -@@ -121,7 +121,10 @@ vsf_ls_populate_dir_list(struct mystr_li - if (!str_isempty(p_filter_str)) - { - unsigned int iters = 0; -- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str, -+ struct mystr normalize_filename_str; -+ str_copy(&normalize_filename_str, &s_next_filename_str); -+ str_normalize_filepath(&normalize_filename_str); -+ if (!vsf_filename_passes_filter(&normalize_filename_str, p_filter_str, - &iters)) - { - continue; +@@ -270,6 +270,8 @@ vsf_filename_passes_filter(const struct + } + } else + str_copy(&name_remain_str, p_filename_str); ++ ++ str_normalize_filepath(&name_remain_str); + + while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) + { Index: vsftpd-3.0.2/str.c =================================================================== --- vsftpd-3.0.2.orig/str.c From 6cd1b030f08cce210acb14bda936eba5cdf4a1e2e511459d77bd8addfaa4603e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Wed, 25 Mar 2015 08:45:22 +0000 Subject: [PATCH 5/9] OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=78 --- vsftpd-path-normalize.patch | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 776b400..20e4ceb 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -28,7 +28,7 @@ Index: vsftpd-3.0.2/str.c /* Ick. Its for die() */ #include "utility.h" #include "sysutil.h" -@@ -781,3 +787,47 @@ str_basename (struct mystr* d_str, const +@@ -781,3 +787,52 @@ str_basename (struct mystr* d_str, const if (str_isempty(d_str)) str_copy (d_str, path); } @@ -68,6 +68,11 @@ Index: vsftpd-3.0.2/str.c + { + str_append_text(&tmp, filename); + } ++ /* TODO: here we should run one more stat to determine if the whole thing ++ * is a directory and append trailing / (ie. /home -> /home/). ++ * This will make the deny_file=/home/ work contrary to currently ++ * needed /home. ++ */ + str_copy(filepath, &tmp); +out: + free(normdir); From ef6c0131cbc1ed1ba4250a60651fde91644104e2f56f5d47f54244cf65845a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Wed, 25 Mar 2015 10:08:56 +0000 Subject: [PATCH 6/9] - Update patch bit more for sanity checks. Done by rsassu@suse.de: * vsftpd-path-normalize.patch OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=79 --- vsftpd-path-normalize.patch | 14 +++++++++++--- vsftpd.changes | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 20e4ceb..93363bf 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -28,7 +28,7 @@ Index: vsftpd-3.0.2/str.c /* Ick. Its for die() */ #include "utility.h" #include "sysutil.h" -@@ -781,3 +787,52 @@ str_basename (struct mystr* d_str, const +@@ -781,3 +787,60 @@ str_basename (struct mystr* d_str, const if (str_isempty(d_str)) str_copy (d_str, path); } @@ -44,8 +44,16 @@ Index: vsftpd-3.0.2/str.c + + /* normalize filepath */ + path = str_strdup(filepath); ++ if (path == NULL) ++ { ++ return; ++ } + char *ch1 = strdup(path); + char *ch2 = strdup(path); ++ if (ch1 == NULL || ch2 == NULL) ++ { ++ goto out; ++ } + /* we split dir/file as realpath /home/REGEXP is NULL so we need dir + * dir only to function correctly, later on we need to glue back the + * file if there is some @@ -74,12 +82,12 @@ Index: vsftpd-3.0.2/str.c + * needed /home. + */ + str_copy(filepath, &tmp); -+out: + free(normdir); ++ str_free(&tmp); ++out: + free(path); + free(ch1); + free(ch2); -+ str_free(&tmp); +} Index: vsftpd-3.0.2/str.h =================================================================== diff --git a/vsftpd.changes b/vsftpd.changes index d9bb242..6c25055 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Mar 25 10:08:03 UTC 2015 - tchvatal@suse.com + +- Update patch bit more for sanity checks. Done by rsassu@suse.de: + * vsftpd-path-normalize.patch + ------------------------------------------------------------------- Mon Mar 23 20:13:51 UTC 2015 - tchvatal@suse.com From abd20973e820a457115fff9700f40458aeffc898b4d6bd7ab71d66c09fe3df41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Sun, 5 Apr 2015 10:34:03 +0000 Subject: [PATCH 7/9] - bnc#925963 stat is sometimes run on wrong path and results with ENOENT: * vsftpd-path-normalize.patch OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=80 --- vsftpd-path-normalize.patch | 15 +++++++-------- vsftpd.changes | 7 +++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 93363bf..12d8120 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -2,15 +2,14 @@ Index: vsftpd-3.0.2/ls.c =================================================================== --- vsftpd-3.0.2.orig/ls.c +++ vsftpd-3.0.2/ls.c -@@ -270,6 +270,8 @@ vsf_filename_passes_filter(const struct - } - } else - str_copy(&name_remain_str, p_filename_str); -+ -+ str_normalize_filepath(&name_remain_str); +@@ -249,6 +249,7 @@ vsf_filename_passes_filter(const struct + int matched = 0; - while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) - { + str_copy(&filter_remain_str, p_filter_str); ++ str_normalize_filepath(p_filter_str); + + if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { + if (str_get_char_at(p_filter_str, 0) == '/') { Index: vsftpd-3.0.2/str.c =================================================================== --- vsftpd-3.0.2.orig/str.c diff --git a/vsftpd.changes b/vsftpd.changes index 6c25055..9f58213 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Sun Apr 5 10:25:50 UTC 2015 - tchvatal@suse.com + +- bnc#925963 stat is sometimes run on wrong path and results with + ENOENT: + * vsftpd-path-normalize.patch + ------------------------------------------------------------------- Wed Mar 25 10:08:03 UTC 2015 - tchvatal@suse.com From e939f108e5f88c9f768f642f28987dcd0d98287c74d3541b9f2d6608b642514b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Sun, 5 Apr 2015 10:35:19 +0000 Subject: [PATCH 8/9] OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=81 --- vsftpd-path-normalize.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 12d8120..6482cdf 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -6,7 +6,7 @@ Index: vsftpd-3.0.2/ls.c int matched = 0; str_copy(&filter_remain_str, p_filter_str); -+ str_normalize_filepath(p_filter_str); ++ str_normalize_filepath(p_filename_str); if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { if (str_get_char_at(p_filter_str, 0) == '/') { From 1cbf7ab3a0bc16c4187fba634f8b2afa5d77856197350fa650881f6ae1e564e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Sun, 5 Apr 2015 11:40:52 +0000 Subject: [PATCH 9/9] ENOENT, ensure we sent both dir+file to filter verification: OBS-URL: https://build.opensuse.org/package/show/network/vsftpd?expand=0&rev=82 --- vsftpd-path-normalize.patch | 48 +++++++++++++++++++++++++++---------- vsftpd.changes | 2 +- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index 6482cdf..73e94d5 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -1,15 +1,3 @@ -Index: vsftpd-3.0.2/ls.c -=================================================================== ---- vsftpd-3.0.2.orig/ls.c -+++ vsftpd-3.0.2/ls.c -@@ -249,6 +249,7 @@ vsf_filename_passes_filter(const struct - int matched = 0; - - str_copy(&filter_remain_str, p_filter_str); -+ str_normalize_filepath(p_filename_str); - - if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { - if (str_get_char_at(p_filter_str, 0) == '/') { Index: vsftpd-3.0.2/str.c =================================================================== --- vsftpd-3.0.2.orig/str.c @@ -100,3 +88,39 @@ Index: vsftpd-3.0.2/str.h /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string * buffer, starting at character position 'p_pos'. The extracted line will +Index: vsftpd-3.0.2/ls.c +=================================================================== +--- vsftpd-3.0.2.orig/ls.c ++++ vsftpd-3.0.2/ls.c +@@ -117,11 +117,13 @@ vsf_ls_populate_dir_list(struct mystr_li + { + continue; + } ++ str_copy(&s_next_path_and_filename_str, &normalised_base_dir_str); ++ str_append_str(&s_next_path_and_filename_str, &s_next_filename_str); + /* If we have an ls option which is a filter, apply it */ + if (!str_isempty(p_filter_str)) + { + unsigned int iters = 0; +- if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str, ++ if (!vsf_filename_passes_filter(&s_next_path_and_filename_str, p_filter_str, + &iters)) + { + continue; +@@ -130,8 +132,6 @@ vsf_ls_populate_dir_list(struct mystr_li + /* Calculate the full path (relative to CWD) for lstat() and + * output purposes + */ +- str_copy(&s_next_path_and_filename_str, &normalised_base_dir_str); +- str_append_str(&s_next_path_and_filename_str, &s_next_filename_str); + if (do_stat) + { + /* lstat() the file. Of course there's a race condition - the +@@ -249,6 +249,7 @@ vsf_filename_passes_filter(const struct + int matched = 0; + + str_copy(&filter_remain_str, p_filter_str); ++ str_normalize_filepath(p_filename_str); + + if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) { + if (str_get_char_at(p_filter_str, 0) == '/') { diff --git a/vsftpd.changes b/vsftpd.changes index 9f58213..3e399a1 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -2,7 +2,7 @@ Sun Apr 5 10:25:50 UTC 2015 - tchvatal@suse.com - bnc#925963 stat is sometimes run on wrong path and results with - ENOENT: + ENOENT, ensure we sent both dir+file to filter verification: * vsftpd-path-normalize.patch -------------------------------------------------------------------