diff options
author | Eric Dumazet <edumazet@google.com> | 2023-09-12 11:17:30 +0200 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2023-09-14 16:16:36 +0200 |
commit | 882af43a0fc37e26d85fb0df0c9edd3bed928de4 (patch) | |
tree | 285d545b88e7edfaa8c03073cad7e8f4ae1cf572 /include/net/udplite.h | |
parent | udplite: remove UDPLITE_BIT (diff) | |
download | linux-882af43a0fc37e26d85fb0df0c9edd3bed928de4.tar.xz linux-882af43a0fc37e26d85fb0df0c9edd3bed928de4.zip |
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: ba4e58eca8aa ("[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>
Diffstat (limited to 'include/net/udplite.h')
-rw-r--r-- | include/net/udplite.h | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/include/net/udplite.h b/include/net/udplite.h index bd33ff2b8f42..786919d29f8d 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h @@ -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 */ |