]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: peers: Missing calloc return value check in peers_register_table
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Wed, 12 May 2021 15:39:04 +0000 (17:39 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 31 May 2021 08:50:46 +0000 (10:50 +0200)
A memory allocation failure happening during peers_register_table would
have resulted in a crash. This function is only called during init.

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

include/haproxy/peers.h
src/peers.c
src/stick_table.c

index 636b5c8718e95cf04dc1067ab7e89016e3bab49a..d5e5765b29db1a8402147c238b2d074f45ef171f 100644 (file)
@@ -36,7 +36,7 @@ extern struct peers *cfg_peers;
 
 int peers_init_sync(struct peers *peers);
 int peers_alloc_dcache(struct peers *peers);
-void peers_register_table(struct peers *, struct stktable *table);
+int peers_register_table(struct peers *, struct stktable *table);
 void peers_setup_frontend(struct proxy *fe);
 
 #if defined(USE_OPENSSL)
index 3f8850843932c4b3d2793839d2c5e7bfb6b428de..3a980dd112211fc1f18e9f24b91ced715090f796 100644 (file)
@@ -3366,16 +3366,21 @@ int peers_alloc_dcache(struct peers *peers)
 
 /*
  * Function used to register a table for sync on a group of peers
- *
+ * Returns 0 in case of success.
  */
-void peers_register_table(struct peers *peers, struct stktable *table)
+int peers_register_table(struct peers *peers, struct stktable *table)
 {
        struct shared_table *st;
        struct peer * curpeer;
        int id = 0;
+       int retval = 0;
 
        for (curpeer = peers->remote; curpeer; curpeer = curpeer->next) {
                st = calloc(1,sizeof(*st));
+               if (!st) {
+                       retval = 1;
+                       break;
+               }
                st->table = table;
                st->next = curpeer->tables;
                if (curpeer->tables)
@@ -3393,6 +3398,8 @@ void peers_register_table(struct peers *peers, struct stktable *table)
        }
 
        table->sync_task = peers->sync_task;
+
+       return retval;
 }
 
 /*
index 0255cd2762abfd1ce1e5bc46188f0cc16817b798..fbfbc4a8c7310a30645c82f123331081f9ca911e 100644 (file)
@@ -637,6 +637,7 @@ struct task *process_table_expire(struct task *task, void *context, unsigned int
 /* Perform minimal stick table intializations, report 0 in case of error, 1 if OK. */
 int stktable_init(struct stktable *t)
 {
+       int peers_retval = 0;
        if (t->size) {
                t->keys = EB_ROOT_UNIQUE;
                memset(&t->exps, 0, sizeof(t->exps));
@@ -654,10 +655,10 @@ int stktable_init(struct stktable *t)
                        t->exp_task->context = (void *)t;
                }
                if (t->peers.p && t->peers.p->peers_fe && !t->peers.p->peers_fe->disabled) {
-                       peers_register_table(t->peers.p, t);
+                       peers_retval = peers_register_table(t->peers.p, t);
                }
 
-               return t->pool != NULL;
+               return (t->pool != NULL) && !peers_retval;
        }
        return 1;
 }