File pure-ftpd-malloc-limit.patch of Package pure-ftpd

diff -Nur pure-ftpd-1.0.49.orig/man/pure-ftpd.8.in pure-ftpd-1.0.49/man/pure-ftpd.8.in
--- pure-ftpd-1.0.49.orig/man/pure-ftpd.8.in	2019-03-25 16:48:42.000000000 +0100
+++ pure-ftpd-1.0.49/man/pure-ftpd.8.in	2020-04-27 16:36:01.574470331 +0200
@@ -9,7 +9,7 @@
 pure\-ftpd \- simple File Transfer Protocol server
 
 .SH "SYNOPSIS"
-.B pure\-ftpd [\-0] [\-1] [\-2 cert_file[,key_file]] [\-3 certd_socket] [\-4] [\-6] [\-a gid] [\-A] [\-b] [\-B] [\-c clients] [\-C cnx/ip] [\-d [\-d]] [\-D] [\-e] [\-E] [\-f facility] [\-F fortunes file] [\-g pidfile] [\-G] [\-H] [\-i] [\-I] [\-j] [\-J ciphers] [\-k percentage] [\-K] [\-l authentication[:config file]] [\-L max files:max depth] [\-m maxload] [\-M] [\-n maxfiles:maxsize] [\-N] [\-o] [\-O format:log file] [\-p first:last] [\-P ip address or host name] [\-q upload:download ratio] [\-Q upload:download ratio] [\-r] [\-R] [\-s] [\-S [address,][port]] [\-t upload bandwidth:download bandwidth] [\-T upload bandwidth:download bandwidth] [\-u uid] [\-U umask files:umask dirs] [\-v bonjour name] [\-V ip address] [\-w] [\-W] [\-x] [\-X] [\-y max user sessions:max anon sessions] [\-Y tls behavior] [\-z] [\-Z]
+.B pure\-ftpd [\-0] [\-1] [\-2 cert_file[,key_file]] [\-3 certd_socket] [\-4] [\-6] [\-a gid] [\-A] [\-b] [\-B] [\-c clients] [\-C cnx/ip] [\-d [\-d]] [\-D] [\-e] [\-E] [\-f facility] [\-F fortunes file] [\-g pidfile] [\-G] [\-H] [\-i] [\-I] [\-j] [\-J ciphers] [\-k percentage] [\-K] [\-l authentication[:config file]] [\-L max files:max depth:[:maxmemory]] [\-m maxload] [\-M] [\-n maxfiles:maxsize] [\-N] [\-o] [\-O format:log file] [\-p first:last] [\-P ip address or host name] [\-q upload:download ratio] [\-Q upload:download ratio] [\-r] [\-R] [\-s] [\-S [address,][port]] [\-t upload bandwidth:download bandwidth] [\-T upload bandwidth:download bandwidth] [\-u uid] [\-U umask files:umask dirs] [\-v bonjour name] [\-V ip address] [\-w] [\-W] [\-x] [\-X] [\-y max user sessions:max anon sessions] [\-Y tls behavior] [\-z] [\-Z]
 
 .br
 Alternative style:
@@ -337,11 +337,12 @@
 .I README.MySQL
 files for info about the built\-in LDAP and SQL directory support.
 .TP
-.B \-L max files:max depth
+.B \-L max files:max depth[:max memory limit]
 Avoid denial\-of\-service attacks by limiting the number of displayed files
-in a 'ls' and the maximum depth of a recursive 'ls'. Defaults are 2000:5
-(2000 files displayed for a single 'ls' and walk through 5 subdirectories
-max).
+in a 'ls', the maximum depth of a recursive 'ls' and optional memory limit
+for globbing in kilobytes. Defaults are 2000:5:512 (2000 files displayed
+for a single 'ls', walk through 5 subdirectories max and limit allocated
+memory for evaluation wildcard characters by 'ls' to 524288 bytes).
 .TP
 .B \-m load
 Do not allow anonymous users to download files if the load is above
