]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tests: ASSERT_SIGNAL: Ensure sanitisers do not mask expected signals
authorChris Down <chris@chrisdown.name>
Wed, 19 Nov 2025 13:45:40 +0000 (21:45 +0800)
committerChris Down <chris@chrisdown.name>
Wed, 19 Nov 2025 18:40:07 +0000 (02:40 +0800)
ASAN installs signal handlers to catch crashes like SIGSEGV or SIGILL.
When these signals are raised, ASAN traps them, prints an error report,
and then typically terminates the process with a different signal (often
SIGABRT) or a non-zero exit code.

This interferes with ASSERT_SIGNAL when checking for specific crash
signals (for example, checking that a function raises SIGSEGV). In such
a case, the test harness sees the ASAN termination signal rather than
the expected signal, causing the test to fail.

Fix this by resetting the signal handler to SIG_DFL in the child process
immediately before executing the test expression. This ensures the
kernel kills the process directly with the expected signal, bypassing
ASAN's interceptors.

src/shared/tests.h

index 1605778fb6c41affcad74ed221a5c5ccaed3b567..2aced04265257dd066513febde7eadae03a9c0b9 100644 (file)
@@ -598,18 +598,19 @@ int assert_signal_internal(void);
 #  define ASSERT_SIGNAL(expr, signal) __coverity_check__(((expr), false))
 #else
 #  define ASSERT_SIGNAL(expr, signal) __ASSERT_SIGNAL(UNIQ, expr, signal)
-#  define __ASSERT_SIGNAL(uniq, expr, signal)                                                                   \
+#  define __ASSERT_SIGNAL(uniq, expr, sgnl)                                                                     \
         ({                                                                                                      \
-                ASSERT_TRUE(SIGNAL_VALID(signal));                                                              \
+                ASSERT_TRUE(SIGNAL_VALID(sgnl));                                                                \
                 int UNIQ_T(_r, uniq) = assert_signal_internal();                                                \
                 ASSERT_OK_ERRNO(UNIQ_T(_r, uniq));                                                              \
                 if (UNIQ_T(_r, uniq) == 0) {                                                                    \
+                        (void) signal(sgnl, SIG_DFL);                                                           \
                         expr;                                                                                   \
                         _exit(EXIT_SUCCESS);                                                                    \
                 }                                                                                               \
-                if (UNIQ_T(_r, uniq) != signal)                                                                 \
+                if (UNIQ_T(_r, uniq) != sgnl)                                                                   \
                         log_test_failed("\"%s\" died with signal %s, but %s was expected",                      \
-                                        #expr, signal_to_string(UNIQ_T(_r, uniq)), signal_to_string(signal));   \
+                                        #expr, signal_to_string(UNIQ_T(_r, uniq)), signal_to_string(sgnl));     \
         })
 #endif