lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260108174504.86488-1-boudewijn@delta-utec.com>
Date: Thu,  8 Jan 2026 18:45:04 +0100
From: Boudewijn van der Heide <boudewijn@...ta-utec.com>
To: netdev@...r.kernel.org
Cc: andrew+netdev@...n.ch,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	linux-kernel@...r.kernel.org,
	Boudewijn van der Heide <boudewijn@...ta-utec.com>,
	syzbot+7182fbe91e58602ec1fe@...kaller.appspotmail.com
Subject: [PATCH net] macvlan: Fix use-after-free in macvlan_common_newlink

The macvlan_common_newlink() function calls macvlan_port_create(),
which allocates a port structure and registers the RX handler via
netdev_rx_handler_register(). Once registered, the handler is
immediately live and can be invoked from softirq context.

If the subsequent call to register_netdevice() fails (e.g., due to
a name collision), the error path calls macvlan_port_destroy(),
which unregisters the handler and immediately frees the port with
kfree().

This creates a race condition: one thread may be processing a packet
in the RX handler and accessing the port structure, while another
thread is executing the error path and frees the port. This results
in the first thread reading freed memory, leading to a use-after-free
and undefined behavior.

Fix this by replacing kfree() with kfree_rcu() to defer the memory
release until all RCU read-side sections have completed,
and add an rcu_head field to the macvlan_port structure. This ensures
the port remains valid while any thread is still accessing it.

This functionality was previously present but was removed in
commit a1f5315ce4e1 ("driver: macvlan: Remove the rcu member of macvlan_port"),
which inadvertently introduced this use-after-free.

Fixes: a1f5315ce4e1 ("driver: macvlan: Remove the rcu member of macvlan_port")
Reported-by: syzbot+7182fbe91e58602ec1fe@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7182fbe91e58602ec1fe
Signed-off-by: Boudewijn van der Heide <boudewijn@...ta-utec.com>
---
 drivers/net/macvlan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 7966545512cf..d6e8f7774055 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -47,6 +47,7 @@ struct macvlan_port {
 	struct list_head	vlans;
 	struct sk_buff_head	bc_queue;
 	struct work_struct	bc_work;
+	struct rcu_head		rcu;
 	u32			bc_queue_len_used;
 	int			bc_cutoff;
 	u32			flags;
@@ -1302,7 +1303,7 @@ static void macvlan_port_destroy(struct net_device *dev)
 		dev_set_mac_address(port->dev, &ss, NULL);
 	}
 
-	kfree(port);
+	kfree_rcu(port, rcu);
 }
 
 static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
-- 
2.47.3


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