diff -Nur pure-ftpd-1.0.49.orig/src/bsd-glob.c pure-ftpd-1.0.49/src/bsd-glob.c
--- pure-ftpd-1.0.49.orig/src/bsd-glob.c	2019-04-02 16:00:39.000000000 +0200
+++ pure-ftpd-1.0.49/src/bsd-glob.c	2020-04-27 16:33:21.997238426 +0200
@@ -107,9 +107,6 @@
 #define M_SET           META('[')
 #define ismeta(c)       (((c)&M_QUOTE) != 0)
 
-#ifndef GLOB_LIMIT_MALLOC
-# define GLOB_LIMIT_MALLOC       65536
-#endif
 #ifndef GLOB_MAX_STARS
 # define GLOB_MAX_STARS          3
 #endif
@@ -160,7 +157,7 @@
 
 static int
 glob_(const char *pattern, int flags, int (*errfunc)(const char *, int),
-      glob_t *pglob, unsigned long maxfiles, int maxdepth)
+      glob_t *pglob, unsigned long maxfiles, int maxdepth, unsigned long maxmemory)
 {
     const unsigned char *patnext;
     int c;
@@ -172,6 +169,7 @@
     }
     pglob->gl_maxdepth = maxdepth;
     pglob->gl_maxfiles = maxfiles;
+    pglob->gl_maxmemory = maxmemory;
     patnext = (unsigned char *) pattern;
     if (!(flags & GLOB_APPEND)) {
         pglob->gl_pathc = 0;
@@ -226,15 +224,15 @@
 glob(const char *pattern, int flags, int (*errfunc) (const char *, int),
      glob_t * pglob)
 {
-    return glob_(pattern, flags, errfunc, pglob, (unsigned long) -1, 0);
+    return glob_(pattern, flags, errfunc, pglob, (unsigned long) -1, 0, GLOB_LIMIT_MALLOC);
 }
 
 int
 sglob(char *pattern, int flags, int (*errfunc) (const char *, int),
-      glob_t * pglob, unsigned long maxfiles, int maxdepth)
+      glob_t * pglob, unsigned long maxfiles, int maxdepth, unsigned long maxmemory)
 {
     simplify(pattern);
-    return glob_(pattern, flags, errfunc, pglob, maxfiles, maxdepth);
+    return glob_(pattern, flags, errfunc, pglob, maxfiles, maxdepth, maxmemory);
 }
 
 /*
@@ -766,7 +764,7 @@
             statv[pglob->gl_offs + pglob->gl_pathc] = NULL;
         } else {
             limitp->glim_malloc += sizeof(**statv);
-            if (limitp->glim_malloc >= GLOB_LIMIT_MALLOC) {
+            if (limitp->glim_malloc >= pglob->gl_maxmemory) {
                 errno = 0;
                 return GLOB_NOSPACE;
             }
@@ -793,7 +791,7 @@
     }
     pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
 
-    if ((newn * sizeof(*pathv)) + limitp->glim_malloc > GLOB_LIMIT_MALLOC) {
+    if ((newn * sizeof(*pathv)) + limitp->glim_malloc > pglob->gl_maxmemory) {
         errno = 0;
         return GLOB_NOSPACE;
     }
diff -Nur pure-ftpd-1.0.49.orig/src/bsd-glob.h pure-ftpd-1.0.49/src/bsd-glob.h
--- pure-ftpd-1.0.49.orig/src/bsd-glob.h	2018-09-19 23:53:05.000000000 +0200
+++ pure-ftpd-1.0.49/src/bsd-glob.h	2020-04-27 16:33:22.001238457 +0200
@@ -38,6 +38,7 @@
 typedef struct {
     unsigned long gl_maxfiles;  /* Maximum number of results */
     int gl_maxdepth;            /* Maximum depth */
+    unsigned long gl_maxmemory; /* Maximum memory allocated */
         int gl_pathc;           /* Count of total paths so far. */
         int gl_matchc;          /* Count of paths matching pattern. */
         int gl_offs;            /* Reserved at beginning of gl_pathv. */
@@ -84,14 +85,14 @@
 
 #ifdef DISABLE_GLOBBING
 # define glob(A, B, C, D) (GLOB_NOSYS)
