From 1252a4710e638965783343a14772659790a6b0d8 Mon Sep 17 00:00:00 2001
From: SChernykh <sergey.v.chernykh@gmail.com>
Date: Tue, 23 May 2023 14:37:09 +0200
Subject: [PATCH] RandomX: fixed undefined behavior

Using an inactive member of a `union` is an undefined behavior in C++
---
 src/crypto/randomx/aes_hash.cpp | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/crypto/randomx/aes_hash.cpp b/src/crypto/randomx/aes_hash.cpp
index 8401d2c86..38eb4d645 100644
--- a/src/crypto/randomx/aes_hash.cpp
+++ b/src/crypto/randomx/aes_hash.cpp
@@ -167,16 +167,8 @@ void fillAes1Rx4(void *state, size_t outputSize, void *buffer) {
 template void fillAes1Rx4<true>(void *state, size_t outputSize, void *buffer);
 template void fillAes1Rx4<false>(void *state, size_t outputSize, void *buffer);
 
-static const rx_vec_i128 inst_mask = []() {
-	constexpr randomx::Instruction inst{ 0xFF, randomx::RegistersCount - 1, randomx::RegistersCount - 1, 0xFF, 0xFFFFFFFFU };
-
-	union {
-		randomx::Instruction mask[2];
-		rx_vec_i128 vec;
-	} result = { inst, inst };
-
-	return result.vec;
-}();
+static constexpr randomx::Instruction inst{ 0xFF, 7, 7, 0xFF, 0xFFFFFFFFU };
+alignas(16) static const randomx::Instruction inst_mask[2] = { inst, inst };
 
 template<int softAes>
 void fillAes4Rx4(void *state, size_t outputSize, void *buffer) {
@@ -227,7 +219,8 @@ void fillAes4Rx4(void *state, size_t outputSize, void *buffer) {
 		rx_store_vec_i128((rx_vec_i128*)outptr + 3, state3);
 	}
 
-	const rx_vec_i128 mask = inst_mask;
+	static_assert(sizeof(inst_mask) == sizeof(rx_vec_i128), "Incorrect inst_mask size");
+	const rx_vec_i128 mask = *reinterpret_cast<const rx_vec_i128*>(inst_mask);
 
 	while (outptr < outputEnd) {
 		TRANSFORM;