From 6bc4dd9b7bd437c878cbfa2ed3d15af8c3e7fd69 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sun, 3 May 2026 22:19:24 +0200 Subject: [PATCH] fix UBSanitizer issue: load of misaligned address for type LTC_FAST_TYPE (replacing LTC_FAST_TYPE_PTR_CAST approach) --- src/headers/tomcrypt_cfg.h | 8 ++++---- src/headers/tomcrypt_private.h | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index 793f401d..14d48409 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -261,16 +261,16 @@ typedef unsigned long ltc_mp_digit; #define LTC_NO_SHA256_X86 #endif -/* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */ -#if defined(LTC_NO_FAST) || (__GNUC__ < 4) || defined(__STRICT_ANSI__) +/* No LTC_FAST if explicitly disabled */ +#if defined(LTC_NO_FAST) #undef LTC_FAST #endif #ifdef LTC_FAST #ifdef ENDIAN_64BITWORD - typedef ulong64 __attribute__((__may_alias__)) LTC_FAST_TYPE; + typedef ulong64 LTC_FAST_TYPE; #else - typedef ulong32 __attribute__((__may_alias__)) LTC_FAST_TYPE; + typedef ulong32 LTC_FAST_TYPE; #endif #define LTC_FAST_XOR3(dst, src1, src2) \ do { \ diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index c81b97b4..3d3921d4 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -47,6 +47,43 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*) #define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) +#ifdef LTC_FAST +/* The LTC_FAST helpers operate on byte buffers that are not guaranteed to be aligned for LTC_FAST_TYPE. + Use memcpy for loads/stores to avoid undefined behavior from unaligned or aliasing-unsafe typed-pointer dereferences. + On GCC/Clang prefer __builtin_memcpy: it is guaranteed to be inlined for constant sizes regardless of any + user override of XMEMCPY (e.g. embedded builds). Other compilers fall back to XMEMCPY. +*/ +static LTC_INLINE LTC_FAST_TYPE LTC_FAST_LOAD(const void *p) +{ + LTC_FAST_TYPE v; +#if defined(__GNUC__) + __builtin_memcpy(&v, p, sizeof(v)); +#else + XMEMCPY(&v, p, sizeof(v)); +#endif + return v; +} + +static LTC_INLINE void LTC_FAST_STORE(void *p, LTC_FAST_TYPE v) +{ +#if defined(__GNUC__) + __builtin_memcpy(p, &v, sizeof(v)); +#else + XMEMCPY(p, &v, sizeof(v)); +#endif +} + +static LTC_INLINE void LTC_FAST_XOR2(void *dst, const void *src) +{ + LTC_FAST_STORE(dst, LTC_FAST_LOAD(dst) ^ LTC_FAST_LOAD(src)); +} + +static LTC_INLINE void LTC_FAST_XOR3(void *dst, const void *src1, const void *src2) +{ + LTC_FAST_STORE(dst, LTC_FAST_LOAD(src1) ^ LTC_FAST_LOAD(src2)); +} +#endif + /* * Internal Enums */