aristanetworks / bst

A one-stop shop for process isolation
MIT License
99 stars 9 forks source link

sig: make PDEATHSIG handling non-racy #74

Closed Snaipe closed 1 year ago

Snaipe commented 1 year ago

The way we've used PDEATHSIG so far was to call it in the child immediately after fork(). This is however inherently racy, because it is absolutely possible for the parent to get SIGKILL'ed after the fork, but before the child gets to call prctl.

This fixes the race by introducing a new function, sig_setpdeathsig.

The function takes the kill signal to pass to prctl PR_SET_PDEATHSIG, as well as the expected parent pid. The way to use this function is as follows:

pid_t ppid = getpid();
pid_t pid = fork();
if (pid == -1) {
    err(1, "fork");
}
if (!pid) {
    // in the child
    sig_setpdeathsig(SIGKILL, ppid);
}

sig_setpdeathsig then takes care of calling prctl(PR_SET_PDEATHSIG, signo), and checks whether the current ppid is the same as the original ppid. If it isn't, it means the parent died and the child got reparented to the nearest subreaper, and the function calls raise(signo).