]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Fix a race where timeout/untimeout could cause crashes for Giant locked
authorAlfred Perlstein <alfred@FreeBSD.org>
Sat, 22 Mar 2008 07:29:45 +0000 (07:29 +0000)
committerAlfred Perlstein <alfred@FreeBSD.org>
Sat, 22 Mar 2008 07:29:45 +0000 (07:29 +0000)
commit435cdf88ea76245289e15e9b1d3136a835685c23
treeb3443ae24c0f902b2465c50508b739835c6d3931
parent20b94d8035dc461dab17c4a27382fce7ac3cea58
Fix a race where timeout/untimeout could cause crashes for Giant locked
code.

The bug:

There exists a race condition for timeout/untimeout(9) due to the
way that the softclock thread dequeues timeouts.

The softclock thread sets the c_func and c_arg of the callout to
NULL while holding the callout lock but not Giant.  It then drops
the callout lock and acquires Giant.

It is at this point where untimeout(9) on another cpu/thread could
be called.

Since c_arg and c_func are cleared, untimeout(9) does not touch the
callout and returns as if the callout is canceled.

The softclock then tries to acquire Giant and likely blocks due to
the other cpu/thread holding it.

The other cpu/thread then likely deallocates the backing store that
c_arg points to and finishes working and hence drops Giant.

Softclock resumes and acquires giant and calls the function with
the now free'd c_arg and we have corruption/crash.

The fix:

We need to track curr_callout even for timeout(9) (LOCAL_ALLOC)
callouts.  We need to free the callout after the softclock processes
it to deal with the race here.

Obtained from: Juniper Networks, iedowse
Reviewed by: jhb, iedowse
MFC After: 2 weeks.
sys/kern/kern_timeout.c