Re: [PATCH net] macvlan: Fix use-after-free in macvlan_common_newlink

From: Eric Dumazet
Date: Thu Jan 08 2026 - 12:50:55 EST


On Thu, Jan 8, 2026 at 6:45 PM Boudewijn van der Heide
<boudewijn@xxxxxxxxxxxxxx> wrote:
>
> 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@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=7182fbe91e58602ec1fe
> Signed-off-by: Boudewijn van der Heide <boudewijn@xxxxxxxxxxxxxx>
> ---
> 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
>

I have sent this instead

https://lore.kernel.org/all/20260108133651.1130486-1-edumazet@xxxxxxxxxx/T/

I think my patch makes more sense.