diff --git a/vsftpd-2.3.4-sqb.patch b/vsftpd-2.3.4-sqb.patch index 0ad9088..21b40c3 100644 --- a/vsftpd-2.3.4-sqb.patch +++ b/vsftpd-2.3.4-sqb.patch @@ -1,7 +1,8 @@ -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 +Index: vsftpd-2.0.7/ls.c +=================================================================== +--- vsftpd-2.0.7.orig/ls.c ++++ vsftpd-2.0.7/ls.c +@@ -243,7 +243,7 @@ vsf_filename_passes_filter(const struct int ret = 0; char last_token = 0; int must_match_at_current_pos = 1; @@ -10,7 +11,7 @@ diff -up vsftpd-3.0.2/ls.c.sqb vsftpd-3.0.2/ls.c str_copy(&filter_remain_str, p_filter_str); -@@ -276,7 +276,7 @@ vsf_filename_passes_filter(const struct +@@ -273,7 +273,7 @@ vsf_filename_passes_filter(const struct static struct mystr s_match_needed_str; /* Locate next special token */ struct str_locate_result locate_result = @@ -19,104 +20,93 @@ diff -up vsftpd-3.0.2/ls.c.sqb vsftpd-3.0.2/ls.c (*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 +@@ -291,8 +291,14 @@ 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)) + if (!str_isempty(&s_match_needed_str)) + { ++ 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 + */ +@@ -344,13 +350,20 @@ vsf_filename_passes_filter(const struct + must_match_at_current_pos = 1; + if (end_brace.found) { -- /* 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); ++ 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_copy(&new_filter_str, &brace_list_str); ++ str_empty(&new_filter_str); ++ if (!matched && !entire) + { -+ ret = 1; ++ str_append_char(&new_filter_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); - } -- indexx = locate_result.index; -- if (must_match_at_current_pos && indexx > 0) -+ if (last_token == '?') ++ 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)) +@@ -368,6 +381,68 @@ vsf_filename_passes_filter(const struct { -- 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; + goto out; } -- 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) ++ else ++ { ++ str_right(&name_remain_str, &temp_str, ++ str_getlen(&name_remain_str) - 1); ++ str_copy(&name_remain_str, &temp_str); ++ } ++ } ++ else if (last_token == '[') ++ { ++ 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);) + { -+ 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)) ++ 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 && !entire) ++ if (!matched) + { + str_append_char(&new_filter_str, '*'); + } -+ str_append_str(&new_filter_str, &brace_list_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)) @@ -124,142 +114,15 @@ diff -up vsftpd-3.0.2/ls.c.sqb vsftpd-3.0.2/ls.c + 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; - } ++ 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. + str_right(&name_remain_str, &temp_str, diff --git a/vsftpd-ls-memleak.patch b/vsftpd-ls-memleak.patch new file mode 100644 index 0000000..b66ddd7 --- /dev/null +++ b/vsftpd-ls-memleak.patch @@ -0,0 +1,11 @@ +Index: vsftpd-2.0.7/ls.c +=================================================================== +--- vsftpd-2.0.7.orig/ls.c ++++ vsftpd-2.0.7/ls.c +@@ -558,5 +559,6 @@ build_dir_line(struct mystr* p_str, cons + /* Filename */ + str_append_str(p_str, p_filename_str); + str_append_text(p_str, "\r\n"); ++ str_free(&s_tmp_str); + } + diff --git a/vsftpd-path-normalize.patch b/vsftpd-path-normalize.patch index ef663bb..c49a8dd 100644 --- a/vsftpd-path-normalize.patch +++ b/vsftpd-path-normalize.patch @@ -161,3 +161,11 @@ Index: vsftpd-3.0.2/ls.c while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) { +@@ -475,6 +475,7 @@ vsf_filename_passes_filter(const struct + } + out: + str_free(&filter_remain_str); ++ str_free(&basic_name_str); + str_free(&name_remain_str); + str_free(&temp_str); + str_free(&brace_list_str); diff --git a/vsftpd.changes b/vsftpd.changes index 1af95c5..dcec9c8 100644 --- a/vsftpd.changes +++ b/vsftpd.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Thu Mar 10 18:15:03 UTC 2016 - jcejka@suse.com + +- Fix memory leaks in ls.c bnc#968138 + * Add patch vsftpd-ls-memleak.patch + * Update patch vsftpd-path-normalize.patch +- Fix wildcard ? matching bnc#969411 + * Update patch vsftpd-2.3.4-sqb.patch + ------------------------------------------------------------------- Mon Sep 21 11:34:46 UTC 2015 - tchvatal@suse.com diff --git a/vsftpd.spec b/vsftpd.spec index 1144c4a..ce59dd0 100644 --- a/vsftpd.spec +++ b/vsftpd.spec @@ -1,7 +1,7 @@ # # spec file for package vsftpd # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -67,6 +67,7 @@ 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 +Patch23: vsftpd-ls-memleak.patch BuildRequires: libcap-devel BuildRequires: openssl-devel BuildRequires: pam-devel @@ -114,6 +115,7 @@ tests. %patch20 -p1 %patch21 -p1 %patch22 -p1 +%patch23 -p1 %build %define seccomp_opts -D_GNU_SOURCE -DUSE_SECCOMP