setitimer: Fix exit race
We use the p_itcallout callout, interlocked by the proc lock, to schedule timeouts for the setitimer(2) system call. When a process exits, the callout must be stopped before the process struct is recycled. Currently we attempt to stop the callout in exit1() with the call _callout_stop_safe(&p->p_itcallout, CS_EXECUTING). If this call returns 0, then we sleep in order to drain the callout. However, this happens only if the callout is not scheduled at all. If the callout thread is blocked on the proc lock, then exit1() will not block and the callout may execute after the process has fully exited, typically resulting in a panic. I cannot see a reason to use the CS_EXECUTING flag here. Instead, use the regular callout_stop()/callout_drain() dance to halt the callout. Reported by: ler Tested by: ler, pho MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34625
This commit is contained in:
parent
0e5c72c3cc
commit
b319171861
@ -369,15 +369,14 @@ exit1(struct thread *td, int rval, int signo)
|
||||
* executing, prevent it from rearming itself and let it finish.
|
||||
*/
|
||||
if (timevalisset(&p->p_realtimer.it_value) &&
|
||||
_callout_stop_safe(&p->p_itcallout, CS_EXECUTING, NULL) == 0) {
|
||||
callout_stop(&p->p_itcallout) == 0) {
|
||||
timevalclear(&p->p_realtimer.it_interval);
|
||||
msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0);
|
||||
KASSERT(!timevalisset(&p->p_realtimer.it_value),
|
||||
("realtime timer is still armed"));
|
||||
PROC_UNLOCK(p);
|
||||
callout_drain(&p->p_itcallout);
|
||||
} else {
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
if (p->p_sysent->sv_onexit != NULL)
|
||||
p->p_sysent->sv_onexit(p);
|
||||
seltdfini(td);
|
||||
|
@ -950,8 +950,6 @@ realitexpire(void *arg)
|
||||
kern_psignal(p, SIGALRM);
|
||||
if (!timevalisset(&p->p_realtimer.it_interval)) {
|
||||
timevalclear(&p->p_realtimer.it_value);
|
||||
if (p->p_flag & P_WEXIT)
|
||||
wakeup(&p->p_itcallout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user