-# define sglob(A, B, C, D, E, F) (GLOB_NOSYS)
+# define sglob(A, B, C, D, E, F, G) (GLOB_NOSYS)
 # define globfree(A) (void) 0
 #else
 # ifndef USELESS_FOR_PUREFTPD
 int glob(const char *, int, int (*)(const char *, int), glob_t *);
 # endif
 int sglob(char *, int, int (*)(const char *, int),
-          glob_t *, unsigned long, int);
+          glob_t *, unsigned long, int, unsigned long);
 void globfree(glob_t *);
 #endif
 
diff -Nur pure-ftpd-1.0.49.orig/src/ftpd.c pure-ftpd-1.0.49/src/ftpd.c
--- pure-ftpd-1.0.49.orig/src/ftpd.c	2019-04-02 16:00:40.000000000 +0200
+++ pure-ftpd-1.0.49/src/ftpd.c	2020-04-27 16:33:22.001238457 +0200
@@ -5923,11 +5923,14 @@
         }
         case 'L': {
             int ret;
+            unsigned int tmp_glob_memory;
 
-            ret = sscanf(optarg, "%u:%u", &max_ls_files, &max_ls_depth);
-            if (ret != 2 ||
-                max_ls_files < 1U || max_ls_depth < 1U) {
+            ret = sscanf(optarg, "%u:%u:%u", &max_ls_files, &max_ls_depth, &tmp_glob_memory);
+            if (ret < 2 || ret > 3 ||
+                max_ls_files < 1U || max_ls_depth < 1U || tmp_glob_memory < 1U) {
                 die(421, LOG_ERR, MSG_CONF_ERR ": " MSG_ILLEGAL_LS_LIMITS ": %s" , optarg);
+            } else if (ret == 3) {
+                max_glob_memory = tmp_glob_memory * 1024;
             }
             break;
         }
diff -Nur pure-ftpd-1.0.49.orig/src/ftpd.h pure-ftpd-1.0.49/src/ftpd.h
--- pure-ftpd-1.0.49.orig/src/ftpd.h	2019-03-25 16:48:42.000000000 +0100
+++ pure-ftpd-1.0.49/src/ftpd.h	2020-04-27 16:33:22.001238457 +0200
@@ -541,6 +541,9 @@
 #ifndef DEFAULT_MAX_LS_DEPTH
 # define DEFAULT_MAX_LS_DEPTH 5U
 #endif
+#ifndef GLOB_LIMIT_MALLOC
+# define GLOB_LIMIT_MALLOC 524288U    /* Memory limit for globbing */
+#endif
 #ifndef GLOB_TIMEOUT
 # define GLOB_TIMEOUT 17                   /* Max user time for a 'ls' to complete */
 #endif
diff -Nur pure-ftpd-1.0.49.orig/src/globals.h pure-ftpd-1.0.49/src/globals.h
--- pure-ftpd-1.0.49.orig/src/globals.h	2019-03-25 17:58:02.000000000 +0100
+++ pure-ftpd-1.0.49/src/globals.h	2020-04-27 16:33:22.001238457 +0200
@@ -77,6 +77,7 @@
 GLOBAL0(int allow_anon_mkdir);
 GLOBAL(unsigned int max_ls_files, DEFAULT_MAX_LS_FILES);
 GLOBAL(unsigned int max_ls_depth, DEFAULT_MAX_LS_DEPTH);
+GLOBAL(unsigned int max_glob_memory, GLOB_LIMIT_MALLOC);
 GLOBAL0(char *fortunes_file);
 GLOBAL0(char host[NI_MAXHOST]);
 GLOBAL0(int replycode);
diff -Nur pure-ftpd-1.0.49.orig/src/ls.c pure-ftpd-1.0.49/src/ls.c
--- pure-ftpd-1.0.49.orig/src/ls.c	2019-04-02 16:00:40.000000000 +0200
+++ pure-ftpd-1.0.49/src/ls.c	2020-04-27 16:33:22.001238457 +0200
@@ -857,7 +857,7 @@
             memset(&g, 0, sizeof g);
             a = sglob(arg,
                       opt_a ? (GLOB_PERIOD | GLOB_LIMIT) : GLOB_LIMIT,
-                      NULL, &g, max_ls_files + 2, max_ls_depth * 2);
+                      NULL, &g, max_ls_files + 2, max_ls_depth * 2, max_glob_memory);
             alarm(0);
             if (a == 0) {
                 char **path;
openSUSE Build Service is sponsored by