Page MenuHomeFreeBSD

setitimer: Fix exit race
ClosedPublic

Authored by markj on Mar 21 2022, 5:52 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Nov 14, 3:08 PM
Unknown Object (File)
Sun, Nov 10, 9:54 PM
Unknown Object (File)
Wed, Nov 6, 12:28 PM
Unknown Object (File)
Sep 18 2024, 8:56 AM
Unknown Object (File)
Sep 9 2024, 9:08 PM
Unknown Object (File)
Sep 4 2024, 1:57 PM
Unknown Object (File)
Sep 4 2024, 1:04 PM
Unknown Object (File)
Aug 28 2024, 5:12 PM
Subscribers

Details

Summary

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.

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: pho

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

markj requested review of this revision.Mar 21 2022, 5:52 PM

Thanks for understanding that! I scratched my head a lot around it. ler@'s panics were definitely attributed to CS_EXECUTING, since it is the only place in kernel where the flag is used and the callout(9) proved to be stable in the last years.

This revision was not accepted when it landed; it landed in state Needs Review.Mar 23 2022, 4:47 PM
This revision was automatically updated to reflect the committed changes.