summaryrefslogtreecommitdiff
path: root/include/net/udplite.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2023-09-12 12:17:30 +0300
committerPaolo Abeni <pabeni@redhat.com>2023-09-14 17:16:36 +0300
commit882af43a0fc37e26d85fb0df0c9edd3bed928de4 (patch)
tree285d545b88e7edfaa8c03073cad7e8f4ae1cf572 /include/net/udplite.h
parent729549aa350c56a777bb342941ed4d69b6585769 (diff)
downloadlinux-882af43a0fc37e26d85fb0df0c9edd3bed928de4.tar.xz
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.h14
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 */