Fix the race between if_detach() and rtm_output().
authormvs <mvs@openbsd.org>
Tue, 7 Sep 2021 09:56:00 +0000 (09:56 +0000)
committermvs <mvs@openbsd.org>
Tue, 7 Sep 2021 09:56:00 +0000 (09:56 +0000)
commit40192866049d58ca33971afdcb144fab8b38563c
tree620bcbc1f2f64f7dac549cd68458783163a4599f
parentd782ea5fe9601698ce63b0b38ed741dad04d3ed3
Fix the race between if_detach() and rtm_output().

When the dying network interface descriptor has if_get(9) obtained
reference owned by foreign thread, the if_detach() thread will sleep
just after it removed this interface from the interface index map.

The data related to this interface is still in routing table, so
if_get(9) called by concurrent rtm_output() thread will return NULL and
the following "ifp != NULL" assertion will be triggered.

So remove the "ifp != NULL" assertions from rtm_output() and try to grab
`ifp' as early as possible then hold it until we finish the work. In the
case we won the race and we have `ifp' non NULL, concurrent if_detach()
thread will wait us. In the case we lost we just return ESRCH.

The problem reported by danj@.
Diff tested by danj@.

ok mpi@
sys/net/rtsock.c