BUG/MINOR: compression: Missing calloc return value check in comp_append_type/algo
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 17 May 2021 08:35:08 +0000 (10:35 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 31 May 2021 08:51:04 +0000 (10:51 +0200)
A memory allocation failure happening in comp_append_type or
comp_append_algo called while parsing compression options would have
resulted in a crash. These functions are only called during
configuration parsing.

It was raised in GitHub issue #1233.
It could be backported to all stable branches.

src/compression.c
src/flt_http_comp.c

index c9c0a30..7a7d900 100644 (file)
@@ -108,12 +108,15 @@ const struct comp_algo comp_algos[] =
 
 /*
  * Add a content-type in the configuration
+ * Returns 0 in case of success, 1 in case of allocation failure.
  */
 int comp_append_type(struct comp *comp, const char *type)
 {
        struct comp_type *comp_type;
 
        comp_type = calloc(1, sizeof(*comp_type));
+       if (!comp_type)
+               return 1;
        comp_type->name_len = strlen(type);
        comp_type->name = strdup(type);
        comp_type->next = comp->types;
@@ -123,6 +126,8 @@ int comp_append_type(struct comp *comp, const char *type)
 
 /*
  * Add an algorithm in the configuration
+ * Returns 0 in case of success, -1 if the <algo> is unmanaged, 1 in case of
+ * allocation failure.
  */
 int comp_append_algo(struct comp *comp, const char *algo)
 {
@@ -132,6 +137,8 @@ int comp_append_algo(struct comp *comp, const char *algo)
        for (i = 0; comp_algos[i].cfg_name; i++) {
                if (strcmp(algo, comp_algos[i].cfg_name) == 0) {
                        comp_algo = calloc(1, sizeof(*comp_algo));
+                       if (!comp_algo)
+                               return 1;
                        memmove(comp_algo, &comp_algos[i], sizeof(struct comp_algo));
                        comp_algo->next = comp->algos;
                        comp->algos = comp_algo;
index 22af46b..2ef8342 100644 (file)
@@ -635,11 +635,17 @@ parse_compression_options(char **args, int section, struct proxy *proxy,
                        return -1;
                }
                while (*(args[cur_arg])) {
-                       if (comp_append_algo(comp, args[cur_arg]) < 0) {
-                               memprintf(err, "'%s' : '%s' is not a supported algorithm.\n",
-                                         args[0], args[cur_arg]);
+                       int retval = comp_append_algo(comp, args[cur_arg]);
+                       if (retval) {
+                               if (retval < 0)
+                                       memprintf(err, "'%s' : '%s' is not a supported algorithm.\n",
+                                                 args[0], args[cur_arg]);
+                               else
+                                       memprintf(err, "'%s' : out of memory while parsing algo '%s'.\n",
+                                                 args[0], args[cur_arg]);
                                return -1;
                        }
+
                        if (proxy->comp->algos->init(&ctx, 9) == 0)
                                proxy->comp->algos->end(&ctx);
                        else {
@@ -661,7 +667,10 @@ parse_compression_options(char **args, int section, struct proxy *proxy,
                        return -1;
                }
                while (*(args[cur_arg])) {
-                       comp_append_type(comp, args[cur_arg]);
+                       if (comp_append_type(comp, args[cur_arg])) {
+                               memprintf(err, "'%s': out of memory.", args[0]);
+                               return -1;
+                       }
                        cur_arg++;
                        continue;
                }