From 8fe3527f87e3b22edf1aaf0bb07092013c63c057 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Mon, 23 Mar 2026 11:26:24 -0400 Subject: [PATCH v4 1/3] Avoid Clang RISC-V auto-vectorization bug in DES Clang 20.1.2 (and possibly earlier/later versions) miscompiles scatter-write patterns like "array[perm[i]] = i" when compiling with -O2. This causes incorrect DES permutation tables in contrib/pgcrypto/crypt-des.c, resulting in wrong password hashes and authentication failures. Add compiler barriers (memory clobber asm statements) after scatter writes in des_init() to prevent auto-vectorization of the affected loops. The barriers are harmless on all compilers (GCC, Clang, MSVC) and have negligible performance impact since DES initialization occurs only once per connection. The fix applies to all compilers to ensure consistent behavior and avoid future compiler bugs with similar optimizations. --- contrib/pgcrypto/crypt-des.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c index 98c30ea122e..0a698da7132 100644 --- a/contrib/pgcrypto/crypt-des.c +++ b/contrib/pgcrypto/crypt-des.c @@ -62,12 +62,14 @@ #include "postgres.h" #include "miscadmin.h" +#include "port/atomics.h" #include "port/pg_bswap.h" #include "px-crypt.h" #define _PASSWORD_EFMT1 '_' + static const char _crypt_a64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -265,6 +267,10 @@ des_init(void) for (i = 0; i < 64; i++) { init_perm[final_perm[i] = IP[i] - 1] = i; + /* This prevents a Clang bug related to auto-vectorization */ +#if defined(__riscv) && defined(__clang__) + pg_memory_barrier(); +#endif inv_key_perm[i] = 255; } @@ -276,6 +282,10 @@ des_init(void) { u_key_perm[i] = key_perm[i] - 1; inv_key_perm[key_perm[i] - 1] = i; + /* This prevents a Clang bug related to auto-vectorization */ +#if defined(__riscv) && defined(__clang__) + pg_memory_barrier(); +#endif inv_comp_perm[i] = 255; } @@ -283,7 +293,13 @@ des_init(void) * Invert the key compression permutation. */ for (i = 0; i < 48; i++) + { inv_comp_perm[comp_perm[i] - 1] = i; + /* This prevents a Clang bug related to auto-vectorization */ +#if defined(__riscv) && defined(__clang__) + pg_memory_barrier(); +#endif + } /* * Set up the OR-mask arrays for the initial and final permutations, and @@ -353,7 +369,13 @@ des_init(void) * the output of the S-box arrays setup above. */ for (i = 0; i < 32; i++) + { un_pbox[pbox[i] - 1] = i; + /* This prevents a Clang bug related to auto-vectorization */ +#if defined(__riscv) && defined(__clang__) + pg_memory_barrier(); +#endif + } for (b = 0; b < 4; b++) for (i = 0; i < 256; i++) -- 2.51.2