Skip to content

Commit f2e977f

Browse files
committed
Merge branch 'net-data-race-annotations'
Eric Dumazet says: ==================== net: another round of data-race annotations Series inspired by some syzbot reports, taking care of 4 socket fields that can be read locklessly. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 82ba0ff + 251cd40 commit f2e977f

File tree

16 files changed

+76
-55
lines changed

16 files changed

+76
-55
lines changed

include/net/ip.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
9494
ipcm_init(ipcm);
9595

9696
ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark);
97-
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
97+
ipcm->sockc.tsflags = READ_ONCE(inet->sk.sk_tsflags);
9898
ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if);
9999
ipcm->addr = inet->inet_saddr;
100100
ipcm->protocol = inet->inet_num;

include/net/sock.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,12 @@ static inline void sk_wmem_queued_add(struct sock *sk, int val)
10531053
WRITE_ONCE(sk->sk_wmem_queued, sk->sk_wmem_queued + val);
10541054
}
10551055

1056+
static inline void sk_forward_alloc_add(struct sock *sk, int val)
1057+
{
1058+
/* Paired with lockless reads of sk->sk_forward_alloc */
1059+
WRITE_ONCE(sk->sk_forward_alloc, sk->sk_forward_alloc + val);
1060+
}
1061+
10561062
void sk_stream_write_space(struct sock *sk);
10571063

10581064
/* OOB backlog add */
@@ -1377,7 +1383,7 @@ static inline int sk_forward_alloc_get(const struct sock *sk)
13771383
if (sk->sk_prot->forward_alloc_get)
13781384
return sk->sk_prot->forward_alloc_get(sk);
13791385
#endif
1380-
return sk->sk_forward_alloc;
1386+
return READ_ONCE(sk->sk_forward_alloc);
13811387
}
13821388

13831389
static inline bool __sk_stream_memory_free(const struct sock *sk, int wake)
@@ -1673,14 +1679,14 @@ static inline void sk_mem_charge(struct sock *sk, int size)
16731679
{
16741680
if (!sk_has_account(sk))
16751681
return;
1676-
sk->sk_forward_alloc -= size;
1682+
sk_forward_alloc_add(sk, -size);
16771683
}
16781684

16791685
static inline void sk_mem_uncharge(struct sock *sk, int size)
16801686
{
16811687
if (!sk_has_account(sk))
16821688
return;
1683-
sk->sk_forward_alloc += size;
1689+
sk_forward_alloc_add(sk, size);
16841690
sk_mem_reclaim(sk);
16851691
}
16861692

@@ -1900,7 +1906,9 @@ struct sockcm_cookie {
19001906
static inline void sockcm_init(struct sockcm_cookie *sockc,
19011907
const struct sock *sk)
19021908
{
1903-
*sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags };
1909+
*sockc = (struct sockcm_cookie) {
1910+
.tsflags = READ_ONCE(sk->sk_tsflags)
1911+
};
19041912
}
19051913

19061914
int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg,
@@ -2695,20 +2703,20 @@ void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
26952703
static inline void
26962704
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
26972705
{
2698-
ktime_t kt = skb->tstamp;
26992706
struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
2700-
2707+
u32 tsflags = READ_ONCE(sk->sk_tsflags);
2708+
ktime_t kt = skb->tstamp;
27012709
/*
27022710
* generate control messages if
27032711
* - receive time stamping in software requested
27042712
* - software time stamp available and wanted
27052713
* - hardware time stamps available and wanted
27062714
*/
27072715
if (sock_flag(sk, SOCK_RCVTSTAMP) ||
2708-
(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
2709-
(kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
2716+
(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
2717+
(kt && tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
27102718
(hwtstamps->hwtstamp &&
2711-
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
2719+
(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
27122720
__sock_recv_timestamp(msg, sk, skb);
27132721
else
27142722
sock_write_timestamp(sk, kt);
@@ -2730,7 +2738,8 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
27302738
#define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \
27312739
SOF_TIMESTAMPING_RAW_HARDWARE)
27322740

2733-
if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY)
2741+
if (sk->sk_flags & FLAGS_RECV_CMSGS ||
2742+
READ_ONCE(sk->sk_tsflags) & TSFLAGS_ANY)
27342743
__sock_recv_cmsgs(msg, sk, skb);
27352744
else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
27362745
sock_write_timestamp(sk, skb->tstamp);

net/can/j1939/socket.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -974,20 +974,22 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
974974
struct sock_exterr_skb *serr;
975975
struct sk_buff *skb;
976976
char *state = "UNK";
977+
u32 tsflags;
977978
int err;
978979

979980
jsk = j1939_sk(sk);
980981

981982
if (!(jsk->state & J1939_SOCK_ERRQUEUE))
982983
return;
983984

985+
tsflags = READ_ONCE(sk->sk_tsflags);
984986
switch (type) {
985987
case J1939_ERRQUEUE_TX_ACK:
986-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK))
988+
if (!(tsflags & SOF_TIMESTAMPING_TX_ACK))
987989
return;
988990
break;
989991
case J1939_ERRQUEUE_TX_SCHED:
990-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED))
992+
if (!(tsflags & SOF_TIMESTAMPING_TX_SCHED))
991993
return;
992994
break;
993995
case J1939_ERRQUEUE_TX_ABORT:
@@ -997,7 +999,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
997999
case J1939_ERRQUEUE_RX_DPO:
9981000
fallthrough;
9991001
case J1939_ERRQUEUE_RX_ABORT:
1000-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE))
1002+
if (!(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE))
10011003
return;
10021004
break;
10031005
default:
@@ -1054,7 +1056,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
10541056
}
10551057

