| From 25fbd119df3980bc8fb1beddb5bab0dca0304971 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 13 Feb 2026 14:25:57 +0000 |
| Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() |
| error path |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| [ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] |
| |
| valis reported that a race condition still happens after my prior patch. |
| |
| macvlan_common_newlink() might have made @dev visible before |
| detecting an error, and its caller will directly call free_netdev(dev). |
| |
| We must respect an RCU period, either in macvlan or the core networking |
| stack. |
| |
| After adding a temporary mdelay(1000) in macvlan_forward_source_one() |
| to open the race window, valis repro was: |
| |
| ip link add p1 type veth peer p2 |
| ip link set address 00:00:00:00:00:20 dev p1 |
| ip link set up dev p1 |
| ip link set up dev p2 |
| ip link add mv0 link p2 type macvlan mode source |
| |
| (ip link add invalid% link p2 type macvlan mode source macaddr add |
| 00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 |
| PING 1.2.3.4 (1.2.3.4): 56 data bytes |
| RTNETLINK answers: Invalid argument |
| |
| BUG: KASAN: slab-use-after-free in macvlan_forward_source |
| (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) |
| Read of size 8 at addr ffff888016bb89c0 by task e/175 |
| |
| CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE |
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 |
| Call Trace: |
| <IRQ> |
| dump_stack_lvl (lib/dump_stack.c:123) |
| print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) |
| ? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) |
| kasan_report (mm/kasan/report.c:597) |
| ? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) |
| macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) |
| ? tasklet_init (kernel/softirq.c:983) |
| macvlan_handle_frame (drivers/net/macvlan.c:501) |
| |
| Allocated by task 169: |
| kasan_save_stack (mm/kasan/common.c:58) |
| kasan_save_track (./arch/x86/include/asm/current.h:25 |
| mm/kasan/common.c:70 mm/kasan/common.c:79) |
| __kasan_kmalloc (mm/kasan/common.c:419) |
| __kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 |
| mm/slub.c:7140) |
| alloc_netdev_mqs (net/core/dev.c:12012) |
| rtnl_create_link (net/core/rtnetlink.c:3648) |
| rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 |
| net/core/rtnetlink.c:4072) |
| rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) |
| netlink_rcv_skb (net/netlink/af_netlink.c:2550) |
| netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) |
| netlink_sendmsg (net/netlink/af_netlink.c:1894) |
| __sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) |
| __x64_sys_sendto (net/socket.c:2209) |
| do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) |
| entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) |
| |
| Freed by task 169: |
| kasan_save_stack (mm/kasan/common.c:58) |
| kasan_save_track (./arch/x86/include/asm/current.h:25 |
| mm/kasan/common.c:70 mm/kasan/common.c:79) |
| kasan_save_free_info (mm/kasan/generic.c:587) |
| __kasan_slab_free (mm/kasan/common.c:287) |
| kfree (mm/slub.c:6674 mm/slub.c:6882) |
| rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 |
| net/core/rtnetlink.c:4072) |
| rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) |
| netlink_rcv_skb (net/netlink/af_netlink.c:2550) |
| netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) |
| netlink_sendmsg (net/netlink/af_netlink.c:1894) |
| __sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) |
| __x64_sys_sendto (net/socket.c:2209) |
| do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) |
| entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) |
| |
| Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Reported-by: valis <sec@valis.email> |
| Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/macvlan.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c |
| index c509228be84d1..4433b8e95b6ac 100644 |
| --- a/drivers/net/macvlan.c |
| +++ b/drivers/net/macvlan.c |
| @@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev, |
| if (create) |
| macvlan_port_destroy(port->dev); |
| } |
| + /* @dev might have been made visible before an error was detected. |
| + * Make sure to observe an RCU grace period before our caller |
| + * (rtnl_newlink()) frees it. |
| + */ |
| + synchronize_net(); |
| return err; |
| } |
| EXPORT_SYMBOL_GPL(macvlan_common_newlink); |
| -- |
| 2.51.0 |
| |