This diff fixes panic tripped by KASSERT(st->sync_state == PFSYNC_S_NONE)
authorsashan <sashan@openbsd.org>
Tue, 8 Nov 2022 16:20:26 +0000 (16:20 +0000)
committersashan <sashan@openbsd.org>
Tue, 8 Nov 2022 16:20:26 +0000 (16:20 +0000)
commit5f17b30aee8b388e13101395f1f026cb3b5be4a6
treeaff25eef10b73dc388f2889284e23b964073267e
parent56904c79f7bc7e2f3f398f85d12182cec2dd7114
This diff fixes panic tripped by KASSERT(st->sync_state == PFSYNC_S_NONE)
found in pfsync_insert_state(). It is caused by two packets which happen
to belong to the same session. Think of UDP stream or two TCP SYN packets
transmitted almost simultaneously. The first such packet wins a state lock
and inserts state to table. The second packet waits for state lock
as a reader. As soon as the first packet is done with state creation
it drops the lock and is going to sent S_INS message to its peer via
pfsync. The second update meanwhile obtains the state lock as a reader.
It finds a state created by the first packet. Later the second packet
also finds out the state needs to be updated, because sync_state
is still set to PFSYNC_S_NONE. The second packet puts state to snapshot
list marking it as S_UPD. All this happens before the first packet has
a chance to make a progress. Think of the first packet loses cpu after
dropping a write lock. Once the first packet gets running again it
trips KASSERT() because sync_state is set to S_UPD.

tested by hrvoje@

OK dlg@
sys/net/pf.c