BUG/MINOR: listener: Handle allocation error when allocating a new bind_conf

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.
This commit is contained in:
Christopher Faulet 2021-04-12 16:56:37 +02:00
parent 2e848a9b75
commit 0c6d1dcf7d
4 changed files with 36 additions and 7 deletions

View 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));
bind_conf->file = strdup(file);
bind_conf->line = line;
LIST_ADDQ(&fe->conf.bind, &bind_conf->by_fe);
if (arg)
bind_conf->arg = strdup(arg);
if (!bind_conf)
goto err;
bind_conf->file = strdup(file);
if (!bind_conf->file)
goto err;
bind_conf->line = line;
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)

View 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;

View File

@ -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 */

View File

@ -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) {