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