ipv4: route: fix inet_rtm_getroute induced crash
"ip route get $daddr iif eth0 from $saddr" causes:
BUG: KASAN: use-after-free in ip_route_input_rcu+0x1535/0x1b50
Call Trace:
ip_route_input_rcu+0x1535/0x1b50
ip_route_input_noref+0xf9/0x190
tcp_v4_early_demux+0x1a4/0x2b0
ip_rcv+0xbcb/0xc05
__netif_receive_skb+0x9c/0xd0
netif_receive_skb_internal+0x5a8/0x890
Problem is that inet_rtm_getroute calls either ip_route_input_rcu (if an
iif was provided) or ip_route_output_key_hash_rcu.
But ip_route_input_rcu, unlike ip_route_output_key_hash_rcu, already
associates the dst_entry with the skb. This clears the SKB_DST_NOREF
bit (i.e. skb_dst_drop will release/free the entry while it should not).
Thus only set the dst if we called ip_route_output_key_hash_rcu().
I tested this patch by running:
while true;do ip r get 10.0.1.2;done > /dev/null &
while true;do ip r get 10.0.1.2 iif eth0 from 10.0.1.1;done > /dev/null &
... and saw no crash or memory leak.
Cc: Roopa Prabhu <roopa@cumulusnetworks.com>
Cc: David Ahern <dsahern@gmail.com>
Fixes: ba52d61e0f
("ipv4: route: restore skb_dst_set in inet_rtm_getroute")
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
11e9d7829d
commit
2c87d63ac8
|
@ -2750,12 +2750,13 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
|||
err = 0;
|
||||
if (IS_ERR(rt))
|
||||
err = PTR_ERR(rt);
|
||||
else
|
||||
skb_dst_set(skb, &rt->dst);
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto errout_free;
|
||||
|
||||
skb_dst_set(skb, &rt->dst);
|
||||
if (rtm->rtm_flags & RTM_F_NOTIFY)
|
||||
rt->rt_flags |= RTCF_NOTIFY;
|
||||
|
||||
|
|
Loading…
Reference in New Issue