Re: [PATCH net-next v3 1/3] af_unix: Schedule the garbage collector at task exit

From: sashiko-bot

Date: Thu Jul 23 2026 - 05:38:23 EST


Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Unconditionally triggering the global AF_UNIX garbage collector on task exit creates a severe system-wide denial of service vulnerability.
- [Medium] A TOCTOU race on `gc_in_progress` causes `do_exit()` to skip queueing the garbage collector if it is currently running, leaving the cyclic sockets leaked indefinitely.
--

--- Patch [1]: [PATCH net-next v3 1/3] af_unix: Schedule the garbage collector at task exit ---
commit 9a35b6370cf5aa7dba01e2ce8f06d95e2eb14265
Author: Nam Cao <namcao@xxxxxxxxxxxxx>

af_unix: Schedule the garbage collector at task exit

This commit attempts to fix a memory leak involving dead cyclic reference
AF_UNIX sockets when a task exits. It does this by scheduling the garbage
collector during task exit, after the task's file descriptors have been
closed.

> diff --git a/kernel/exit.c b/kernel/exit.c
> index 2c0b1c02920f4..593ac4b0105f2 100644
> --- a/kernel/exit.c
> +++ b/kernel/exit.c
[ ... ]
> @@ -1009,6 +1010,12 @@ void __noreturn do_exit(long code)
> exit_task_work(tsk);
> exit_thread(tsk);
>
> + /*
> + * Must be after exit_files() and exit_task_work(tsk) to ensure that
> + * the task's AF_UNIX sockets have all been closed.
> + */
> + unix_schedule_gc(NULL);

[Severity: High]
Does unconditionally triggering the global AF_UNIX garbage collector on task
exit create a severe system-wide denial of service vulnerability?

By passing NULL to unix_schedule_gc(), the rate-limiting check
(user->unix_inflight) is bypassed. If an unprivileged user creates a cyclic
graph of AF_UNIX sockets, every task exit system-wide would unconditionally
queue unix_gc_work.

The GC thread would then take the global unix_gc_lock spinlock and perform
an O(N) traversal of all cyclic sockets, burning CPU and blocking all
legitimate AF_UNIX operations system-wide.

[Severity: Medium]
Can a race on gc_in_progress cause do_exit() to skip queueing the garbage
collector if it is currently running, leaving the cyclic sockets leaked
indefinitely?

If a background GC run is currently active, gc_in_progress is true. If the
concurrent GC scans the exiting task's sockets before they are closed, it
considers them alive.

When the exiting task subsequently closes them and calls
unix_schedule_gc(NULL), it sees gc_in_progress is true and silently skips
queueing a new GC pass. This fails to reliably fix the socket leak it was
intended to resolve.

> +
> sched_autogroup_exit_task(tsk);
> cgroup_task_exit(tsk);
>

--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1784712370.git.namcao@xxxxxxxxxxxxx?part=1