10561058
serr->opt_stats = true;
1057-
if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
1059+
if (tsflags & SOF_TIMESTAMPING_OPT_ID)
10581060
serr->ee.ee_data = session->tskey;
10591061

10601062
netdev_dbg(session->priv->ndev, "%s: 0x%p tskey: %i, state: %s\n",

net/core/skbuff.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5207,7 +5207,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
52075207
serr->ee.ee_info = tstype;
52085208
serr->opt_stats = opt_stats;
52095209
serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0;
5210-
if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
5210+
if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) {
52115211
serr->ee.ee_data = skb_shinfo(skb)->tskey;
52125212
if (sk_is_tcp(sk))
52135213
serr->ee.ee_data -= atomic_read(&sk->sk_tskey);
@@ -5263,21 +5263,23 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
52635263
{
52645264
struct sk_buff *skb;
52655265
bool tsonly, opt_stats = false;
5266+
u32 tsflags;
52665267

52675268
if (!sk)
52685269
return;
52695270

5270-
if (!hwtstamps && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) &&
5271+
tsflags = READ_ONCE(sk->sk_tsflags);
5272+
if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) &&
52715273
skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS)
52725274
return;
52735275

5274-
tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
5276+
tsonly = tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
52755277
if (!skb_may_tx_timestamp(sk, tsonly))
52765278
return;
52775279

52785280
if (tsonly) {
52795281
#ifdef CONFIG_INET
5280-
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
5282+
if ((tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
52815283
sk_is_tcp(sk)) {
52825284
skb = tcp_get_timestamping_opt_stats(sk, orig_skb,
52835285
ack_skb);

net/core/sock.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ static int sock_timestamping_bind_phc(struct sock *sk, int phc_index)
894894
if (!match)
895895
return -EINVAL;
896896

897-
sk->sk_bind_phc = phc_index;
897+
WRITE_ONCE(sk->sk_bind_phc, phc_index);
898898

899899
return 0;
900900
}
@@ -937,7 +937,7 @@ int sock_set_timestamping(struct sock *sk, int optname,
937937
return ret;
938938
}
939939

940-
sk->sk_tsflags = val;
940+
WRITE_ONCE(sk->sk_tsflags, val);
941941
sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
942942

943943
if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
@@ -1045,7 +1045,7 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
10451045
mem_cgroup_uncharge_skmem(sk->sk_memcg, pages);
10461046
return -ENOMEM;
10471047
}
1048-
sk->sk_forward_alloc += pages << PAGE_SHIFT;
1048+
sk_forward_alloc_add(sk, pages << PAGE_SHIFT);
10491049

10501050
WRITE_ONCE(sk->sk_reserved_mem,
10511051
sk->sk_reserved_mem + (pages << PAGE_SHIFT));
@@ -1719,8 +1719,8 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
17191719

17201720
case SO_TIMESTAMPING_OLD:
17211721
lv = sizeof(v.timestamping);
1722-
v.timestamping.flags = sk->sk_tsflags;
1723-
v.timestamping.bind_phc = sk->sk_bind_phc;
1722+
v.timestamping.flags = READ_ONCE(sk->sk_tsflags);
1723+
v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc);
17241724
break;
17251725

17261726
case SO_RCVTIMEO_OLD:
@@ -3139,10 +3139,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
31393139
{
31403140
int ret, amt = sk_mem_pages(size);
31413141

3142-
sk->sk_forward_alloc += amt << PAGE_SHIFT;
3142+
sk_forward_alloc_add(sk, amt << PAGE_SHIFT);
31433143
ret = __sk_mem_raise_allocated(sk, size, amt, kind);
31443144
if (!ret)
3145-
sk->sk_forward_alloc -= amt << PAGE_SHIFT;
3145+
sk_forward_alloc_add(sk, -(amt << PAGE_SHIFT));
31463146
return ret;
31473147
}
31483148
EXPORT_SYMBOL(__sk_mem_schedule);
@@ -3174,7 +3174,7 @@ void __sk_mem_reduce_allocated(struct sock *sk, int amount)
31743174
void __sk_mem_reclaim(struct sock *sk, int amount)
31753175
{
31763176
amount >>= PAGE_SHIFT;
3177-
sk->sk_forward_alloc -= amount << PAGE_SHIFT;
3177+
sk_forward_alloc_add(sk, -(amount << PAGE_SHIFT));
31783178
__sk_mem_reduce_allocated(sk, amount);
31793179
}
31803180
EXPORT_SYMBOL(__sk_mem_reclaim);
@@ -3743,7 +3743,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem)
37433743
mem[SK_MEMINFO_RCVBUF] = READ_ONCE(sk->sk_rcvbuf);
37443744
mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk);
37453745
mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf);
3746-
mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc;
3746+
mem[SK_MEMINFO_FWD_ALLOC] = sk_forward_alloc_get(sk);
37473747
mem[SK_MEMINFO_WMEM_QUEUED] = READ_ONCE(sk->sk_wmem_queued);
37483748
mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc);
37493749
mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len);

