From d8a3b6edcb83abda46aea30d074aa2b7c81794e7 Mon Sep 17 00:00:00 2001 From: Pauli Date: Fri, 6 May 2022 16:59:26 +1000 Subject: [PATCH] bn_nist: fix strict aliasing problem As of clang-14 the strict aliasing is causing code to magically disappear. By explicitly inlining the code, the aliasing problem evaporates. Fixes #18225 Reviewed-by: Tomas Mraz Reviewed-by: Tim Hudson Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/18258) (cherry picked from commit 8712db5e4e0c508de10e887aebf639384dc20710) --- crypto/bn/bn_nist.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index aea8a6e65d994..5b6d4e7e4dff1 100644 --- a/crypto/bn/bn_nist.c +++ b/crypto/bn/bn_nist.c @@ -249,17 +249,28 @@ const BIGNUM *BN_get0_nist_prime_521(void) return &ossl_bignum_nist_p_521; } -static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max) -{ - int i; - -#ifdef BN_DEBUG - (void)ossl_assert(top <= max); -#endif - for (i = 0; i < top; i++) - dst[i] = src[i]; - for (; i < max; i++) - dst[i] = 0; +/* + * To avoid more recent compilers (specifically clang-14) from treating this + * code as a violation of the strict aliasing conditions and omiting it, this + * cannot be declared as a function. Moreover, the dst parameter cannot be + * cached in a local since this no longer references the union and again falls + * foul of the strict aliasing criteria. Refer to #18225 for the initial + * diagnostics and llvm/llvm-project#55255 for the later discussions with the + * LLVM developers. The problem boils down to if an array in the union is + * converted to a pointer or if it is used directly. + * + * This function was inlined regardless, so there is no space cost to be + * paid for making it a macro. + */ +#define nist_cp_bn_0(dst, src_in, top, max) \ +{ \ + int ii; \ + const BN_ULONG *src = src_in; \ + \ + for (ii = 0; ii < top; ii++) \ + (dst)[ii] = src[ii]; \ + for (; ii < max; ii++) \ + (dst)[ii] = 0; \ } static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)