diff options
author | Pauli <pauli@openssl.org> | 2022-05-06 09:59:26 +0300 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2022-08-17 18:44:45 +0300 |
commit | 6246649d657127a031782b29ba6132a4203260b2 (patch) | |
tree | 5383c5b7249b33d9f574562762493cc807af2669 | |
parent | d87e99df3162b2d56b8d44907fde88b67d7e3900 (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
Backport of #18258 to 1.1.1.
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18948)
-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 325dc22849..fcee38ecd1 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 &_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) |