]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: tree-wide: use array_size_or_fail() in array size for allocations
authorWilly Tarreau <w@1wt.eu>
Wed, 20 May 2026 15:02:53 +0000 (17:02 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 20 May 2026 15:05:19 +0000 (17:05 +0200)
Instead of relying on malloc(n*size), we now pass array_size_or_fail(n,m)
so that it becomes possible to detect overflow. This is particularly
interesting for global settings that might be set large enough to cause
overflows on 32-bit systems for example, resulting in small values that
then cause trouble. Now the overflow will be detected at allocation time.
Around 25 locations were updated.

15 files changed:
src/cfgparse-ssl.c
src/cfgparse.c
src/cli.c
src/errors.c
src/fd.c
src/haproxy.c
src/log.c
src/resolvers.c
src/server.c
src/sock.c
src/ssl_ckch.c
src/ssl_sock.c
src/stats-file.c
src/stats.c
src/stick_table.c

index da88ecb8154e3034ae5e35c0e2272a048b5341fb..a01d1eb9bb7f7d3dd53964cc2254a0a3538add96 100644 (file)
@@ -1495,7 +1495,7 @@ static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px
                goto fail;
        }
 
-       keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(union tls_sess_key));
+       keys_ref->tlskeys = malloc(array_size_or_fail(TLS_TICKETS_NO, sizeof(union tls_sess_key)));
        if (!keys_ref->tlskeys) {
                memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
                goto fail;
index 03c78841793d7eaf072e14f7fef125b8e8756744..2e684e15d73053e6b720ca6f27f84e85948bd08b 100644 (file)
@@ -1394,7 +1394,7 @@ int parse_cfg(const struct cfgfile *cfg)
        global.cfg_curr_line = 0;
        global.cfg_curr_file = file;
 
-       if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
+       if ((thisline = malloc(array_size_or_fail(sizeof(*thisline), linesize))) == NULL) {
                ha_alert("Out of memory trying to allocate a buffer for a configuration line.\n");
                err_code = -1;
                goto err;
@@ -1442,7 +1442,7 @@ next_line:
                        char *newline;
                        int newlinesize = linesize * 2;
 
-                       newline = realloc(thisline, sizeof(*thisline) * newlinesize);
+                       newline = realloc(thisline, array_size_or_fail(sizeof(*thisline), newlinesize));
                        if (newline == NULL) {
                                ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
                                         file, linenum);
index 8210985e4166fb38b6bb0a527f5e77503416330b..eab076dde5bd1e5e5d4e5937beb7caf2f1dd5d68 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2543,7 +2543,7 @@ static int _getsocks(char **args, char *payload, struct appctx *appctx, void *pr
        /* We will send sockets MAX_SEND_FD per MAX_SEND_FD, allocate a
         * buffer big enough to store the socket information.
         */
-       tmpbuf = malloc(MAX_SEND_FD * (1 + MAXPATHLEN + 1 + IFNAMSIZ + sizeof(int)));
+       tmpbuf = malloc(array_size_or_fail(MAX_SEND_FD, (1 + MAXPATHLEN + 1 + IFNAMSIZ + sizeof(int))));
        if (tmpbuf == NULL) {
                ha_warning("Failed to allocate memory to transfer socket information\n");
                goto out;
index 98e5126062a9c05bdeeff65c9e58e95526e934cf..f71622c0a2d9d944af554a76c0bc030cb72b55e5 100644 (file)
@@ -110,7 +110,7 @@ static void usermsgs_put(const struct ist *msg)
 {
        /* Allocate the buffer if not already done. */
        if (unlikely(b_is_null(&usermsgs_buf))) {
-               usermsgs_buf.area = malloc(USER_MESSAGES_BUFSIZE * sizeof(char));
+               usermsgs_buf.area = malloc(array_size_or_fail(USER_MESSAGES_BUFSIZE, sizeof(char)));
                if (usermsgs_buf.area)
                        usermsgs_buf.size = USER_MESSAGES_BUFSIZE;
        }
index 3d7d198ab7c62d9c036770975f51468208b683cd..7b468d264f9b504712ca95e56ab3aa8b8d042853 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -1166,7 +1166,7 @@ int init_pollers()
        struct poller *bp;
 
        /* always provide an aligned fdtab */
-       if ((fdtab = ha_aligned_zalloc(64, global.maxsock * sizeof(*fdtab))) == NULL) {
+       if ((fdtab = ha_aligned_zalloc(64, array_size_or_fail(global.maxsock, sizeof(*fdtab)))) == NULL) {
                ha_alert("Not enough memory to allocate %d entries for fdtab!\n", global.maxsock);
                goto fail_tab;
        }
index ffd969d8ce30b4c6adc37b6fb4dce117d170adba..560bc1e070cd3152026352f0244dbeb589aca55c 100644 (file)
@@ -1713,7 +1713,7 @@ void haproxy_init_args(int argc, char **argv)
                                        oldpids_sig = SIGTERM; /* terminate immediately */
                                while (argc > 1 && argv[1][0] != '-') {
                                        char * endptr = NULL;
-                                       oldpids = realloc(oldpids, (nb_oldpids + 1) * sizeof(int));
+                                       oldpids = realloc(oldpids, array_size_or_fail(nb_oldpids + 1, sizeof(int)));
                                        if (!oldpids) {
                                                ha_alert("Cannot allocate old pid : out of memory.\n");
                                                exit(1);
index 570cce27fd43e6ae6cafd765627dcfe83a49b861..89318b82c3fb0b0e7f82a713002ae0e579b43a15 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1608,7 +1608,7 @@ struct logger *dup_logger(struct logger *def)
                        goto error;
        }
        if (def->lb.smp_rgs) {
-               cpy->lb.smp_rgs = malloc(sizeof(*cpy->lb.smp_rgs) * def->lb.smp_rgs_sz);
+               cpy->lb.smp_rgs = malloc(array_size_or_fail(sizeof(*cpy->lb.smp_rgs), def->lb.smp_rgs_sz));
                if (!cpy->lb.smp_rgs)
                        goto error;
                memcpy(cpy->lb.smp_rgs, def->lb.smp_rgs,
index 623e5552f43db9337a524dcc7da80b6f48c42232..07c25b2c8c7248735bba86f841de3d147c993c14 100644 (file)
@@ -3478,7 +3478,7 @@ static int parse_resolve_conf(char **errmsg, char **warnmsg)
        int duplicate_name = 0;
        int err_code = 0;
 
-       if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
+       if ((resolv_line = malloc(array_size_or_fail(sizeof(*resolv_line), LINESIZE))) == NULL) {
                memprintf(errmsg, "out of memory.\n");
                err_code |= ERR_ALERT | ERR_FATAL;
                goto resolv_out;
index ae35cc72f558dac943a57cceab61d21ee3d0af41..23b6322bf718c57acd5362a94eaf65007ed3b6bd 100644 (file)
@@ -3632,7 +3632,7 @@ int srv_postinit(struct server *srv)
 
        /* initialize idle conns lists */
        if (srv->max_idle_conns != 0) {
-               srv->curr_idle_thr = ha_aligned_zalloc(64, global.nbthread * sizeof(*srv->curr_idle_thr));
+               srv->curr_idle_thr = ha_aligned_zalloc(64, array_size_or_fail(global.nbthread, sizeof(*srv->curr_idle_thr)));
                if (!srv->curr_idle_thr) {
                        ha_alert("memory error during idle conn list init for %s/%s server\n",
                                 srv->proxy->id, srv->id);
@@ -6106,8 +6106,8 @@ static int srv_init_per_thr(struct server *srv)
 {
        int i;
 
-       srv->per_thr = ha_aligned_zalloc(64, global.nbthread * sizeof(*srv->per_thr));
-       srv->per_tgrp = ha_aligned_zalloc(64, global.nbtgroups * sizeof(*srv->per_tgrp));
+       srv->per_thr = ha_aligned_zalloc(64, array_size_or_fail(global.nbthread, sizeof(*srv->per_thr)));
+       srv->per_tgrp = ha_aligned_zalloc(64, array_size_or_fail(global.nbtgroups, sizeof(*srv->per_tgrp)));
        if (!srv->per_thr || !srv->per_tgrp)
                return -1;
 
index a828f789588378a44e7c8c9b087b17015afb48ec..df387e4e87d2e755ce597a89d92e4b937f67531f 100644 (file)
@@ -533,7 +533,7 @@ int sock_get_old_sockets(const char *unixsocket)
 
        }
        memset(&msghdr, 0, sizeof(msghdr));
-       cmsgbuf = malloc(CMSG_SPACE(sizeof(int)) * MAX_SEND_FD);
+       cmsgbuf = malloc(array_size_or_fail(CMSG_SPACE(sizeof(int)), MAX_SEND_FD));
        if (!cmsgbuf) {
                ha_warning("Failed to allocate memory to send sockets\n");
                goto out;
@@ -561,13 +561,13 @@ int sock_get_old_sockets(const char *unixsocket)
                goto out;
        }
 
-       tmpbuf = malloc(fd_nb * (1 + MAXPATHLEN + 1 + IFNAMSIZ + sizeof(int)));
+       tmpbuf = malloc(array_size_or_fail(fd_nb, (1 + MAXPATHLEN + 1 + IFNAMSIZ + sizeof(int))));
        if (tmpbuf == NULL) {
                ha_warning("Failed to allocate memory while receiving sockets\n");
                goto out;
        }
 
-       tmpfd = malloc(fd_nb * sizeof(int));
+       tmpfd = malloc(array_size_or_fail(fd_nb, sizeof(int)));
        if (tmpfd == NULL) {
                ha_warning("Failed to allocate memory while receiving sockets\n");
                goto out;
index e7544b5bfd603bdf4eb664f2481aceb8f26314af..d612c9d02d256236777d3e2a61f23739a509af56 100644 (file)
@@ -1099,7 +1099,7 @@ struct ckch_store *ckchs_dup(const struct ckch_store *src)
                /* copy the array of domain strings */
 
                while (src->conf.acme.domains[n]) {
-                       r = my_realloc2(r, sizeof(char *) * (n + 2));
+                       r = my_realloc2(r, array_size_or_fail(sizeof(char *), (n + 2)));
                        if (!r)
                                goto error;
 
@@ -1120,7 +1120,7 @@ struct ckch_store *ckchs_dup(const struct ckch_store *src)
                /* copy the array of IP strings */
 
                while (src->conf.acme.ips[n]) {
-                       r = my_realloc2(r, sizeof(char *) * (n + 2));
+                       r = my_realloc2(r, array_size_or_fail(sizeof(char *), (n + 2)));
                        if (!r)
                                goto error;
 
@@ -5329,7 +5329,7 @@ int ckch_conf_parse(char **args, int cur_arg, struct ckch_conf *f, int *found, c
                                do {
                                        while (*e != ',' && *e != '\0')
                                                e++;
-                                       r = my_realloc2(r, sizeof(char *) * (n + 2));
+                                       r = my_realloc2(r, array_size_or_fail(sizeof(char *), (n + 2)));
                                        if (!r) {
                                                ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
                                                err_code |= ERR_ALERT | ERR_ABORT;
index ee6ddfd84f50701c4f378a616e48f457c63acce2..dd1b9f6045a347d3925da67a6835eb6bc76e0182 100644 (file)
@@ -3743,7 +3743,7 @@ static void ssl_sock_resize_passphrase_cache(void)
        int idx;
        int new_size = passphrase_cache_size << 1;
 
-       passphrase_randoms = my_realloc2(passphrase_randoms, sizeof(*passphrase_randoms) * (new_size));
+       passphrase_randoms = my_realloc2(passphrase_randoms, array_size_or_fail(sizeof(*passphrase_randoms), (new_size)));
        if (!passphrase_randoms) {
                ha_alert("ssl_sock_passwd_cb: passphrase randoms realloc failed");
                passphrase_idx = -1;
@@ -3759,7 +3759,7 @@ static void ssl_sock_resize_passphrase_cache(void)
 
        if (passphrase_cache_size) {
                passphrase_cache_size = new_size;
-               passphrase_cache = my_realloc2(passphrase_cache, sizeof(*passphrase_cache) * passphrase_cache_size);
+               passphrase_cache = my_realloc2(passphrase_cache, array_size_or_fail(sizeof(*passphrase_cache), passphrase_cache_size));
                if (!passphrase_cache) {
                        ha_alert("ssl_sock_passwd_cb: passphrase cache realloc failed");
                        passphrase_idx = -1;
index 954b91ed6c349ac6b7a8cf7587eee1a08f2199ec..205b886b1849cb4c0541f44968e4854813e59748 100644 (file)
@@ -417,7 +417,7 @@ void apply_stats_file(void)
                goto out;
        }
 
-       line = malloc(sizeof(char) * LINESIZE);
+       line = malloc(array_size_or_fail(sizeof(char), LINESIZE));
        if (!line) {
                ha_warning("config: Can't load stats-file '%s': line alloc error.\n", global.stats_file);
                goto out;
index d323006f1ffc6924a6c8cfef90b26fdbdf409cb1..6843f49b457543892366acd4139a4856295ebdf7 100644 (file)
@@ -1208,7 +1208,7 @@ static int allocate_stats_px_postcheck(void)
 
        stat_cols_len[STATS_DOMAIN_PROXY] += ST_I_PX_MAX;
 
-       stat_cols[STATS_DOMAIN_PROXY] = malloc(stat_cols_len[STATS_DOMAIN_PROXY] * sizeof(struct name_desc));
+       stat_cols[STATS_DOMAIN_PROXY] = malloc(array_size_or_fail(stat_cols_len[STATS_DOMAIN_PROXY], sizeof(struct name_desc)));
        if (!stat_cols[STATS_DOMAIN_PROXY]) {
                ha_alert("stats: cannot allocate all fields for proxy statistics\n");
                err_code |= ERR_ALERT | ERR_FATAL;
@@ -1247,7 +1247,7 @@ static int allocate_stats_rslv_postcheck(void)
        size_t i = 0, offset;
        int err_code = 0;
 
-       stat_cols[STATS_DOMAIN_RESOLVERS] = malloc(stat_cols_len[STATS_DOMAIN_RESOLVERS] * sizeof(struct name_desc));
+       stat_cols[STATS_DOMAIN_RESOLVERS] = malloc(array_size_or_fail(stat_cols_len[STATS_DOMAIN_RESOLVERS], sizeof(struct name_desc)));
        if (!stat_cols[STATS_DOMAIN_RESOLVERS]) {
                ha_alert("stats: cannot allocate all fields for resolver statistics\n");
                err_code |= ERR_ALERT | ERR_FATAL;
@@ -1282,7 +1282,7 @@ static int allocate_stat_lines_per_thread(void)
        for (i = 0; i < STATS_DOMAIN_COUNT; ++i) {
                const int domain = domains[i];
 
-               stat_lines[domain] = malloc(stat_cols_len[domain] * sizeof(struct field));
+               stat_lines[domain] = malloc(array_size_or_fail(stat_cols_len[domain], sizeof(struct field)));
                if (!stat_lines[domain])
                        return 0;
        }
index 0a33a775ecc797c3be77ae4521fba195ffa06718..6bc8f172f7be1397e898ab785882775b71afab8a 100644 (file)
@@ -5978,7 +5978,7 @@ static int stkt_create_stk_ctr_pool(void)
        if (!global.tune.nb_stk_ctr)
                return 0;
 
-       pool_head_stk_ctr = create_pool("stk_ctr", sizeof(*((struct session*)0)->stkctr) * global.tune.nb_stk_ctr, MEM_F_SHARED);
+       pool_head_stk_ctr = create_pool("stk_ctr", array_size_or_fail(sizeof(*((struct session*)0)->stkctr), global.tune.nb_stk_ctr), MEM_F_SHARED);
        if (!pool_head_stk_ctr) {
                ha_alert("out of memory while creating the stick-counters pool.\n");
                return ERR_ABORT;