]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: listener: Handle allocation error when allocating a new bind_conf
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 12 Apr 2021 14:56:37 +0000 (16:56 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 12 Apr 2021 19:33:43 +0000 (21:33 +0200)
Allocation error are now handled in bind_conf_alloc() functions. Thus
callers, when not already done, are also updated to catch NULL return value.

This patch may be backported (at least partially) to all stable
versions. However, it only fix errors durung configuration parsing. Thus it
is not mandatory.

include/haproxy/listener.h
src/cfgparse-listen.c
src/cli.c
src/log.c

index 17fe9e09087f6dde89d726829c798c920ab08419..a8c798c53a8ef58b4ca6aeeb25910bf8c4db19d2 100644 (file)
@@ -174,19 +174,27 @@ unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r);
 
 /* allocate an bind_conf struct for a bind line, and chain it to the frontend <fe>.
  * If <arg> is not NULL, it is duplicated into ->arg to store useful config
- * information for error reporting.
+ * information for error reporting. NULL is returned on error.
  */
 static inline struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file,
                                  int line, const char *arg, struct xprt_ops *xprt)
 {
        struct bind_conf *bind_conf = calloc(1, sizeof(struct bind_conf));
 
+       if (!bind_conf)
+               goto err;
+
        bind_conf->file = strdup(file);
+       if (!bind_conf->file)
+               goto err;
        bind_conf->line = line;
-       LIST_ADDQ(&fe->conf.bind, &bind_conf->by_fe);
-       if (arg)
+       if (arg) {
                bind_conf->arg = strdup(arg);
+               if (!bind_conf->arg)
+                       goto err;
+       }
 
+       LIST_ADDQ(&fe->conf.bind, &bind_conf->by_fe);
        bind_conf->settings.ux.uid = -1;
        bind_conf->settings.ux.gid = -1;
        bind_conf->settings.ux.mode = 0;
@@ -200,6 +208,14 @@ static inline struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *fi
 #endif
        LIST_INIT(&bind_conf->listeners);
        return bind_conf;
+
+  err:
+       if (bind_conf) {
+               ha_free(&bind_conf->file);
+               ha_free(&bind_conf->arg);
+       }
+       ha_free(&bind_conf);
+       return NULL;
 }
 
 static inline const char *listener_state_str(const struct listener *l)
index fba6d019d9ba435cc7e988936030b33ef9633953..3038beb14a1b14923b037d115d09e76edcaede80 100644 (file)
@@ -387,7 +387,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                }
 
                bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
-
+               if (!bind_conf) {
+                       ha_alert("Out of memory error.\n");
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
                /* use default settings for unix sockets */
                bind_conf->settings.ux.uid  = global.unix_bind.ux.uid;
                bind_conf->settings.ux.gid  = global.unix_bind.ux.gid;
index 32d7efbe002e0aa0f033a94f21e48c1c5a8484c3..13603df5dde765ba63a0426cf0047819a9c8fc38 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -401,6 +401,10 @@ static int cli_parse_global(char **args, int section_type, struct proxy *curpx,
                }
 
                bind_conf = bind_conf_alloc(global.cli_fe, file, line, args[2], xprt_get(XPRT_RAW));
+               if (!bind_conf) {
+                       memprintf(err, "'%s %s' : out of memory trying to allocate a bind_conf", args[0], args[1]);
+                       return -1;
+               }
                bind_conf->level &= ~ACCESS_LVL_MASK;
                bind_conf->level |= ACCESS_LVL_OPER; /* default access level */
 
index 2931ee96dc4f6c98d1bedd1328428ce497a89e76..7930c52eff928085b162b6b7682a9d7f46b7bbcb 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -4031,6 +4031,11 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
 
                bind_conf = bind_conf_alloc(cfg_log_forward, file, linenum,
                                            NULL, xprt_get(XPRT_RAW));
+               if (!bind_conf) {
+                       ha_alert("parsing [%s:%d] : out of memory error.", file, linenum);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
 
                if (!str2receiver(args[1], cfg_log_forward, bind_conf, file, linenum, &errmsg)) {
                        if (errmsg && *errmsg) {