net/ipv4/ip_output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ static int __ip_append_data(struct sock *sk,
981981
paged = !!cork->gso_size;
982982

983983
if (cork->tx_flags & SKBTX_ANY_TSTAMP &&
984-
sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
984+
READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID)
985985
tskey = atomic_inc_return(&sk->sk_tskey) - 1;
986986

987987
hh_len = LL_RESERVED_SPACE(rt->dst.dev);

net/ipv4/ip_sockglue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk,
511511
* or without payload (SOF_TIMESTAMPING_OPT_TSONLY).
512512
*/
513513
info = PKTINFO_SKB_CB(skb);
514-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) ||
514+
if (!(READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_CMSG) ||
515515
!info->ipi_ifindex)
516516
return false;
517517

net/ipv4/tcp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,14 +2259,14 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
22592259
}
22602260
}
22612261

2262-
if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
2262+
if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_SOFTWARE)
22632263
has_timestamping = true;
22642264
else
22652265
tss->ts[0] = (struct timespec64) {0};
22662266
}
22672267

22682268
if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
2269-
if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)
2269+
if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_RAW_HARDWARE)
22702270
has_timestamping = true;
22712271
else
22722272
tss->ts[2] = (struct timespec64) {0};

net/ipv4/tcp_output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3474,7 +3474,7 @@ void sk_forced_mem_schedule(struct sock *sk, int size)
34743474
if (delta <= 0)
34753475
return;
34763476
amt = sk_mem_pages(delta);
3477-
sk->sk_forward_alloc += amt << PAGE_SHIFT;
3477+
sk_forward_alloc_add(sk, amt << PAGE_SHIFT);
34783478
sk_memory_allocated_add(sk, amt);
34793479

34803480
if (mem_cgroup_sockets_enabled && sk->sk_memcg)

net/ipv4/udp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,9 +1414,9 @@ static void udp_rmem_release(struct sock *sk, int size, int partial,
14141414
spin_lock(&sk_queue->lock);
14151415

14161416

1417-
sk->sk_forward_alloc += size;
1417+
sk_forward_alloc_add(sk, size);
14181418
amt = (sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1);
1419-
sk->sk_forward_alloc -= amt;
1419+
sk_forward_alloc_add(sk, -amt);
14201420

14211421
if (amt)
14221422
__sk_mem_reduce_allocated(sk, amt >> PAGE_SHIFT);
@@ -1527,7 +1527,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
15271527
goto uncharge_drop;
15281528
}
15291529

1530-
sk->sk_forward_alloc -= size;
1530+
sk_forward_alloc_add(sk, -size);
15311531

15321532
/* no need to setup a destructor, we will explicitly release the
15331533
* forward allocated memory on dequeue

net/ipv6/ip6_output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ static int __ip6_append_data(struct sock *sk,
15011501
orig_mtu = mtu;
15021502

15031503
if (cork->tx_flags & SKBTX_ANY_TSTAMP &&
1504-
sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
1504+
READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID)
15051505
tskey = atomic_inc_return(&sk->sk_tskey) - 1;
15061506

15071507
hh_len = LL_RESERVED_SPACE(rt->dst.dev);

net/ipv6/ping.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
119119
return -EINVAL;
120120

121121
ipcm6_init_sk(&ipc6, np);
122-
ipc6.sockc.tsflags = sk->sk_tsflags;
122+
ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags);
123123
ipc6.sockc.mark = READ_ONCE(sk->sk_mark);
124124

125125
fl6.flowi6_oif = oif;

net/ipv6/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
772772
fl6.flowi6_uid = sk->sk_uid;
773773

774774
ipcm6_init(&ipc6);
775-
ipc6.sockc.tsflags = sk->sk_tsflags;
775+
ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags);
776776
ipc6.sockc.mark = fl6.flowi6_mark;
777777

778778
if (sin6) {

net/ipv6/udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
13391339

13401340
ipcm6_init(&ipc6);
13411341
ipc6.gso_size = READ_ONCE(up->gso_size);
1342-
ipc6.sockc.tsflags = sk->sk_tsflags;
1342+
ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags);
13431343
ipc6.sockc.mark = READ_ONCE(sk->sk_mark);
13441344

13451345
/* destination address check */

0 commit comments

Comments
 (0)