From e7a63b5ceb41444c358d1ff602009de9daed1b75 Mon Sep 17 00:00:00 2001 From: Mina Almasry Date: Tue, 8 Sep 2026 18:07:43 +0000 Subject: [PATCH] net: devmem: fix TX binding UAF on netdevice unregister TX dma-buf bindings do not take a net_device reference and do not register with RX queues. Consequently, they are skipped by the devmem RX teardown routine. If the bound device unregisters, the TX binding's dev pointer is left dangling. Closing the socket later causes netdev_nl_sock_priv_destroy() to dereference this freed pointer. Fix this by explicitly clearing binding->dev for TX bindings during net_device unregistration. Signed-off-by: Mina Almasry --- net/core/dev.c | 2 ++ net/core/devmem.c | 17 +++++++++++++++++ net/core/devmem.h | 5 +++++ 3 files changed, 24 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index ecfbd72d5d1a4..c9aec533f6f21 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -12401,6 +12401,8 @@ static void dev_memory_provider_uninstall(struct net_device *dev) __netif_mp_uninstall_rxq(rxq, &rxq->mp_params); } + + net_devmem_dev_uninstall(dev); } /* devices must be UP and netdev_lock()'d */ diff --git a/net/core/devmem.c b/net/core/devmem.c index f4d60654ce7fd..feb40d75d7241 100644 --- a/net/core/devmem.c +++ b/net/core/devmem.c @@ -153,6 +153,23 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding) percpu_ref_kill(&binding->ref); } +void net_devmem_dev_uninstall(struct net_device *dev) +{ + struct net_devmem_dmabuf_binding *binding; + unsigned long id; + + xa_for_each(&net_devmem_dmabuf_bindings, id, binding) { + if (binding->dev == dev && xa_empty(&binding->bound_rxqs)) { + mutex_lock(&binding->lock); + if (binding->dev == dev) { + ASSERT_EXCLUSIVE_WRITER(binding->dev); + WRITE_ONCE(binding->dev, NULL); + } + mutex_unlock(&binding->lock); + } + } +} + int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx, struct net_devmem_dmabuf_binding *binding, struct netlink_ext_ack *extack) diff --git a/net/core/devmem.h b/net/core/devmem.h index 4a293a7d1149c..6a737b4024528 100644 --- a/net/core/devmem.h +++ b/net/core/devmem.h @@ -100,6 +100,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev, struct netlink_ext_ack *extack); struct net_devmem_dmabuf_binding *net_devmem_lookup_dmabuf(u32 id); void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding); +void net_devmem_dev_uninstall(struct net_device *dev); int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx, struct net_devmem_dmabuf_binding *binding, struct netlink_ext_ack *extack); @@ -196,6 +197,10 @@ net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding) { } +static inline void net_devmem_dev_uninstall(struct net_device *dev) +{ +} + static inline int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx, struct net_devmem_dmabuf_binding *binding, -- 2.55.0.979.g7e5102b832-goog