From 67ffb772b7488b84e37e6880290820fc54434b33 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sat, 4 Mar 2023 02:06:19 +0100 Subject: Fix memory leak on failed realloc(3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to C99 ยง7.20.3.4: If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged. Therefore, a temporary pointer must be used to ensure the original object can still be deallocated should realloc(3) return a null pointer. --- server.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'server.c') diff --git a/server.c b/server.c index d867b59..f00a37c 100644 --- a/server.c +++ b/server.c @@ -58,12 +58,17 @@ int server_client_close(struct server *const s, struct server_client *const c) { memcpy(ref, ref + 1, s->n - i); - if (!(s->c = realloc(s->c, (s->n - 1) * sizeof *s->c))) + const size_t n = s->n - 1; + struct server_client *const c = realloc(s->c, n * sizeof *s->c); + + if (!c) { fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); return -1; } + + s->c = c; } else { @@ -127,19 +132,26 @@ static struct server_client *alloc_client(struct server *const s) __func__, strerror(errno)); return NULL; } - else if (!(s->c = realloc(s->c, (s->n + 1) * sizeof *s->c))) + + const size_t n = s->n + 1; + struct server_client *const clients = realloc(s->c, n * sizeof *s->c); + + if (!clients) { - fprintf(stderr, "%s: realloc(3): %s\n", - __func__, strerror(errno)); + fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); return NULL; } - s->c[s->n] = (const struct server_client) + struct server_client *const c = &clients[s->n]; + + *c = (const struct server_client) { .fd = fd }; - return &s->c[s->n++]; + s->c = clients; + s->n = n; + return c; } void server_client_write_pending(struct server_client *const c, -- cgit v1.2.3