diff options
author | Pauli <pauli@openssl.org> | 2022-05-06 16:59:26 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2022-05-10 19:39:21 +1000 |
commit | d8a3b6edcb83abda46aea30d074aa2b7c81794e7 (patch) | |
tree | 93955c6c6a11a854f1b257fb7381ced60e70aeb9 /crypto/bn | |
parent | 39f7f543738f954c9a7c0ef554e32563e241bcb9 (diff) |
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 <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18258)
(cherry picked from commit 8712db5e4e0c508de10e887aebf639384dc20710)
Diffstat (limited to 'crypto/bn')
-rw-r--r-- | crypto/bn/bn_nist.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index aea8a6e65d..5b6d4e7e4d 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) |