tests: ASSERT_SIGNAL: Stop exit codes from masquerading as signals

When a child process exits normally (si_code == CLD_EXITED),
siginfo.si_status contains the exit code. When it is killed by a signal
(si_code == CLD_KILLED or CLD_DUMPED), si_status contains the signal
number.  However, assert_signal_internal() returns si_status blindly.
This causes exit codes to be misinterpreted as signal numbers.

This allows failing tests to silently pass if their exit code
numerically coincides with the expected signal. For example, a test
expecting SIGABRT (6) would incorrectly pass if the child simply exited
with status 6 instead of being killed by a signal.

Fix this by checking si_code. Only return si_status as a signal number
if the child was actually killed by a signal (CLD_KILLED or CLD_DUMPED).
If the child exited normally (CLD_EXITED), return 0 to indicate that no
signal occurred.
This commit is contained in:
Chris Down
2025-11-20 02:40:07 +08:00
parent 408e8d361f
commit 39adecfcd8
2 changed files with 38 additions and 1 deletions
+9 -1
View File
@@ -446,7 +446,15 @@ int assert_signal_internal(void) {
if (r < 0)
return r;
return siginfo.si_status;
/* si_status means different things depending on si_code:
* - CLD_EXITED: si_status is the exit code
* - CLD_KILLED/CLD_DUMPED: si_status is the signal number that killed the process
* We need to return the signal number only if the child was killed by a signal. */
if (IN_SET(siginfo.si_code, CLD_KILLED, CLD_DUMPED))
return siginfo.si_status;
/* Child exited normally, return 0 to indicate no signal was received, regardless of actual exit */
return 0;
}