From 84728d4e01338c266b1581b6f3919df608bfac00 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 16 Aug 2024 14:13:12 +0100 Subject: [PATCH] tests: Move alternate stack onto the heap rather than the main stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And size it to `sysconf (_SC_MINSIGSTKSZ)`, if defined. This might fix the sigaltstack test on muslc, as suggested by Markus Wichmann (https://www.openwall.com/lists/musl/2024/05/30/2) and Rich Felker (https://www.openwall.com/lists/musl/2024/05/29/7) on the musl mailing list. The thinking is that the CI machine might have a huge register file (AVX512 or some other large extension) which doesn’t fit in `MINSIGSTKSZ`. By sizing the alternate stack to `sysconf (_SC_MINSIGSTKSZ)` we should be able to avoid that. Moving it onto the heap should avoid any potential complications or bugs from having one stack embedded within another. Signed-off-by: Philip Withnall Fixes: #3315 --- glib/tests/unix.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/glib/tests/unix.c b/glib/tests/unix.c index c51963104..d3ef5148b 100644 --- a/glib/tests/unix.c +++ b/glib/tests/unix.c @@ -588,14 +588,27 @@ test_signal_alternate_stack (int signal) #ifndef SA_ONSTACK g_test_skip ("alternate stack is not supported"); #else - guint8 stack_memory[MINSIGSTKSZ]; - guint8 zero_mem[MINSIGSTKSZ]; - stack_t stack = { .ss_sp = stack_memory, .ss_size = MINSIGSTKSZ }; + size_t minsigstksz = MINSIGSTKSZ; + guint8 *stack_memory = NULL; + guint8 *zero_mem = NULL; + stack_t stack = { 0 }; stack_t old_stack = { 0 }; - memset (stack_memory, 0, MINSIGSTKSZ); - memset (zero_mem, 0, MINSIGSTKSZ); - g_assert_cmpmem (stack_memory, MINSIGSTKSZ, zero_mem, MINSIGSTKSZ); +#ifdef _SC_MINSIGSTKSZ + /* Use the kernel-provided minimum stack size, if available. Otherwise default + * to MINSIGSTKSZ. Unfortunately that might not be big enough for huge + * register files for big CPU instruction set extensions. */ + minsigstksz = sysconf (_SC_MINSIGSTKSZ); + if (minsigstksz == (size_t) -1 || minsigstksz < (size_t) MINSIGSTKSZ) + minsigstksz = MINSIGSTKSZ; +#endif + + stack_memory = g_malloc0 (minsigstksz); + zero_mem = g_malloc0 (minsigstksz); + g_assert_cmpmem (stack_memory, minsigstksz, zero_mem, minsigstksz); + + stack.ss_sp = stack_memory; + stack.ss_size = minsigstksz; g_assert_no_errno (sigaltstack (&stack, &old_stack)); @@ -620,6 +633,10 @@ test_signal_alternate_stack (int signal) stack.ss_flags = SS_DISABLE; g_assert_no_errno (sigaltstack (&stack, &old_stack)); + + g_free (zero_mem); + g_free (stack_memory); + return; } #endif @@ -627,20 +644,23 @@ test_signal_alternate_stack (int signal) /* Very stupid check to ensure that the alternate stack is used instead of * the default one. This test would fail if SA_ONSTACK wouldn't be set. */ - g_assert_cmpint (memcmp (stack_memory, zero_mem, MINSIGSTKSZ), !=, 0); + g_assert_cmpint (memcmp (stack_memory, zero_mem, minsigstksz), !=, 0); /* We need to memset again zero_mem since compiler may have optimized it out * as we've seen in freebsd CI. */ - memset (zero_mem, 0, MINSIGSTKSZ); - memset (stack_memory, 0, MINSIGSTKSZ); - g_assert_cmpmem (stack_memory, MINSIGSTKSZ, zero_mem, MINSIGSTKSZ); + memset (zero_mem, 0, minsigstksz); + memset (stack_memory, 0, minsigstksz); + g_assert_cmpmem (stack_memory, minsigstksz, zero_mem, minsigstksz); stack.ss_flags = SS_DISABLE; g_assert_no_errno (sigaltstack (&stack, &old_stack)); test_signal (signal); - g_assert_cmpmem (stack_memory, MINSIGSTKSZ, zero_mem, MINSIGSTKSZ); + g_assert_cmpmem (stack_memory, minsigstksz, zero_mem, minsigstksz); + + g_free (zero_mem); + g_free (stack_memory); #endif }