diff options
| author | David S. Miller <[email protected]> | 2023-09-15 10:33:49 +0100 |
|---|---|---|
| committer | David S. Miller <[email protected]> | 2023-09-15 10:33:49 +0100 |
| commit | e73d5fb75d67538b13fe04d14a55f32ea4efe227 (patch) | |
| tree | 7096c954f2073480a2cb52ef4e443bac1b336679 /include/linux | |
| parent | f2fa1c812c91e99d0317d1fc7d845e1e05f39716 (diff) | |
| parent | 859f8b265fc2a11af0fb0c52b4087e0409250592 (diff) | |
Merge branch 'ipv6-data-races'
Eric Dumazet says:
====================
ipv6: round of data-races fixes
This series is inspired by one related syzbot report.
Many inet6_sk(sk) fields reads or writes are racy.
Move 1-bit fields to inet->inet_flags to provide
atomic safety. inet6_{test|set|clear|assign}_bit() helpers
could be changed later if we need to make room in inet_flags.
Also add missing READ_ONCE()/WRITE_ONCE() when
lockless readers need access to specific fields.
np->srcprefs will be handled separately to avoid merge conflicts
because a prior patch was posted for net tree.
====================
Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/ipv6.h | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index af8a771a053c..09253825c99c 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -213,28 +213,9 @@ struct ipv6_pinfo { __be32 flow_label; __u32 frag_size; - /* - * Packed in 16bits. - * Omit one shift by putting the signed field at MSB. - */ -#if defined(__BIG_ENDIAN_BITFIELD) - __s16 hop_limit:9; - __u16 __unused_1:7; -#else - __u16 __unused_1:7; - __s16 hop_limit:9; -#endif + s16 hop_limit; + u8 mcast_hops; -#if defined(__BIG_ENDIAN_BITFIELD) - /* Packed in 16bits. */ - __s16 mcast_hops:9; - __u16 __unused_2:6, - mc_loop:1; -#else - __u16 mc_loop:1, - __unused_2:6; - __s16 mcast_hops:9; -#endif int ucast_oif; int mcast_oif; @@ -262,21 +243,11 @@ struct ipv6_pinfo { } rxopt; /* sockopt flags */ - __u16 recverr:1, - sndflow:1, - repflow:1, - pmtudisc:3, - padding:1, /* 1 bit hole */ - srcprefs:3, /* 001: prefer temporary address + __u8 srcprefs:3; /* 001: prefer temporary address * 010: prefer public address * 100: prefer care-of address */ - dontfrag:1, - autoflowlabel:1, - autoflowlabel_set:1, - mc_all:1, - recverr_rfc4884:1, - rtalert_isolate:1; + __u8 pmtudisc; __u8 min_hopcount; __u8 tclass; __be32 rcv_flowinfo; @@ -293,6 +264,18 @@ struct ipv6_pinfo { struct inet6_cork cork; }; +/* We currently use available bits from inet_sk(sk)->inet_flags, + * this could change in the future. + */ +#define inet6_test_bit(nr, sk) \ + test_bit(INET_FLAGS_##nr, &inet_sk(sk)->inet_flags) +#define inet6_set_bit(nr, sk) \ + set_bit(INET_FLAGS_##nr, &inet_sk(sk)->inet_flags) +#define inet6_clear_bit(nr, sk) \ + clear_bit(INET_FLAGS_##nr, &inet_sk(sk)->inet_flags) +#define inet6_assign_bit(nr, sk, val) \ + assign_bit(INET_FLAGS_##nr, &inet_sk(sk)->inet_flags, val) + /* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */ struct raw6_sock { /* inet_sock has to be the first member of raw6_sock */ |