From: Lee Jones <lee@kernel.org>
To: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>,
Kuniyuki Iwashima <kuni1840@gmail.com>,
stable@vger.kernel.org, netdev@vger.kernel.org,
Lei Lu <llfamsec@gmail.com>
Subject: Re: [PATCH stable 5.15/6.1/6.6] af_unix: Clear oob_skb in scan_inflight().
Date: Tue, 29 Apr 2025 12:12:49 +0100 [thread overview]
Message-ID: <20250429111249.GA2619229@google.com> (raw)
In-Reply-To: <20250304030149.82265-1-kuniyu@amazon.com>
On Mon, 03 Mar 2025, Kuniyuki Iwashima wrote:
> Embryo socket is not queued in gc_candidates, so we can't drop
> a reference held by its oob_skb.
>
> Let's say we create listener and embryo sockets, send the
> listener's fd to the embryo as OOB data, and close() them
> without recv()ing the OOB data.
>
> There is a self-reference cycle like
>
> listener -> embryo.oob_skb -> listener
>
> , so this must be cleaned up by GC. Otherwise, the listener's
> refcnt is not released and sockets are leaked:
>
> # unshare -n
> # cat /proc/net/protocols | grep UNIX-STREAM
> UNIX-STREAM 1024 0 -1 NI 0 yes kernel ...
>
> # python3
> >>> from array import array
> >>> from socket import *
> >>>
> >>> s = socket(AF_UNIX, SOCK_STREAM)
> >>> s.bind('\0test\0')
> >>> s.listen()
> >>>
> >>> c = socket(AF_UNIX, SOCK_STREAM)
> >>> c.connect(s.getsockname())
> >>> c.sendmsg([b'x'], [(SOL_SOCKET, SCM_RIGHTS, array('i', [s.fileno()]))], MSG_OOB)
> 1
> >>> quit()
>
> # cat /proc/net/protocols | grep UNIX-STREAM
> UNIX-STREAM 1024 3 -1 NI 0 yes kernel ...
> ^^^
> 3 sockets still in use after FDs are close()d
>
> Let's drop the embryo socket's oob_skb ref in scan_inflight().
>
> This also fixes a racy access to oob_skb that commit 9841991a446c
> ("af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue
> lock.") fixed for the new Tarjan's algo-based GC.
>
> Fixes: 314001f0bf92 ("af_unix: Add OOB support")
> Reported-by: Lei Lu <llfamsec@gmail.com>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> ---
> This has no upstream commit because I replaced the entire GC in
> 6.10 and the new GC does not have this bug, and this fix is only
> applicable to the old GC (<= 6.9), thus for 5.15/6.1/6.6.
> ---
> ---
> net/unix/garbage.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
Tested-by: Lee Jones <lee@kernel.org>
> diff --git a/net/unix/garbage.c b/net/unix/garbage.c
> index 2a758531e102..b3fbdf129944 100644
> --- a/net/unix/garbage.c
> +++ b/net/unix/garbage.c
> @@ -102,13 +102,14 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
> /* Process the descriptors of this socket */
> int nfd = UNIXCB(skb).fp->count;
> struct file **fp = UNIXCB(skb).fp->fp;
> + struct unix_sock *u;
>
> while (nfd--) {
> /* Get the socket the fd matches if it indeed does so */
> struct sock *sk = unix_get_socket(*fp++);
>
> if (sk) {
> - struct unix_sock *u = unix_sk(sk);
> + u = unix_sk(sk);
>
> /* Ignore non-candidates, they could
> * have been added to the queues after
> @@ -122,6 +123,13 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
> }
> }
> if (hit && hitlist != NULL) {
> +#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
> + u = unix_sk(x);
> + if (u->oob_skb) {
> + WARN_ON_ONCE(skb_unref(u->oob_skb));
> + u->oob_skb = NULL;
> + }
> +#endif
> __skb_unlink(skb, &x->sk_receive_queue);
> __skb_queue_tail(hitlist, skb);
> }
> @@ -299,17 +307,9 @@ void unix_gc(void)
> * which are creating the cycle(s).
> */
> skb_queue_head_init(&hitlist);
> - list_for_each_entry(u, &gc_candidates, link) {
> + list_for_each_entry(u, &gc_candidates, link)
> scan_children(&u->sk, inc_inflight, &hitlist);
>
> -#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
> - if (u->oob_skb) {
> - kfree_skb(u->oob_skb);
> - u->oob_skb = NULL;
> - }
> -#endif
> - }
> -
> /* not_cycle_list contains those sockets which do not make up a
> * cycle. Restore these to the inflight list.
> */
> --
> 2.39.5 (Apple Git-154)
>
--
Lee Jones [李琼斯]
prev parent reply other threads:[~2025-04-29 11:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-04 3:01 [PATCH stable 5.15/6.1/6.6] af_unix: Clear oob_skb in scan_inflight() Kuniyuki Iwashima
2025-03-04 22:13 ` Sasha Levin
2025-03-05 14:08 ` Greg Kroah-Hartman
2025-03-05 18:10 ` Kuniyuki Iwashima
2025-03-05 18:22 ` Greg KH
2025-05-12 7:53 ` Lee Jones
2025-05-16 8:18 ` Lee Jones
2025-05-16 18:27 ` [PATCH Astable " Kuniyuki Iwashima
2025-04-29 11:12 ` Lee Jones [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250429111249.GA2619229@google.com \
--to=lee@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=kuni1840@gmail.com \
--cc=kuniyu@amazon.com \
--cc=llfamsec@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.