Make `so' dereference safe within pflow_output_process().
authormvs <mvs@openbsd.org>
Wed, 23 Nov 2022 15:12:27 +0000 (15:12 +0000)
committermvs <mvs@openbsd.org>
Wed, 23 Nov 2022 15:12:27 +0000 (15:12 +0000)
commitf0d16c93a43c6558e249fedb126cd7a0c7287512
tree6d9dd105bdf6636b886c35d608d0981129450257
parent2d32fa7951ab90cbb391c7602cbc52baf8dcefbf
Make `so' dereference safe within pflow_output_process().

sosend() has sleep points, so the kernel lock serialisation within
pflow_output_process() doesn't work as expected. The pflow(4) interface
associated socket `so' could be overwritten by concurrent pflowioctl()
thread.

Introduce pflow(4) interface's `sc_lock' rwlock(9) to make `so'
dereference safe. Since the solock() of udp(4) sockets uses netlock as
backend, the `sc_lock' should be taken first. This expands a little
netlock relocking within pflowioctl().

pflow_sendout_mbuf() called by pflow_output_process(), now called
without kernel lock held, so the mp safe counters_pkt(9) used instead
of manual `if_opackets' increment.

Since if_detach() does partial ifnet destruction, now it can't be called
before we finish pflow_output_process() task, otherwise we introduce use
after free for interface counters. In other hand, we need to deny
pflowioctl() to reschedule pflow_output_process() task. The `sc_dyind'
flag introduced for that.

Tested by Hrvoje Popovski.

ok bluhm@
sys/net/if_pflow.c
sys/net/if_pflow.h