This is the second attempt at achieving the same goal. This time, the submission avoids forking the current code base, ensuring it remains easier to maintain over time.
The set has been tested using the SCM_RIGHTS test suite [1] using QEMU and has been seen to successfully mitigate a UAF on on a top tier handset.
RESULTS:
TAP version 13 1..20 # Starting 20 tests from 5 test cases. # RUN scm_rights.dgram.self_ref ... # OK scm_rights.dgram.self_ref ok 1 scm_rights.dgram.self_ref # RUN scm_rights.dgram.triangle ... # OK scm_rights.dgram.triangle ok 2 scm_rights.dgram.triangle # RUN scm_rights.dgram.cross_edge ... # OK scm_rights.dgram.cross_edge ok 3 scm_rights.dgram.cross_edge # RUN scm_rights.dgram.backtrack_from_scc ... # OK scm_rights.dgram.backtrack_from_scc ok 4 scm_rights.dgram.backtrack_from_scc # RUN scm_rights.stream.self_ref ... # OK scm_rights.stream.self_ref ok 5 scm_rights.stream.self_ref # RUN scm_rights.stream.triangle ... # OK scm_rights.stream.triangle ok 6 scm_rights.stream.triangle # RUN scm_rights.stream.cross_edge ... # OK scm_rights.stream.cross_edge ok 7 scm_rights.stream.cross_edge # RUN scm_rights.stream.backtrack_from_scc ... # OK scm_rights.stream.backtrack_from_scc ok 8 scm_rights.stream.backtrack_from_scc # RUN scm_rights.stream_oob.self_ref ... # OK scm_rights.stream_oob.self_ref ok 9 scm_rights.stream_oob.self_ref # RUN scm_rights.stream_oob.triangle ... # OK scm_rights.stream_oob.triangle ok 10 scm_rights.stream_oob.triangle # RUN scm_rights.stream_oob.cross_edge ... # OK scm_rights.stream_oob.cross_edge ok 11 scm_rights.stream_oob.cross_edge # RUN scm_rights.stream_oob.backtrack_from_scc ... # OK scm_rights.stream_oob.backtrack_from_scc ok 12 scm_rights.stream_oob.backtrack_from_scc # RUN scm_rights.stream_listener.self_ref ... # OK scm_rights.stream_listener.self_ref ok 13 scm_rights.stream_listener.self_ref # RUN scm_rights.stream_listener.triangle ... # OK scm_rights.stream_listener.triangle ok 14 scm_rights.stream_listener.triangle # RUN scm_rights.stream_listener.cross_edge ... # OK scm_rights.stream_listener.cross_edge ok 15 scm_rights.stream_listener.cross_edge # RUN scm_rights.stream_listener.backtrack_from_scc ... # OK scm_rights.stream_listener.backtrack_from_scc ok 16 scm_rights.stream_listener.backtrack_from_scc # RUN scm_rights.stream_listener_oob.self_ref ... # OK scm_rights.stream_listener_oob.self_ref ok 17 scm_rights.stream_listener_oob.self_ref # RUN scm_rights.stream_listener_oob.triangle ... # OK scm_rights.stream_listener_oob.triangle ok 18 scm_rights.stream_listener_oob.triangle # RUN scm_rights.stream_listener_oob.cross_edge ... # OK scm_rights.stream_listener_oob.cross_edge ok 19 scm_rights.stream_listener_oob.cross_edge # RUN scm_rights.stream_listener_oob.backtrack_from_scc ... # OK scm_rights.stream_listener_oob.backtrack_from_scc ok 20 scm_rights.stream_listener_oob.backtrack_from_scc # PASSED: 20 / 20 tests passed. # Totals: pass:20 fail:0 xfail:0 xpass:0 skip:0 error:0
[0] https://lore.kernel.org/all/20250304030149.82265-1-kuniyu@amazon.com/ [1] https://lore.kernel.org/all/20240325202425.60930-16-kuniyu@amazon.com/
Alexander Mikhalitsyn (1): af_unix: Kconfig: make CONFIG_UNIX bool
Kuniyuki Iwashima (24): af_unix: Return struct unix_sock from unix_get_socket(). af_unix: Run GC on only one CPU. af_unix: Try to run GC async. af_unix: Replace BUG_ON() with WARN_ON_ONCE(). af_unix: Remove io_uring code for GC. af_unix: Remove CONFIG_UNIX_SCM. af_unix: Allocate struct unix_vertex for each inflight AF_UNIX fd. af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd. af_unix: Link struct unix_edge when queuing skb. af_unix: Bulk update unix_tot_inflight/unix_inflight when queuing skb. af_unix: Iterate all vertices by DFS. af_unix: Detect Strongly Connected Components. af_unix: Save listener for embryo socket. af_unix: Fix up unix_edge.successor for embryo socket. af_unix: Save O(n) setup of Tarjan's algo. af_unix: Skip GC if no cycle exists. af_unix: Avoid Tarjan's algorithm if unnecessary. af_unix: Assign a unique index to SCC. af_unix: Detect dead SCC. af_unix: Replace garbage collection algorithm. af_unix: Remove lock dance in unix_peek_fds(). af_unix: Try not to hold unix_gc_lock during accept(). af_unix: Don't access successor in unix_del_edges() during GC. af_unix: Add dead flag to struct scm_fp_list.
Michal Luczaj (1): af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS
Shigeru Yoshida (1): af_unix: Fix uninit-value in __unix_walk_scc()
include/net/af_unix.h | 48 ++- include/net/scm.h | 11 + net/Makefile | 2 +- net/core/scm.c | 17 ++ net/unix/Kconfig | 11 +- net/unix/Makefile | 2 - net/unix/af_unix.c | 120 +++++--- net/unix/garbage.c | 691 +++++++++++++++++++++++++++++------------- net/unix/scm.c | 154 ---------- net/unix/scm.h | 10 - 10 files changed, 618 insertions(+), 448 deletions(-) delete mode 100644 net/unix/scm.c delete mode 100644 net/unix/scm.h