]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
redis: fix memory leaks
authorDaniel Salzman <daniel.salzman@nic.cz>
Wed, 12 Nov 2025 16:21:39 +0000 (17:21 +0100)
committerDaniel Salzman <daniel.salzman@nic.cz>
Wed, 26 Nov 2025 14:49:47 +0000 (15:49 +0100)
src/knot/common/hiredis.c

index 37cfcd3290b8ffd859e8c466d6e28859e3b20b3e..631fe2533dd68a473762ae113ff6230f1bc579be 100644 (file)
@@ -37,18 +37,6 @@ redisContextFuncs redisContextGnuTLSFuncs = {
        .write = knot_redis_tls_write
 };
 
-static void ctx_deinit(redis_tls_ctx_t *ctx)
-{
-       if (ctx != NULL) {
-               if (ctx->tls != NULL) {
-                       knot_creds_free(ctx->tls->creds);
-                       knot_tls_ctx_free(ctx->tls);
-               }
-               knot_creds_free(ctx->local_creds);
-               hi_free(ctx);
-       }
-}
-
 static void knot_redis_tls_close(redisContext *ctx)
 {
        redis_tls_ctx_t *tls_ctx = ctx->privctx;
@@ -61,7 +49,15 @@ static void knot_redis_tls_close(redisContext *ctx)
 
 static void knot_redis_tls_free(void *privctx)
 {
-       ctx_deinit((redis_tls_ctx_t *)privctx);
+       redis_tls_ctx_t *tls_ctx = privctx;
+       if (tls_ctx != NULL) {
+               if (tls_ctx->tls != NULL) {
+                       knot_creds_free(tls_ctx->tls->creds);
+                       knot_tls_ctx_free(tls_ctx->tls);
+               }
+               knot_creds_free(tls_ctx->local_creds);
+               hi_free(tls_ctx);
+       }
 }
 
 static ssize_t knot_redis_tls_read(struct redisContext *ctx, char *buff, size_t size)
@@ -103,17 +99,21 @@ static int hiredis_attach_gnutls(redisContext *ctx, struct knot_creds *local_cre
 
        privctx->tls = knot_tls_ctx_new(creds, 5000, 2000, KNOT_TLS_CLIENT);
        if (privctx->tls == NULL) {
-               ctx_deinit(privctx);
+               hi_free(privctx);
                return KNOT_EINVAL;
        }
 
        privctx->conn = knot_tls_conn_new(privctx->tls, ctx->fd);
        if (privctx->conn == NULL) {
-               ctx_deinit(privctx);
+               knot_tls_ctx_free(privctx->tls);
+               hi_free(privctx);
                return KNOT_ECONN;
        }
 
        if (knot_tls_handshake(privctx->conn, true) != KNOT_EOK) {
+               knot_tls_conn_del(privctx->conn);
+               knot_tls_ctx_free(privctx->tls);
+               hi_free(privctx);
                return KNOT_ECONN;
        }
 
@@ -138,6 +138,7 @@ static redisContext *connect_addr(conf_t *conf, const char *addr_str, int port)
                log_debug("rdb, failed to connect, remote %s%s%.0u (%s)",
                          addr_str, (port != 0 ? "@" : ""), port,
                          (rdb != NULL ? rdb->errstr : "no reply"));
+               redisFree(rdb);
                return NULL;
        }
 
@@ -347,10 +348,14 @@ redisContext *rdb_connect(conf_t *conf, bool require_master)
                } else if (role == 1 && !require_master) { // Replica
                        goto connected;
                } else if (role == 2) { // Sentinel
-                       if (get_master(rdb, addr_str, sizeof(addr_str), &port) == KNOT_EOK &&
+                       int ret = get_master(rdb, addr_str, sizeof(addr_str), &port);
+                       redisFree(rdb);
+                       if (ret == KNOT_EOK &&
                            (rdb = connect_addr(conf, addr_str, port)) != NULL) {
                                goto connected;
                        }
+               } else {
+                       redisFree(rdb);
                }
 
                conf_val_next(&db_listen);