Chris Down 0b7dfc036d tests: ASSERT_SIGNAL: Prevent hallucinating parent as child and confusing exit codes with signals (#39807)
This series fixes two distinct, pretty bad bugs in `ASSERT_SIGNAL`.
These bugs can allow failing tests to pass, and can also cause the test
runner to silently terminate prematurely in a way that looks like
success.

This is not theoretical, see
https://github.com/systemd/systemd/pull/39674#discussion_r2540552699 for
a real case of this happening.

---

Bug 1: Parent process hallucinates it is the child and re-executes the
expression being tested

Previously, assert_signal_internal() returned 0 in two mutually
exclusive states:

1. We are the child process (immediately after fork()).
2. We are the parent process, and the child exited normally (status 0).

The macro failed to distinguish these cases. If a child failed to crash
as expected, the parent received 0, incorrectly interpreted it as it
being the child, and re-executed the test expression inside the parent
process.

This can cause tests to falsely pass. The parent would successfully run
the expression (which wasn't supposed to crash in the parent), succeed,
and call _exit(EXIT_SUCCESS).

The second consequence is silent truncation. When the parent called
_exit(), it terminated the entire test runner immediately. Any
subsequent tests in the same binary were never executed.

---

Bug 2: Conflation of exit codes and signals

The harness returned the raw si_status without checking si_code. This
meant that an exit code was indistinguishable from a signal number. For
example, if a child process failed and called exit(6), the harness
reported it as having been killed by SIGABRT (signal 6).

---

This PR both fixes the bugs and reworks the ASSERT_SIGNAL infrastructure
to ensure this is very unlikely to regress:

- assert_signal_internal now returns an explicit control flow enum
(FORK_CHILD / FORK_PARENT) separate from the status data. This makes it
structurally impossible for the parent to hallucinate that it is the
child.
- The output parameter is only populated with a signal number if si_code
confirms the process was killed by a signal. Normal exits return 0.
2025-11-20 03:52:02 +08:00
2025-11-18 10:09:19 +00:00
2025-10-07 13:00:12 +01:00
2025-03-07 17:27:20 +01:00
2025-11-17 08:58:51 +00:00
2025-10-20 11:39:25 +01:00
2025-09-17 12:08:03 +02:00
2025-06-05 14:39:20 +02:00
2025-10-07 13:00:12 +01:00
2025-11-17 18:36:12 +00:00
2025-11-18 13:00:24 +00:00
2025-11-09 04:53:46 +09:00
2025-05-22 01:37:05 +09:00
2025-07-10 18:09:17 +02:00

Systemd

System and Service Manager

OBS Packages Status
Semaphore CI 2.0 Build Status
Coverity Scan Status
OSS-Fuzz Status
CIFuzz
CII Best Practices
Fossies codespell report
Translation status
Coverage Status
Packaging status
OpenSSF Scorecard

Details

Most documentation is available on systemd's web site.

Assorted, older, general information about systemd can be found in the systemd Wiki.

Information about build requirements is provided in the README file.

Consult our NEWS file for information about what's new in the most recent systemd versions.

Please see the Code Map for information about this repository's layout and content.

Please see the Hacking guide for information on how to hack on systemd and test your modifications.

Please see our Contribution Guidelines for more information about filing GitHub Issues and posting GitHub Pull Requests.

When preparing patches for systemd, please follow our Coding Style Guidelines.

If you are looking for support, please contact our mailing list, join our IRC channel #systemd on libera.chat or Matrix channel

Stable branches with backported patches are available in the stable repo.

We have a security bug bounty program sponsored by the Sovereign Tech Fund hosted on YesWeHack

Repositories with distribution packages built from git main are available on OBS

Description
No description provided
Readme Cite this repository 321 MiB
Languages
C 89%
Python 5.1%
Shell 4.5%
Meson 1.2%