af_unix: Fix garbage collector racing against connect()
Garbage collector does not take into account the risk of embryo getting
enqueued during the garbage collection. If such embryo has a peer that
carries SCM_RIGHTS, two consecutive passes of scan_children() may see a
different set of children. Leading to an incorrectly elevated inflight
count, and then a dangling pointer within the gc_inflight_list.
sockets are AF_UNIX/SOCK_STREAM
S is an unconnected socket
L is a listening in-flight socket bound to addr, not in fdtable
V's fd will be passed via sendmsg(), gets inflight count bumped
connect(S, addr) sendmsg(S, [V]); close(V) __unix_gc()
---------------- ------------------------- -----------
NS = unix_create1()
skb1 = sock_wmalloc(NS)
L = unix_find_other(addr)
unix_state_lock(L)
unix_peer(S) = NS
// V count=1 inflight=0
NS = unix_peer(S)
skb2 = sock_alloc()
skb_queue_tail(NS, skb2[V])
// V became in-flight
// V count=2 inflight=1
close(V)
// V count=1 inflight=1
// GC candidate condition met
for u in gc_inflight_list:
if (total_refs == inflight_refs)
add u to gc_candidates
// gc_candidates={L, V}
for u in gc_candidates:
scan_children(u, dec_inflight)
// embryo (skb1) was not
// reachable from L yet, so V's
// inflight remains unchanged
__skb_queue_tail(L, skb1)
unix_state_unlock(L)
for u in gc_candidates:
if (u.inflight)
scan_children(u, inc_inflight_move_tail)
// V count=1 inflight=2 (!)
If there is a GC-candidate listening socket, lock/unlock its state. This
makes GC wait until the end of any ongoing connect() to that socket. After
flipping the lock, a possibly SCM-laden embryo is already enqueued. And if
there is another embryo coming, it can not possibly carry SCM_RIGHTS. At
this point, unix_inflight() can not happen because unix_gc_lock is already
taken. Inflight graph remains unaffected.
Fixes: 1fd05ba5 ("[AF_UNIX]: Rewrite garbage collector, fixes race.")
Signed-off-by:
Michal Luczaj <mhal@rbox.co>
Reviewed-by:
Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20240409201047.1032217-1-mhal@rbox.co
Signed-off-by:
Paolo Abeni <pabeni@redhat.com>
-
mentioned in commit efd3913f
-
mentioned in commit 42df4f2b
-
mentioned in commit 1191dc51
-
mentioned in commit afcea7e0
-
mentioned in commit 97486fe3
-
mentioned in commit 316696f1
-
mentioned in commit a35823e8
-
mentioned in commit e8e652b8
-
mentioned in commit 65e0a92c
-
mentioned in commit 53f60c53
-
mentioned in commit 30a74bc0
-
mentioned in commit ef1bbb3d
-
mentioned in commit 91cf3086
-
mentioned in commit f86c6a0b
-
mentioned in commit 7eb7d969
-
mentioned in commit d0c6724b
-
mentioned in commit 94c88f80
-
mentioned in commit 83ff38c5
-
mentioned in commit f4eb7e17
-
mentioned in commit f15786d5
-
mentioned in commit bf8fc58f
-
mentioned in commit 4d382310
-
mentioned in commit 4f169b3f
-
mentioned in commit a4e12e86
-
mentioned in commit 264434cb
-
mentioned in commit 7c6bbcca
-
mentioned in commit 71bf445d
-
mentioned in commit 0a36a75b
-
mentioned in commit f91f368b
-
mentioned in commit 45d7a6a9
-
mentioned in commit ea688af3
-
mentioned in commit 5dba713f
-
mentioned in commit 954bf2e9
-
mentioned in commit 1c869c8f
-
mentioned in commit 32099ac2
-
mentioned in commit 891e1954
-
mentioned in commit 258ff14e
-
mentioned in commit 64038c86
-
mentioned in commit 271b09aa
-
mentioned in commit 9dc10a65
-
mentioned in commit 9e73b9b9
-
mentioned in commit 39df2333
-
mentioned in commit eae51347
-
mentioned in commit d98b2c0b
-
mentioned in commit 85dc8d26
-
mentioned in commit 24d246e7
-
mentioned in commit 3c85bd75
-
mentioned in commit 0b74a3b0
-
mentioned in commit 45cd4bfb
-
mentioned in commit d2859556
-
mentioned in commit 31fbf01d
-
mentioned in commit 7babde13
-
mentioned in commit 86692040
-
mentioned in commit 3a18a6ce
-
mentioned in commit 647852b1
-
mentioned in commit c5a821b9
-
mentioned in commit 897b4b44
-
mentioned in commit eb5cd3fd
-
mentioned in commit 40171642
-
mentioned in commit 70e489f3
-
mentioned in commit 4dd72e5c
-
mentioned in commit f30aff55
-
mentioned in commit fa9bf099
-
mentioned in commit 4bdb5943
-
mentioned in commit 346adc2a
-
mentioned in commit 903a9818
-
mentioned in commit 6302e1be
-
mentioned in commit a316800e
-
mentioned in commit a1a65323
-
mentioned in commit 05d2945c
-
mentioned in commit 68b07e0c
-
mentioned in commit 260cf320
-
mentioned in commit 3ae6c70a
-
mentioned in commit 05e7c0ef
-
mentioned in commit 2b5351e5
-
mentioned in commit d5129e92
-
mentioned in commit badc4dde
-
mentioned in commit d9f595d2
-
mentioned in commit fc203c3d
-
mentioned in commit 89ed4a22