]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Fix a race between kern_setitimer() and realitexpire(), where the
authorkib <kib@FreeBSD.org>
Tue, 4 Dec 2012 20:49:39 +0000 (20:49 +0000)
committerkib <kib@FreeBSD.org>
Tue, 4 Dec 2012 20:49:39 +0000 (20:49 +0000)
commit54d4ef7790ac3f2922675f0defbaf3b2f5a54d7a
treebe5ca68461521c9d13f018cf6445647db4335cf1
parentf366a4aadf28f389a29d65d4ae42b4e84bc63720
Fix a race between kern_setitimer() and realitexpire(), where the
callout is started before kern_setitimer() acquires process mutex, but
looses a race and kern_setitimer() gets the process mutex before the
callout.  Then, assuming that new specified struct itimerval has
it_interval zero, but it_value non-zero, the callout, after it starts
executing again, clears p->p_realtimer.it_value, but kern_setitimer()
already rescheduled the callout.

As the result of the race, both p_realtimer is zero, and the callout
is rescheduled. Then, in the exit1(), the exit code sees that it_value
is zero and does not even try to stop the callout. This allows the
struct proc to be reused and eventually the armed callout is
re-initialized.  The consequence is the corrupted callwheel tailq.

Use process mutex to interlock the callout start, which fixes the race.

Reported and tested by: pho
Reviewed by: jhb
MFC after: 2 weeks
sys/kern/init_main.c
sys/kern/kern_fork.c
sys/kern/kern_time.c