0001-listdir-reuse-a-single-buffer-to-store-every-file-name-to-display.patch 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. From aea56f4bcb9948d456f3fae4d044fd3fa2e19706 Mon Sep 17 00:00:00 2001
  2. From: Frank Denis <github@pureftpd.org>
  3. Date: Mon, 30 Dec 2019 17:40:04 +0100
  4. Subject: [PATCH] listdir(): reuse a single buffer to store every file name to
  5. display
  6. Allocating a new buffer for each entry is useless.
  7. And as these buffers are allocated on the stack, on systems with a
  8. small stack size, with many entries, the limit can easily be reached,
  9. causing a stack exhaustion and aborting the user session.
  10. Reported by Antonio Morales from the GitHub Security Lab team, thanks!
  11. [Retrieved from:
  12. https://github.com/jedisct1/pure-ftpd/commit/aea56f4bcb9948d456f3fae4d044fd3fa2e19706]
  13. Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
  14. ---
  15. src/ls.c | 15 ++++++++-------
  16. 1 file changed, 8 insertions(+), 7 deletions(-)
  17. diff --git a/src/ls.c b/src/ls.c
  18. index cf804c7..f8a588f 100644
  19. --- a/src/ls.c
  20. +++ b/src/ls.c
  21. @@ -661,6 +661,8 @@ static void listdir(unsigned int depth, int f, void * const tls_fd,
  22. char *names;
  23. PureFileInfo *s;
  24. PureFileInfo *r;
  25. + char *alloca_subdir;
  26. + size_t sizeof_subdir;
  27. int d;
  28. if (depth >= max_ls_depth || matches >= max_ls_files) {
  29. @@ -690,14 +692,12 @@ static void listdir(unsigned int depth, int f, void * const tls_fd,
  30. }
  31. outputfiles(f, tls_fd);
  32. r = dir;
  33. + sizeof_subdir = PATH_MAX + 1U;
  34. + if ((alloca_subdir = ALLOCA(sizeof_subdir)) == NULL) {
  35. + goto toomany;
  36. + }
  37. while (opt_R && r != s) {
  38. if (r->name_offset != (size_t) -1 && !chdir(FI_NAME(r))) {
  39. - char *alloca_subdir;
  40. - const size_t sizeof_subdir = PATH_MAX + 1U;
  41. -
  42. - if ((alloca_subdir = ALLOCA(sizeof_subdir)) == NULL) {
  43. - goto toomany;
  44. - }
  45. if (SNCHECK(snprintf(alloca_subdir, sizeof_subdir, "%s/%s",
  46. name, FI_NAME(r)), sizeof_subdir)) {
  47. goto nolist;
  48. @@ -706,8 +706,8 @@ static void listdir(unsigned int depth, int f, void * const tls_fd,
  49. wrstr(f, tls_fd, alloca_subdir);
  50. wrstr(f, tls_fd, ":\r\n\r\n");
  51. listdir(depth + 1U, f, tls_fd, alloca_subdir);
  52. +
  53. nolist:
  54. - ALLOCA_FREE(alloca_subdir);
  55. if (matches >= max_ls_files) {
  56. goto toomany;
  57. }
  58. @@ -720,6 +720,7 @@ static void listdir(unsigned int depth, int f, void * const tls_fd,
  59. r++;
  60. }
  61. toomany:
  62. + ALLOCA_FREE(alloca_subdir);
  63. free(names);
  64. free(dir);
  65. names = NULL;