udplite: fix various data-races
udp->pcflag, udp->pcslen and udp->pcrlen reads/writes are racy.
Move udp->pcflag to udp->udp_flags for atomicity,
and add READ_ONCE()/WRITE_ONCE() annotations for pcslen and pcrlen.
Fixes: ba4e58eca8
("[NET]: Supporting UDP-Lite (RFC 3828) in Linux")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
729549aa35
commit
882af43a0f
@@ -66,14 +66,18 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
|
||||
/* Fast-path computation of checksum. Socket may not be locked. */
|
||||
static inline __wsum udplite_csum(struct sk_buff *skb)
|
||||
{
|
||||
const struct udp_sock *up = udp_sk(skb->sk);
|
||||
const int off = skb_transport_offset(skb);
|
||||
const struct sock *sk = skb->sk;
|
||||
int len = skb->len - off;
|
||||
|
||||
if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
|
||||
if (0 < up->pcslen)
|
||||
len = up->pcslen;
|
||||
udp_hdr(skb)->len = htons(up->pcslen);
|
||||
if (udp_test_bit(UDPLITE_SEND_CC, sk)) {
|
||||
u16 pcslen = READ_ONCE(udp_sk(sk)->pcslen);
|
||||
|
||||
if (pcslen < len) {
|
||||
if (pcslen > 0)
|
||||
len = pcslen;
|
||||
udp_hdr(skb)->len = htons(pcslen);
|
||||
}
|
||||
}
|
||||
skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
|
||||
|
||||
|
Reference in New Issue
Block a user