Page MenuHomeFreeBSD

inpcb: Close some SO_REUSEPORT_LB races
ClosedPublic

Authored by markj on Dec 10 2024, 7:10 PM.
Tags
None
Referenced Files
F107486682: D48020.id.diff
Tue, Jan 14, 9:55 PM
F107467761: D48020.diff
Tue, Jan 14, 2:45 PM
Unknown Object (File)
Sat, Jan 4, 8:52 PM
Unknown Object (File)
Fri, Jan 3, 9:11 PM
Unknown Object (File)
Fri, Dec 27, 6:22 AM
Unknown Object (File)
Fri, Dec 27, 1:08 AM
Unknown Object (File)
Tue, Dec 17, 4:02 PM
Unknown Object (File)
Dec 15 2024, 5:24 PM

Details

Summary

For a long time, the inpcb lookup path has been lockless in the common
case: we use net_epoch to synchronize lookups. However, the routines
which update lbgroups were not careful to synchronize with unlocked
lookups. I believe that in the worst case this can result in spurious
connection aborts (I have a regression test case to exercise this), but
it's hard to be certain.

Modify in_pcblbgroup* routines to synchronize with unlocked lookup:

  • When removing inpcbs from an lbgroup, do not shrink the array. The maximum number of lbgroup entries is INPCBLBGROUP_SIZMAX (256), and it doesn't seem worth the complexity to shrink the array when a socket is removed.
  • When resizing an lbgroup, do not insert it into the hash table until it is fully initialized; otherwise lookups may observe a partially constructed lbgroup.
  • When adding an inpcb to the group, increment the counter after adding the array entry, using a release store. Otherwise it's possible for lookups to observe a null array slot.
  • When looking up an entry, use a corresponding acquire load.

Sponsored by: Klara, Inc.
Sponsored by: Stormshield

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 61071
Build 57955: arc lint + arc unit