* [PATCH v3 net 1/2] af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS
2024-05-17 9:27 [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest Michal Luczaj
@ 2024-05-17 9:27 ` Michal Luczaj
2024-05-17 9:27 ` [PATCH v3 net 2/2] selftest: af_unix: Make SCM_RIGHTS into OOB data Michal Luczaj
2024-05-21 11:50 ` [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: Michal Luczaj @ 2024-05-17 9:27 UTC (permalink / raw)
To: netdev; +Cc: davem, edumazet, kuba, pabeni, kuniyu, shuah, Michal Luczaj
GC attempts to explicitly drop oob_skb's reference before purging the hit
list.
The problem is with embryos: kfree_skb(u->oob_skb) is never called on an
embryo socket.
The python script below [0] sends a listener's fd to its embryo as OOB
data. While GC does collect the embryo's queue, it fails to drop the OOB
skb's refcount. The skb which was in embryo's receive queue stays as
unix_sk(sk)->oob_skb and keeps the listener's refcount [1].
Tell GC to dispose embryo's oob_skb.
[0]:
from array import array
from socket import *
addr = '\x00unix-oob'
lis = socket(AF_UNIX, SOCK_STREAM)
lis.bind(addr)
lis.listen(1)
s = socket(AF_UNIX, SOCK_STREAM)
s.connect(addr)
scm = (SOL_SOCKET, SCM_RIGHTS, array('i', [lis.fileno()]))
s.sendmsg([b'x'], [scm], MSG_OOB)
lis.close()
[1]
$ grep unix-oob /proc/net/unix
$ ./unix-oob.py
$ grep unix-oob /proc/net/unix
0000000000000000: 00000002 00000000 00000000 0001 02 0 @unix-oob
0000000000000000: 00000002 00000000 00010000 0001 01 6072 @unix-oob
Fixes: 4090fa373f0e ("af_unix: Replace garbage collection algorithm.")
Signed-off-by: Michal Luczaj <mhal@rbox.co>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
net/unix/garbage.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 1f8b8cdfcdc8..dfe94a90ece4 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -342,6 +342,18 @@ enum unix_recv_queue_lock_class {
U_RECVQ_LOCK_EMBRYO,
};
+static void unix_collect_queue(struct unix_sock *u, struct sk_buff_head *hitlist)
+{
+ skb_queue_splice_init(&u->sk.sk_receive_queue, hitlist);
+
+#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+ if (u->oob_skb) {
+ WARN_ON_ONCE(skb_unref(u->oob_skb));
+ u->oob_skb = NULL;
+ }
+#endif
+}
+
static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist)
{
struct unix_vertex *vertex;
@@ -365,18 +377,11 @@ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist
/* listener -> embryo order, the inversion never happens. */
spin_lock_nested(&embryo_queue->lock, U_RECVQ_LOCK_EMBRYO);
- skb_queue_splice_init(embryo_queue, hitlist);
+ unix_collect_queue(unix_sk(skb->sk), hitlist);
spin_unlock(&embryo_queue->lock);
}
} else {
- skb_queue_splice_init(queue, hitlist);
-
-#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
- if (u->oob_skb) {
- kfree_skb(u->oob_skb);
- u->oob_skb = NULL;
- }
-#endif
+ unix_collect_queue(u, hitlist);
}
spin_unlock(&queue->lock);
--
2.45.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 net 2/2] selftest: af_unix: Make SCM_RIGHTS into OOB data.
2024-05-17 9:27 [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest Michal Luczaj
2024-05-17 9:27 ` [PATCH v3 net 1/2] af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS Michal Luczaj
@ 2024-05-17 9:27 ` Michal Luczaj
2024-05-19 8:44 ` Michal Luczaj
2024-05-21 11:50 ` [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest patchwork-bot+netdevbpf
2 siblings, 1 reply; 5+ messages in thread
From: Michal Luczaj @ 2024-05-17 9:27 UTC (permalink / raw)
To: netdev; +Cc: davem, edumazet, kuba, pabeni, kuniyu, shuah
From: Kuniyuki Iwashima <kuniyu@amazon.com>
scm_rights.c covers various test cases for inflight file descriptors
and garbage collector for AF_UNIX sockets.
Currently, SCM_RIGHTS messages are sent with 3-bytes string, and it's
not good for MSG_OOB cases, as SCM_RIGTS cmsg goes with the first 2-bytes,
which is non-OOB data.
Let's send SCM_RIGHTS messages with 1-byte character to pack SCM_RIGHTS
into OOB data.
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
tools/testing/selftests/net/af_unix/scm_rights.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/af_unix/scm_rights.c b/tools/testing/selftests/net/af_unix/scm_rights.c
index bab606c9f1eb..2bfed46e0b19 100644
--- a/tools/testing/selftests/net/af_unix/scm_rights.c
+++ b/tools/testing/selftests/net/af_unix/scm_rights.c
@@ -197,8 +197,8 @@ void __send_fd(struct __test_metadata *_metadata,
const FIXTURE_VARIANT(scm_rights) *variant,
int inflight, int receiver)
{
-#define MSG "nop"
-#define MSGLEN 3
+#define MSG "x"
+#define MSGLEN 1
struct {
struct cmsghdr cmsghdr;
int fd[2];
--
2.45.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest
2024-05-17 9:27 [PATCH v3 net 0/2] af_unix: Fix GC and improve selftest Michal Luczaj
2024-05-17 9:27 ` [PATCH v3 net 1/2] af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS Michal Luczaj
2024-05-17 9:27 ` [PATCH v3 net 2/2] selftest: af_unix: Make SCM_RIGHTS into OOB data Michal Luczaj
@ 2024-05-21 11:50 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-05-21 11:50 UTC (permalink / raw)
To: Michal Luczaj; +Cc: netdev, davem, edumazet, kuba, pabeni, kuniyu, shuah
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Fri, 17 May 2024 11:27:00 +0200 you wrote:
> Series deals with AF_UNIX garbage collector mishandling some in-flight
> graph cycles. Embryos carrying OOB packets with SCM_RIGHTS cause issues.
>
> Patch 1/2 fixes the memory leak.
> Patch 2/2 tweaks the selftest for a better OOB coverage.
>
> v3:
> - Patch 1/2: correct the commit message (Kuniyuki)
>
> [...]
Here is the summary with links:
- [v3,net,1/2] af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS
https://git.kernel.org/netdev/net/c/041933a1ec7b
- [v3,net,2/2] selftest: af_unix: Make SCM_RIGHTS into OOB data.
https://git.kernel.org/netdev/net/c/e060e433e512
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread