From: Paul Floyd Date: Sat, 11 Apr 2026 15:09:52 +0000 (+0200) Subject: FreeBSD regtest: make timing_safe more consistent X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;ds=inline;p=thirdparty%2Fvalgrind.git FreeBSD regtest: make timing_safe more consistent This test was failing on FreeeBSD 16 arm64. I don't think that it's anything that has changed, just that the test was flaky. The problem is in the MEMCMP replacement code which has a word alignment check before doing word sized comparisons. The test was comparing a string literal on the stack with an strdup'd copy. strdup should give 8/16 byte alignment for 32bit/64bit platforms. There's no guarantee for the string literal. To make this stable I've changed the literal from pointer to alignas(16) array and replaced the strdup with aligned_alloc and memcpy. I've also added asserts that the stack and heap addresses 16byte aligned. --- diff --git a/memcheck/tests/freebsd/timing_safe.c b/memcheck/tests/freebsd/timing_safe.c index abc1b42dd..0b0d20e4d 100644 --- a/memcheck/tests/freebsd/timing_safe.c +++ b/memcheck/tests/freebsd/timing_safe.c @@ -1,15 +1,18 @@ #include #include #include +#include +#include int main(void) { - char* s1 = "the the the"; - char* s2 = "the cat zat"; + alignas(16) char s1[] = "the the the"; + char s2[] = "the cat zat"; char* d1; double undef1; double undef2; int res; + assert((uintptr_t)s1%16 == 0); res = timingsafe_bcmp(s1, s2, 3); assert(res == 0); @@ -30,7 +33,9 @@ int main(void) timingsafe_bcmp(&undef1, &undef2, 8); timingsafe_memcmp(&undef1, &undef2, 8); - d1 = strdup(s1); + d1 = aligned_alloc(16, 16); + memcpy(d1, s1, strlen(s1)+1); + assert((uintptr_t)d1%16 == 0); timingsafe_bcmp(s1, d1, 13); timingsafe_memcmp(s1, d1, 13); diff --git a/memcheck/tests/freebsd/timing_safe.stderr.exp b/memcheck/tests/freebsd/timing_safe.stderr.exp index f1aa70e03..3dfaef1a6 100644 --- a/memcheck/tests/freebsd/timing_safe.stderr.exp +++ b/memcheck/tests/freebsd/timing_safe.stderr.exp @@ -1,54 +1,64 @@ Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:30) + by 0x........: main (timing_safe.c:33) Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:30) + by 0x........: main (timing_safe.c:33) Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:31) + by 0x........: main (timing_safe.c:34) Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:31) + by 0x........: main (timing_safe.c:34) -Invalid read of size 1 +Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:35) - Address 0x........ is 0 bytes after a block of size 12 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - ... - by 0x........: main (timing_safe.c:33) + by 0x........: main (timing_safe.c:40) -Invalid read of size 1 +Conditional jump or move depends on uninitialised value(s) at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...) + by 0x........: main (timing_safe.c:41) + +Invalid read of size 8 + at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...) + by 0x........: main (timing_safe.c:45) + Address 0x........ is 0 bytes inside a block of size 16 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (timing_safe.c:43) + Block was alloc'd at + at 0x........: aligned_alloc (vg_replace_malloc.c:...) by 0x........: main (timing_safe.c:36) - Address 0x........ is 0 bytes after a block of size 12 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - ... - by 0x........: main (timing_safe.c:33) Invalid read of size 1 at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:40) - Address 0x........ is 0 bytes inside a block of size 12 free'd + by 0x........: main (timing_safe.c:45) + Address 0x........ is 8 bytes inside a block of size 16 free'd at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (timing_safe.c:38) + by 0x........: main (timing_safe.c:43) Block was alloc'd at - at 0x........: malloc (vg_replace_malloc.c:...) - ... - by 0x........: main (timing_safe.c:33) + at 0x........: aligned_alloc (vg_replace_malloc.c:...) + by 0x........: main (timing_safe.c:36) + +Invalid read of size 8 + at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...) + by 0x........: main (timing_safe.c:46) + Address 0x........ is 0 bytes inside a block of size 16 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (timing_safe.c:43) + Block was alloc'd at + at 0x........: aligned_alloc (vg_replace_malloc.c:...) + by 0x........: main (timing_safe.c:36) Invalid read of size 1 at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...) - by 0x........: main (timing_safe.c:41) - Address 0x........ is 0 bytes inside a block of size 12 free'd + by 0x........: main (timing_safe.c:46) + Address 0x........ is 8 bytes inside a block of size 16 free'd at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (timing_safe.c:38) + by 0x........: main (timing_safe.c:43) Block was alloc'd at - at 0x........: malloc (vg_replace_malloc.c:...) - ... - by 0x........: main (timing_safe.c:33) + at 0x........: aligned_alloc (vg_replace_malloc.c:...) + by 0x........: main (timing_safe.c:36)