mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
rtnetlink: fix rtnl_dump_ifinfo() error path
syzbot found that rtnl_dump_ifinfo() could return with a lock held [1]
Move code around so that rtnl_link_ops_put() and put_net()
can be called at the end of this function.
[1]
WARNING: lock held when returning to user space!
6.12.0-rc7-syzkaller-01681-g38f83a57aa8e #0 Not tainted
syz-executor399/5841 is leaving the kernel with locks still held!
1 lock held by syz-executor399/5841:
#0: ffffffff8f46c2a0 (&ops->srcu#2){.+.+}-{0:0}, at: rcu_lock_acquire include/linux/rcupdate.h:337 [inline]
#0: ffffffff8f46c2a0 (&ops->srcu#2){.+.+}-{0:0}, at: rcu_read_lock include/linux/rcupdate.h:849 [inline]
#0: ffffffff8f46c2a0 (&ops->srcu#2){.+.+}-{0:0}, at: rtnl_link_ops_get+0x22/0x250 net/core/rtnetlink.c:555
Fixes: 43c7ce69d2
("rtnetlink: Protect struct rtnl_link_ops with SRCU.")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Joe Damato <jdamato@fastly.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20241121194105.3632507-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
078f644cb8
commit
9b234a97b1
@ -2442,7 +2442,9 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid);
|
||||
if (IS_ERR(tgt_net)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid target network namespace id");
|
||||
return PTR_ERR(tgt_net);
|
||||
err = PTR_ERR(tgt_net);
|
||||
netnsid = -1;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case IFLA_EXT_MASK:
|
||||
@ -2457,7 +2459,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
default:
|
||||
if (cb->strict_check) {
|
||||
NL_SET_ERR_MSG(extack, "Unsupported attribute in link dump request");
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2479,11 +2482,14 @@ walk_entries:
|
||||
break;
|
||||
}
|
||||
|
||||
if (kind_ops)
|
||||
rtnl_link_ops_put(kind_ops, ops_srcu_index);
|
||||
|
||||
cb->seq = tgt_net->dev_base_seq;
|
||||
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
|
||||
|
||||
out:
|
||||
|
||||
if (kind_ops)
|
||||
rtnl_link_ops_put(kind_ops, ops_srcu_index);
|
||||
if (netnsid >= 0)
|
||||
put_net(tgt_net);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user