PDP contexts can be deleted through GTP_CMD_DELPDP or while the GTP network device is being unregistered. The latter is serialized by RTNL, but the generic-netlink delete path only holds RCU. Running both paths concurrently can therefore make both paths delete the same PDP context. On a KASAN-enabled kernel, a reproducer racing DELPDP against RTM_DELLINK triggered: Oops: general protection fault, probably for non-canonical address KASAN: maybe wild-memory-access in range [0xdead000000000120-0xdead000000000127] RIP: gtp_genl_del_pdp+0x1c1/0x420 [gtp] RBP: dead000000000122 The second deletion dereferenced the poisoned hlist pprev pointer. Take RTNL around the DELPDP lookup and deletion so that PDP creation, generic-netlink deletion and link teardown use the same serialization domain. Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Signed-off-by: Qing Ming --- drivers/net/gtp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 427b91aca50d..7c4a99e2fd52 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -2127,6 +2127,8 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[GTPA_VERSION]) return -EINVAL; + rtnl_lock(); + rcu_read_lock(); pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); @@ -2147,6 +2149,7 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info) out_unlock: rcu_read_unlock(); + rtnl_unlock(); return err; } -- 2.53.0