diff options
author | Pauli <pauli@openssl.org> | 2022-05-06 16:59:26 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2022-05-10 19:38:42 +1000 |
commit | 8712db5e4e0c508de10e887aebf639384dc20710 (patch) | |
tree | 052caa20dc711107ef5912b458817c2cf920ac78 /crypto | |
parent | 1c8787d5e0b01bedfc3cbe5eab5b85290221d8c1 (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)
Diffstat (limited to 'crypto')
-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) |