mhi_mbim_newlink() adds the link to mbim->link_list before calling
register_netdevice(). If registration fails, the caller frees the
netdev without removing the link, leaving a dangling list entry that
RCU readers such as mhi_mbim_rx() can access after free.
Register the netdev before adding the link to the list so that failed
registrations do not publish a link.
Found while reviewing newlink error paths. A UML/KASAN test module
using driver wrappers and a fake MHI context reproduced the use-after-free
in the driver's RCU lookup. The fix passed the registration-failure and
create/delete tests. Both UML builds passed with W=1.
Fixes: aa730a9905b7 ("net: wwan: Add MHI MBIM network driver")
Cc: <redacted>
Signed-off-by: Xia Yan <redacted>
---
drivers/net/wwan/mhi_wwan_mbim.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
index 336f897..846b317 100644
--- a/drivers/net/wwan/mhi_wwan_mbim.c
+++ b/drivers/net/wwan/mhi_wwan_mbim.c
@@ -561,6 +561,7 @@ static int mhi_mbim_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
{
struct mhi_mbim_link *link = wwan_netdev_drvpriv(ndev);
struct mhi_mbim_context *mbim = ctxt;
+ int ret;
link->mbim = mbim;
link->session = mhi_mbim_get_link_mux_id(link->mbim->mdev->mhi_cntrl) + if_id;@@ -575,10 +576,14 @@ static int mhi_mbim_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
}
rcu_read_unlock();
+ ret = register_netdevice(ndev);
+ if (ret)
+ return ret;
+
/* Already protected by RTNL lock */
hlist_add_head_rcu(&link->hlnode, &mbim->link_list[LINK_HASH(if_id)]);
- return register_netdevice(ndev);
+ return 0;
}
static void mhi_mbim_dellink(void *ctxt, struct net_device *ndev,
base-commit: 8d5ce4751fad9499ea408163af7f410f18a85782