Commit 74edd30c9f for openssl.org
commit 74edd30c9f6b3a583ca05fc97f296ddd0e161b78
Author: Nikola Pajkovsky <nikolap@openssl.org>
Date: Tue May 12 11:32:10 2026 +0200
stack: use free thunk when deep copy cleanup fails
internal_copy() used the generic OPENSSL_sk_freefunc directly when a deep
copy failed after copying some elements. For typed stacks, callers pass
type-specific free callbacks that have been cast to OPENSSL_sk_freefunc, so
calling them through the generic function pointer type is undefined behavior.
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
MergeDate: Wed May 20 15:53:43 2026
(Merged from https://github.com/openssl/openssl/pull/31151)
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index e797554783..bd3c6f54ef 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -47,6 +47,16 @@ OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk,
return old;
}
+static void free_with_thunk(OPENSSL_STACK *sk, OPENSSL_sk_freefunc free_func, const void *data)
+{
+ if (data == NULL)
+ return;
+ if (sk->free_thunk != NULL)
+ sk->free_thunk(free_func, (void *)data);
+ else
+ free_func((void *)data);
+}
+
static OPENSSL_STACK *internal_copy(const OPENSSL_STACK *sk,
OPENSSL_sk_copyfunc copy_func,
OPENSSL_sk_freefunc free_func)
@@ -80,8 +90,7 @@ static OPENSSL_STACK *internal_copy(const OPENSSL_STACK *sk,
continue;
if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
while (--i >= 0)
- if (ret->data[i] != NULL)
- free_func((void *)ret->data[i]);
+ free_with_thunk(ret, free_func, ret->data[i]);
goto err;
}
}
@@ -460,14 +469,9 @@ void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
if (st == NULL)
return;
- for (i = 0; i < st->num; i++) {
- if (st->data[i] != NULL) {
- if (st->free_thunk != NULL)
- st->free_thunk(func, (void *)st->data[i]);
- else
- func((void *)st->data[i]);
- }
- }
+ for (i = 0; i < st->num; i++)
+ free_with_thunk(st, func, st->data[i]);
+
OPENSSL_sk_free(st);
}