Commit e7608cf6cc for openssl.org
commit e7608cf6cc188fbee3e26ad9648564e39fb51c84
Author: 609bob <1850029304@qq.com>
Date: Wed Oct 28 20:04:35 2026 +0800
providers/implementations/kdfs/argon2.c: fix memory leak in argon2_derive()
This also requires a more carefule thread handling
in fill_mem_blocks_mt(), that avoids returning on error before joining
all the outstanding threads.
Fixes: 6dfa998f7ea1 "providers: add Argon2 KDF"
Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Merge-date: Wed Nov 11 09:24:25 2026
Merged-from: https://github.com/openssl/openssl/pull/33434
diff --git a/providers/implementations/kdfs/argon2.c b/providers/implementations/kdfs/argon2.c
index b988aa212f..61fdde9f52 100644
--- a/providers/implementations/kdfs/argon2.c
+++ b/providers/implementations/kdfs/argon2.c
@@ -574,11 +574,12 @@ static int fill_mem_blocks_mt(KDF_ARGON2 *ctx)
for (l = 0; l < ctx->lanes; ++l) {
ARGON2_POS p;
if (l >= ctx->threads) {
- if (ossl_crypto_thread_join(t[l - ctx->threads], NULL) == 0)
+ void *thr = t[l - ctx->threads];
+ if (ossl_crypto_thread_join(thr, NULL) == 0)
goto fail;
- if (ossl_crypto_thread_clean(t[l - ctx->threads]) == 0)
+ t[l - ctx->threads] = NULL;
+ if (ossl_crypto_thread_clean(thr) == 0)
goto fail;
- t[l] = NULL;
}
p.pass = r;
@@ -591,22 +592,16 @@ static int fill_mem_blocks_mt(KDF_ARGON2 *ctx)
t[l] = ossl_crypto_thread_start(ctx->libctx, &fill_segment_thr,
(void *)&t_data[l]);
if (t[l] == NULL) {
- for (ll = 0; ll < l; ++ll) {
- if (ossl_crypto_thread_join(t[ll], NULL) == 0)
- goto fail;
- if (ossl_crypto_thread_clean(t[ll]) == 0)
- goto fail;
- t[ll] = NULL;
- }
goto fail;
}
}
for (l = ctx->lanes - ctx->threads; l < ctx->lanes; ++l) {
- if (ossl_crypto_thread_join(t[l], NULL) == 0)
- goto fail;
- if (ossl_crypto_thread_clean(t[l]) == 0)
+ void *thr = t[l];
+ if (ossl_crypto_thread_join(thr, NULL) == 0)
goto fail;
t[l] = NULL;
+ if (ossl_crypto_thread_clean(thr) == 0)
+ goto fail;
}
}
}
@@ -617,10 +612,18 @@ static int fill_mem_blocks_mt(KDF_ARGON2 *ctx)
return 1;
fail:
- if (t_data != NULL)
- OPENSSL_free(t_data);
- if (t != NULL)
- OPENSSL_free(t);
+ if (t != NULL) {
+ for (ll = 0; ll < ctx->lanes; ++ll) {
+ if (t[ll] == NULL)
+ continue;
+ if (ossl_crypto_thread_join(t[ll], NULL) != 0)
+ (void)ossl_crypto_thread_clean(t[ll]);
+ t[ll] = NULL;
+ }
+ }
+
+ OPENSSL_free(t_data);
+ OPENSSL_free(t);
return 0;
}
@@ -1110,8 +1113,15 @@ static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
if (initialize(ctx) != 1)
return 0;
- if (fill_memory_blocks(ctx) != 1)
+ if (fill_memory_blocks(ctx) != 1) {
+ if (ctx->type != ARGON2_D)
+ OPENSSL_secure_clear_free(ctx->memory,
+ ctx->memory_blocks * sizeof(BLOCK));
+ else
+ OPENSSL_clear_free(ctx->memory,
+ ctx->memory_blocks * sizeof(BLOCK));
return 0;
+ }
finalize(ctx, out);