007-CVE-2015-1419.patch (3122B)
1 Description: CVE-2015-1419: config option deny_file is not handled correctly 2 Author: Marcus Meissner <meissner@suse.com> 3 Origin: https://bugzilla.novell.com/show_bug.cgi?id=CVE-2015-1419 4 Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776922 5 Last-Update: 2015-02-24 6 --- 7 This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ 8 --- a/ls.c 9 +++ b/ls.c 10 @@ -7,6 +7,7 @@ 11 * Would you believe, code to handle directory listing. 12 */ 13 14 +#include <stdlib.h> 15 #include "ls.h" 16 #include "access.h" 17 #include "defs.h" 18 @@ -243,11 +244,42 @@ vsf_filename_passes_filter(const struct 19 struct mystr temp_str = INIT_MYSTR; 20 struct mystr brace_list_str = INIT_MYSTR; 21 struct mystr new_filter_str = INIT_MYSTR; 22 + struct mystr normalize_filename_str = INIT_MYSTR; 23 + const char *normname; 24 + const char *path; 25 int ret = 0; 26 char last_token = 0; 27 int must_match_at_current_pos = 1; 28 + 29 str_copy(&filter_remain_str, p_filter_str); 30 - str_copy(&name_remain_str, p_filename_str); 31 + 32 + /* normalize filepath */ 33 + path = str_strdup(p_filename_str); 34 + normname = realpath(path, NULL); 35 + if (normname == NULL) 36 + goto out; 37 + str_alloc_text(&normalize_filename_str, normname); 38 + 39 + if (!str_isempty (&filter_remain_str) && !str_isempty(&normalize_filename_str)) { 40 + if (str_get_char_at(p_filter_str, 0) == '/') { 41 + if (str_get_char_at(&normalize_filename_str, 0) != '/') { 42 + str_getcwd (&name_remain_str); 43 + 44 + if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */ 45 + str_append_char (&name_remain_str, '/'); 46 + 47 + str_append_str (&name_remain_str, &normalize_filename_str); 48 + } 49 + else 50 + str_copy (&name_remain_str, &normalize_filename_str); 51 + } else { 52 + if (str_get_char_at(p_filter_str, 0) != '{') 53 + str_basename (&name_remain_str, &normalize_filename_str); 54 + else 55 + str_copy (&name_remain_str, &normalize_filename_str); 56 + } 57 + } else 58 + str_copy(&name_remain_str, &normalize_filename_str); 59 60 while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) 61 { 62 @@ -360,6 +392,9 @@ vsf_filename_passes_filter(const struct 63 ret = 0; 64 } 65 out: 66 + free(normname); 67 + free(path); 68 + str_free(&normalize_filename_str); 69 str_free(&filter_remain_str); 70 str_free(&name_remain_str); 71 str_free(&temp_str); 72 --- a/str.c 73 +++ b/str.c 74 @@ -711,3 +711,14 @@ str_replace_unprintable(struct mystr* p_ 75 } 76 } 77 78 +void 79 +str_basename (struct mystr* d_str, const struct mystr* path) 80 +{ 81 + static struct mystr tmp; 82 + 83 + str_copy (&tmp, path); 84 + str_split_char_reverse(&tmp, d_str, '/'); 85 + 86 + if (str_isempty(d_str)) 87 + str_copy (d_str, path); 88 +} 89 --- a/str.h 90 +++ b/str.h 91 @@ -100,6 +100,7 @@ void str_replace_unprintable(struct myst 92 int str_atoi(const struct mystr* p_str); 93 filesize_t str_a_to_filesize_t(const struct mystr* p_str); 94 unsigned int str_octal_to_uint(const struct mystr* p_str); 95 +void str_basename (struct mystr* d_str, const struct mystr* path); 96 97 /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string 98 * buffer, starting at character position 'p_pos'. The extracted line will