Skip to content

Commit

Permalink
bn_nist: fix strict aliasing problem
Browse files Browse the repository at this point in the history
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 #18258)

(cherry picked from commit 8712db5)
  • Loading branch information
paulidale committed May 10, 2022
1 parent 39f7f54 commit d8a3b6e
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions crypto/bn/bn_nist.c
Expand Up @@ -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)
Expand Down

0 comments on commit d8a3b6e

Please sign in to comment.