]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: proxy: Missing calloc return value check in chash_init_server_tree
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Wed, 19 May 2021 14:40:28 +0000 (16:40 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 31 May 2021 08:55:51 +0000 (10:55 +0200)
A memory allocation failure happening in chash_init_server_tree while
trying to allocate a server's lb_nodes item used in consistent hashing
would have resulted in a crash. This function is only called during
configuration parsing.

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

include/haproxy/lb_chash.h
src/cfgparse.c
src/lb_chash.c

index 77d790fbe33b931ecad76d2f6fa0587605102600..79504574b803faaa144f9f777c2491a2e4ec136e 100644 (file)
@@ -27,7 +27,7 @@
 
 struct proxy;
 struct server;
-void chash_init_server_tree(struct proxy *p);
+int chash_init_server_tree(struct proxy *p);
 struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid);
 struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const struct server *avoid);
 
index adc903b530b76004c6870dfaf5bfc32047817406..286289ad757c28ebee7127a1599ae13f50ca9e4c 100644 (file)
@@ -3658,7 +3658,9 @@ out_uri_auth_compat:
                                init_server_map(curproxy);
                        } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
                                curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
-                               chash_init_server_tree(curproxy);
+                               if (chash_init_server_tree(curproxy) < 0) {
+                                       cfgerr++;
+                               }
                        } else {
                                curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
                                fwrr_init_server_groups(curproxy);
@@ -3678,7 +3680,9 @@ out_uri_auth_compat:
                case BE_LB_KIND_HI:
                        if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
                                curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
-                               chash_init_server_tree(curproxy);
+                               if (chash_init_server_tree(curproxy) < 0) {
+                                       cfgerr++;
+                               }
                        } else {
                                curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
                                init_server_map(curproxy);
@@ -3964,6 +3968,7 @@ out_uri_auth_compat:
                                cfgerr++;
                                continue;
                        }
+
                }
        }
 
index 709105c0e7b707744751adc747996192fa6798bf..469da71f5f6c1ba831d0a77d054b0fbdae61b144 100644 (file)
@@ -19,6 +19,7 @@
 #include <import/eb32tree.h>
 #include <haproxy/api.h>
 #include <haproxy/backend.h>
+#include <haproxy/errors.h>
 #include <haproxy/queue.h>
 #include <haproxy/server-t.h>
 #include <haproxy/tools.h>
@@ -462,8 +463,9 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid)
  * constistent hashing. The servers receive an array of initialized nodes
  * with their assigned keys. It also sets p->lbprm.wdiv to the eweight to
  * uweight ratio.
+ * Return 0 in case of success, -1 in case of allocation failure.
  */
-void chash_init_server_tree(struct proxy *p)
+int chash_init_server_tree(struct proxy *p)
 {
        struct server *srv;
        struct eb_root init_head = EB_ROOT;
@@ -495,6 +497,10 @@ void chash_init_server_tree(struct proxy *p)
                srv->lb_nodes_now = 0;
                srv->lb_nodes = calloc(srv->lb_nodes_tot,
                                       sizeof(*srv->lb_nodes));
+               if (!srv->lb_nodes) {
+                       ha_alert("failed to allocate lb_nodes for server %s.\n", srv->id);
+                       return -1;
+               }
                for (node = 0; node < srv->lb_nodes_tot; node++) {
                        srv->lb_nodes[node].server = srv;
                        srv->lb_nodes[node].node.key = full_hash(srv->puid * SRV_EWGHT_RANGE + node);
@@ -503,4 +509,5 @@ void chash_init_server_tree(struct proxy *p)
                if (srv_currently_usable(srv))
                        chash_queue_dequeue_srv(srv);
        }
+       return 0;
 }