summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/getenv.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-10-02 12:03:02 +0000
committerglebius <glebius@FreeBSD.org>2012-10-02 12:03:02 +0000
commita73c365c3b7a51e662010c36af75a21348fd4284 (patch)
treeafe853480ed945ed5806733cf06f55fc929ee88f /lib/libc/stdlib/getenv.c
parent14ab314813fbcbb17b38135fc14cb2e0e351ef7e (diff)
downloadFreeBSD-src-a73c365c3b7a51e662010c36af75a21348fd4284.zip
FreeBSD-src-a73c365c3b7a51e662010c36af75a21348fd4284.tar.gz
There is a complex race in in_pcblookup_hash() and in_pcblookup_group().
Both functions need to obtain lock on the found PCB, and they can't do classic inter-lock with the PCB hash lock, due to lock order reversal. To keep the PCB stable, these functions put a reference on it and after PCB lock is acquired drop it. If the reference was the last one, this means we've raced with in_pcbfree() and the PCB is no longer valid. This approach works okay only if we are acquiring writer-lock on the PCB. In case of reader-lock, the following scenario can happen: - 2 threads locate pcb, and do in_pcbref() on it. - These 2 threads drop the inp hash lock. - Another thread comes to delete pcb via in_pcbfree(), it obtains hash lock, does in_pcbremlists(), drops hash lock, and runs in_pcbrele_wlocked(), which doesn't free the pcb due to two references on it. Then it unlocks the pcb. - 2 aforementioned threads acquire reader lock on the pcb and run in_pcbrele_rlocked(). One gets 1 from in_pcbrele_rlocked() and continues, second gets 0 and considers pcb freed, returns. - The thread that got 1 continutes working with detached pcb, which later leads to panic in the underlying protocol level. To plumb that problem an additional INPCB flag introduced - INP_FREED. We check for that flag in the in_pcbrele_rlocked() and if it is set, we pretend that that was the last reference. Discussed with: rwatson, jhb Reported by: Vladimir Medvedkin <medved rambler-co.ru>
Diffstat (limited to 'lib/libc/stdlib/getenv.c')
0 files changed, 0 insertions, 0 deletions
OpenPOWER on IntegriCloud