mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-20 11:09:00 +07:00
udp: fix dst races with multicast early demux
Multicast dst are not cached. They carry DST_NOCACHE. As mentioned in commitf886497212
("ipv4: fix dst race in sk_dst_get()"), these dst need special care before caching them into a socket. Caching them is allowed only if their refcnt was not 0, ie we must use atomic_inc_not_zero() Also, we must use READ_ONCE() to fetch sk->sk_rx_dst, as mentioned in commitd0c294c53a
("tcp: prevent fetching dst twice in early demux code") Fixes:421b3885bf
("udp: ipv4: Add udp early demux") Tested-by: Gregory Hoggarth <Gregory.Hoggarth@alliedtelesis.co.nz> Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Gregory Hoggarth <Gregory.Hoggarth@alliedtelesis.co.nz> Reported-by: Alex Gartrell <agartrell@fb.com> Cc: Michal Kubeček <mkubecek@suse.cz> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2fc09962e2
commit
10e2eb878f
@ -1995,12 +1995,19 @@ void udp_v4_early_demux(struct sk_buff *skb)
|
||||
|
||||
skb->sk = sk;
|
||||
skb->destructor = sock_efree;
|
||||
dst = sk->sk_rx_dst;
|
||||
dst = READ_ONCE(sk->sk_rx_dst);
|
||||
|
||||
if (dst)
|
||||
dst = dst_check(dst, 0);
|
||||
if (dst)
|
||||
skb_dst_set_noref(skb, dst);
|
||||
if (dst) {
|
||||
/* DST_NOCACHE can not be used without taking a reference */
|
||||
if (dst->flags & DST_NOCACHE) {
|
||||
if (likely(atomic_inc_not_zero(&dst->__refcnt)))
|
||||
skb_dst_set(skb, dst);
|
||||
} else {
|
||||
skb_dst_set_noref(skb, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int udp_rcv(struct sk_buff *skb)
|
||||
|
Loading…
Reference in New Issue
Block a user