mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-28 21:07:43 +00:00
pidfd: block SIGCHLD during tmp process creation
This patch blocks SIGCHLD during temporary process creation to prevent a race condition between kill() and waitpid() where sigchld_handler() causes `criu restore` to fail with an error. Fixes: #2490 Signed-off-by: Bhavik Sachdev <b.sachdev1904@gmail.com> Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
parent
e6ce8f4054
commit
d8be857b4b
20
criu/pidfd.c
20
criu/pidfd.c
@ -145,6 +145,20 @@ static int create_tmp_process(void)
|
|||||||
static int free_dead_pidfd(struct dead_pidfd *dead)
|
static int free_dead_pidfd(struct dead_pidfd *dead)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
sigset_t blockmask, oldmask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block SIGCHLD to prevent interfering from sigchld_handler()
|
||||||
|
* and to properly handle the tmp process termination without
|
||||||
|
* a race condition. A similar approach is used in cr_system().
|
||||||
|
*/
|
||||||
|
sigemptyset(&oldmask);
|
||||||
|
sigemptyset(&blockmask);
|
||||||
|
sigaddset(&blockmask, SIGCHLD);
|
||||||
|
if (sigprocmask(SIG_BLOCK, &blockmask, &oldmask) == -1) {
|
||||||
|
pr_perror("Cannot set mask of blocked signals");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (kill(dead->pid, SIGKILL) < 0) {
|
if (kill(dead->pid, SIGKILL) < 0) {
|
||||||
pr_perror("Could not kill temporary process with pid: %d",
|
pr_perror("Could not kill temporary process with pid: %d",
|
||||||
@ -158,6 +172,12 @@ static int free_dead_pidfd(struct dead_pidfd *dead)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore the original signal mask after tmp process has terminated */
|
||||||
|
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
|
||||||
|
pr_perror("Cannot clear blocked signals");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (!WIFSIGNALED(status)) {
|
if (!WIFSIGNALED(status)) {
|
||||||
pr_err("Expected temporary process to be terminated by a signal\n");
|
pr_err("Expected temporary process to be terminated by a signal\n");
|
||||||
goto err;
|
goto err;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user