007-CVE-2015-1419.patch 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. +#include <stdlib.h>
  14. #include "ls.h"
  15. #include "access.h"
  16. #include "defs.h"
  17. @@ -243,11 +244,42 @@ vsf_filename_passes_filter(const struct
  18. struct mystr temp_str = INIT_MYSTR;
  19. struct mystr brace_list_str = INIT_MYSTR;
  20. struct mystr new_filter_str = INIT_MYSTR;
  21. + struct mystr normalize_filename_str = INIT_MYSTR;
  22. + const char *normname;
  23. + const char *path;
  24. int ret = 0;
  25. char last_token = 0;
  26. int must_match_at_current_pos = 1;
  27. +
  28. str_copy(&filter_remain_str, p_filter_str);
  29. - str_copy(&name_remain_str, p_filename_str);
  30. +
  31. + /* normalize filepath */
  32. + path = str_strdup(p_filename_str);
  33. + normname = realpath(path, NULL);
  34. + if (normname == NULL)
  35. + goto out;
  36. + str_alloc_text(&normalize_filename_str, normname);
  37. +
  38. + if (!str_isempty (&filter_remain_str) && !str_isempty(&normalize_filename_str)) {
  39. + if (str_get_char_at(p_filter_str, 0) == '/') {
  40. + if (str_get_char_at(&normalize_filename_str, 0) != '/') {
  41. + str_getcwd (&name_remain_str);
  42. +
  43. + if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */
  44. + str_append_char (&name_remain_str, '/');
  45. +
  46. + str_append_str (&name_remain_str, &normalize_filename_str);
  47. + }
  48. + else
  49. + str_copy (&name_remain_str, &normalize_filename_str);
  50. + } else {
  51. + if (str_get_char_at(p_filter_str, 0) != '{')
  52. + str_basename (&name_remain_str, &normalize_filename_str);
  53. + else
  54. + str_copy (&name_remain_str, &normalize_filename_str);
  55. + }
  56. + } else
  57. + str_copy(&name_remain_str, &normalize_filename_str);
  58. while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
  59. {
  60. @@ -360,6 +392,9 @@ vsf_filename_passes_filter(const struct
  61. ret = 0;
  62. }
  63. out:
  64. + free(normname);
  65. + free(path);
  66. + str_free(&normalize_filename_str);
  67. str_free(&filter_remain_str);
  68. str_free(&name_remain_str);
  69. str_free(&temp_str);
  70. --- a/str.c
  71. +++ b/str.c
  72. @@ -711,3 +711,14 @@ str_replace_unprintable(struct mystr* p_
  73. }
  74. }
  75. +void
  76. +str_basename (struct mystr* d_str, const struct mystr* path)
  77. +{
  78. + static struct mystr tmp;
  79. +
  80. + str_copy (&tmp, path);
  81. + str_split_char_reverse(&tmp, d_str, '/');
  82. +
  83. + if (str_isempty(d_str))
  84. + str_copy (d_str, path);
  85. +}
  86. --- a/str.h
  87. +++ b/str.h
  88. @@ -100,6 +100,7 @@ void str_replace_unprintable(struct myst
  89. int str_atoi(const struct mystr* p_str);
  90. filesize_t str_a_to_filesize_t(const struct mystr* p_str);
  91. unsigned int str_octal_to_uint(const struct mystr* p_str);
  92. +void str_basename (struct mystr* d_str, const struct mystr* path);
  93. /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string
  94. * buffer, starting at character position 'p_pos'. The extracted line will