From 959171376f4974b883b2aa4228b3f8c610ca2ae9 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 5 Aug 2020 23:07:07 +0200 Subject: [PATCH] BUG/MINOR: arg: Fix leaks during arguments validation for fetches/converters Some sample fetches or sample converters uses a validation functions for their arguments. In these function, string arguments (ARGT_STR) may be converted to another type (for instance a regex, a variable or a integer). Because these strings are allocated when the argument list is built, they must be freed after a conversion. Most of time, it is done. But not always. This patch fixes these minor memory leaks (only on few strings, during the configuration parsing). This patch may be backported to all supported versions, most probably as far as 2.1 only. If this commit is backported, the previous one 73292e9e6 ("BUG/MINOR: lua: Duplicate map name to load it when a new Map object is created") must also be backported. Note that some validation functions does not exists on old version. It should be easy to resolve conflicts. --- src/map.c | 2 ++ src/payload.c | 13 ++++++--- src/sample.c | 81 ++++++++++++++++++++++++--------------------------- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/map.c b/src/map.c index 3e9aa41b2b..5289e458a3 100644 --- a/src/map.c +++ b/src/map.c @@ -151,6 +151,7 @@ int sample_load_map(struct arg *arg, struct sample_conv *conv, arg[1].data.str.area); return 0; } + free(arg[1].data.str.area); if (data.type == SMP_T_IPV4) { arg[1].type = ARGT_IPV4; arg[1].data.ipv4 = data.u.ipv4; @@ -161,6 +162,7 @@ int sample_load_map(struct arg *arg, struct sample_conv *conv, } /* replace the first argument by this definition */ + free(arg[0].data.str.area); arg[0].type = ARGT_MAP; arg[0].data.map = desc; diff --git a/src/payload.c b/src/payload.c index 7feea16c30..a977233de0 100644 --- a/src/payload.c +++ b/src/payload.c @@ -1102,17 +1102,21 @@ int val_payload_lv(struct arg *arg, char **err_msg) } if (arg[2].type == ARGT_STR && arg[2].data.str.data > 0) { + long long int i; + if (arg[2].data.str.area[0] == '+' || arg[2].data.str.area[0] == '-') relative = 1; str = arg[2].data.str.area; - arg[2].type = ARGT_SINT; - arg[2].data.sint = read_int64(&str, - str + arg[2].data.str.data); + i = read_int64(&str, str + arg[2].data.str.data); if (*str != '\0') { memprintf(err_msg, "payload offset2 is not a number"); return 0; } - if (arg[0].data.sint + arg[1].data.sint + arg[2].data.sint < 0) { + free(arg[2].data.str.area); + arg[2].type = ARGT_SINT; + arg[2].data.sint = i; + + if (arg[0].data.sint + arg[1].data.sint + arg[2].data.sint < 0) { memprintf(err_msg, "payload offset2 too negative"); return 0; } @@ -1310,6 +1314,7 @@ int val_distcc(struct arg *arg, char **err_msg) token = (arg[0].data.str.area[0] << 24) + (arg[0].data.str.area[1] << 16) + (arg[0].data.str.area[2] << 8) + (arg[0].data.str.area[3] << 0); + free(arg[0].data.str.area); arg[0].type = ARGT_SINT; arg[0].data.sint = token; diff --git a/src/sample.c b/src/sample.c index 2e221047b5..9026b6e9c9 100644 --- a/src/sample.c +++ b/src/sample.c @@ -1514,6 +1514,7 @@ static int smp_check_debug(struct arg *args, struct sample_conv *conv, return 0; } + free(args[1].data.str.area); args[1].type = ARGT_PTR; args[1].data.ptr = sink; return 1; @@ -2143,6 +2144,8 @@ enum input_type { static int sample_conv_json_check(struct arg *arg, struct sample_conv *conv, const char *file, int line, char **err) { + enum input_type type; + if (!arg) { memprintf(err, "Unexpected empty arg list"); return 0; @@ -2153,45 +2156,28 @@ static int sample_conv_json_check(struct arg *arg, struct sample_conv *conv, return 0; } - if (strcmp(arg->data.str.area, "") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_ASCII; - return 1; - } - - else if (strcmp(arg->data.str.area, "ascii") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_ASCII; - return 1; - } - - else if (strcmp(arg->data.str.area, "utf8") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_UTF8; - return 1; - } - - else if (strcmp(arg->data.str.area, "utf8s") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_UTF8S; - return 1; - } - - else if (strcmp(arg->data.str.area, "utf8p") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_UTF8P; - return 1; - } - - else if (strcmp(arg->data.str.area, "utf8ps") == 0) { - arg->type = ARGT_SINT; - arg->data.sint = IT_UTF8PS; - return 1; + if (strcmp(arg->data.str.area, "") == 0) + type = IT_ASCII; + else if (strcmp(arg->data.str.area, "ascii") == 0) + type = IT_ASCII; + else if (strcmp(arg->data.str.area, "utf8") == 0) + type = IT_UTF8; + else if (strcmp(arg->data.str.area, "utf8s") == 0) + type = IT_UTF8S; + else if (strcmp(arg->data.str.area, "utf8p") == 0) + type = IT_UTF8P; + else if (strcmp(arg->data.str.area, "utf8ps") == 0) + type = IT_UTF8PS; + else { + memprintf(err, "Unexpected input code type. " + "Allowed value are 'ascii', 'utf8', 'utf8s', 'utf8p' and 'utf8ps'"); + return 0; } - memprintf(err, "Unexpected input code type. " - "Allowed value are 'ascii', 'utf8', 'utf8s', 'utf8p' and 'utf8ps'"); - return 0; + free(arg->data.str.area); + arg->type = ARGT_SINT; + arg->data.sint = type; + return 1; } static int sample_conv_json(const struct arg *arg_p, struct sample *smp, void *private) @@ -2666,6 +2652,7 @@ static int check_operator(struct arg *args, struct sample_conv *conv, { const char *str; const char *end; + long long int i; /* Try to decode a variable. */ if (vars_check_arg(&args[0], NULL)) @@ -2674,12 +2661,15 @@ static int check_operator(struct arg *args, struct sample_conv *conv, /* Try to convert an integer */ str = args[0].data.str.area; end = str + strlen(str); - args[0].data.sint = read_int64(&str, end); + i = read_int64(&str, end); if (*str != '\0') { memprintf(err, "expects an integer or a variable name"); return 0; } + + free(args[0].data.str.area); args[0].type = ARGT_SINT; + args[0].data.sint = i; return 1; } @@ -3203,6 +3193,7 @@ static int sample_conv_protobuf_check(struct arg *args, struct sample_conv *conv return 0; } + free(args[1].data.str.area); args[1].type = ARGT_SINT; args[1].data.sint = pbuf_type; } @@ -3368,23 +3359,26 @@ smp_fetch_env(const struct arg *args, struct sample *smp, const char *kw, void * int smp_check_date_unit(struct arg *args, char **err) { if (args[1].type == ARGT_STR) { + long long int unit; + if (strcmp(args[1].data.str.area, "s") == 0) { - args[1].data.sint = TIME_UNIT_S; + unit = TIME_UNIT_S; } else if (strcmp(args[1].data.str.area, "ms") == 0) { - args[1].data.sint = TIME_UNIT_MS; + unit = TIME_UNIT_MS; } else if (strcmp(args[1].data.str.area, "us") == 0) { - args[1].data.sint = TIME_UNIT_US; + unit = TIME_UNIT_US; } else { memprintf(err, "expects 's', 'ms' or 'us', got '%s'", args[1].data.str.area); return 0; } - free(args[1].data.str.area); - args[1].data.str.area = NULL; + + free(args[1].data.str.area); args[1].type = ARGT_SINT; + args[1].data.sint = unit; } else if (args[1].type != ARGT_STOP) { memprintf(err, "Unexpected arg type"); @@ -3622,6 +3616,7 @@ static int smp_check_const_bin(struct arg *args, char **err) if (!parse_binary(args[0].data.str.area, &binstr, &binstrlen, err)) return 0; + free(args[0].data.str.area); args[0].type = ARGT_STR; args[0].data.str.area = binstr; args[0].data.str.data = binstrlen; -- 2.39.5