mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
swtpm-util: reap the profile listing child on failure
swtpm_find_best_profile() keeps the swtpm_setup --print-profiles child in a PidRef that is only closed on return. If the wait fails, the child is neither killed nor reaped. On a fiber this happens whenever the fiber is cancelled during the wait. Kill and reap the child in the cleanup, like other helpers that fork short lived children do. Drop the PidRef before the cleanup when the wait reports an exit status, a child killed by a signal, or a child that is already gone. Otherwise the cleanup would send SIGKILL to a PID that another process might use by now, if no pidfd was available.
This commit is contained in:
1 parent
fd39acb784
commit
6a02f8893c
1 file changed
+6
-1
@@ -43,7 +43,7 @@ static int swtpm_find_best_profile(const char *swtpm_setup, char **ret) {
|
||||
log_debug("About to spawn: %s", strnull(cmdline));
|
||||
}
|
||||
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
_cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
|
||||
r = pidref_safe_fork_full(
|
||||
"(swtpm-lprof)",
|
||||
(int[]) { -EBADF, mfd, STDERR_FILENO },
|
||||
@@ -61,6 +61,11 @@ static int swtpm_find_best_profile(const char *swtpm_setup, char **ret) {
|
||||
}
|
||||
|
||||
r = pidref_wait_for_terminate_and_check("(swtpm-lprof)", &pidref, WAIT_LOG_ABNORMAL);
|
||||
/* An exit status, -EPROTO for a child killed by a signal, and -ECHILD mean that the child is gone.
|
||||
* The cleanup must not send SIGKILL then, because without a pidfd the PID might belong to another
|
||||
* process by now. After any other failure the child is not reaped yet, and the cleanup kills it. */
|
||||
if (r >= 0 || IN_SET(r, -EPROTO, -ECHILD))
|
||||
pidref_done(&pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in new issue
Block a user