Commit 580acf6c authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'af_unix-fix-gc-and-improve-selftest'

Michal Luczaj says:

====================
af_unix: Fix GC and improve selftest

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)

v2: https://lore.kernel.org/netdev/20240516145457.1206847-1-mhal@rbox.co/
  - Patch 1/2: remove WARN_ON_ONCE() (Kuniyuki)
  - Combine both patches into a series (Kuniyuki)

v1: https://lore.kernel.org/netdev/20240516103049.1132040-1-mhal@rbox.co/
====================

Link: https://lore.kernel.org/r/20240517093138.1436323-1-mhal@rbox.coSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 3ebc46ca e060e433
...@@ -342,6 +342,18 @@ enum unix_recv_queue_lock_class { ...@@ -342,6 +342,18 @@ enum unix_recv_queue_lock_class {
U_RECVQ_LOCK_EMBRYO, 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) static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist)
{ {
struct unix_vertex *vertex; struct unix_vertex *vertex;
...@@ -365,18 +377,11 @@ static void unix_collect_skb(struct list_head *scc, struct sk_buff_head *hitlist ...@@ -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. */ /* listener -> embryo order, the inversion never happens. */
spin_lock_nested(&embryo_queue->lock, U_RECVQ_LOCK_EMBRYO); 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); spin_unlock(&embryo_queue->lock);
} }
} else { } else {
skb_queue_splice_init(queue, hitlist); unix_collect_queue(u, hitlist);
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
if (u->oob_skb) {
kfree_skb(u->oob_skb);
u->oob_skb = NULL;
}
#endif
} }
spin_unlock(&queue->lock); spin_unlock(&queue->lock);
......
...@@ -197,8 +197,8 @@ void __send_fd(struct __test_metadata *_metadata, ...@@ -197,8 +197,8 @@ void __send_fd(struct __test_metadata *_metadata,
const FIXTURE_VARIANT(scm_rights) *variant, const FIXTURE_VARIANT(scm_rights) *variant,
int inflight, int receiver) int inflight, int receiver)
{ {
#define MSG "nop" #define MSG "x"
#define MSGLEN 3 #define MSGLEN 1
struct { struct {
struct cmsghdr cmsghdr; struct cmsghdr cmsghdr;
int fd[2]; int fd[2];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment