Skip to content

Commit 3c5b4d6

Browse files
edumazetdavem330
authored andcommitted
net: annotate data-races around sk->sk_mark
sk->sk_mark is often read while another thread could change the value. Fixes: 4a19ec5 ("[NET]: Introducing socket mark socket option.") Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b4b5532 commit 3c5b4d6

File tree

23 files changed

+42
-40
lines changed

23 files changed

+42
-40
lines changed

include/net/inet_sock.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,12 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
107107

108108
static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
109109
{
110-
if (!sk->sk_mark &&
111-
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
110+
u32 mark = READ_ONCE(sk->sk_mark);
111+
112+
if (!mark && READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
112113
return skb->mark;
113114

114-
return sk->sk_mark;
115+
return mark;
115116
}
116117

117118
static inline int inet_request_bound_dev_if(const struct sock *sk,

include/net/ip.h

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

96-
ipcm->sockc.mark = inet->sk.sk_mark;
96+
ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark);
9797
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
9898
ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if);
9999
ipcm->addr = inet->inet_saddr;

include/net/route.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
168168
__be16 dport, __be16 sport,
169169
__u8 proto, __u8 tos, int oif)
170170
{
171-
flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
171+
flowi4_init_output(fl4, oif, sk ? READ_ONCE(sk->sk_mark) : 0, tos,
172172
RT_SCOPE_UNIVERSE, proto,
173173
sk ? inet_sk_flowi_flags(sk) : 0,
174174
daddr, saddr, dport, sport, sock_net_uid(net, sk));
@@ -301,7 +301,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst,
301301
if (inet_sk(sk)->transparent)
302302
flow_flags |= FLOWI_FLAG_ANYSRC;
303303

304-
flowi4_init_output(fl4, oif, sk->sk_mark, ip_sock_rt_tos(sk),
304+
flowi4_init_output(fl4, oif, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk),
305305
ip_sock_rt_scope(sk), protocol, flow_flags, dst,
306306
src, dport, sport, sk->sk_uid);
307307
}

net/can/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
865865

866866
skb->dev = dev;
867867
skb->priority = sk->sk_priority;
868-
skb->mark = sk->sk_mark;
868+
skb->mark = READ_ONCE(sk->sk_mark);
869869
skb->tstamp = sockc.transmit_time;
870870

871871
skb_setup_tx_timestamp(skb, sockc.tsflags);

net/core/sock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf);
990990
static void __sock_set_mark(struct sock *sk, u32 val)
991991
{
992992
if (val != sk->sk_mark) {
993-
sk->sk_mark = val;
993+
WRITE_ONCE(sk->sk_mark, val);
994994
sk_dst_reset(sk);
995995
}
996996
}
@@ -1851,7 +1851,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18511851
optval, optlen, len);
18521852

18531853
case SO_MARK:
1854-
v.val = sk->sk_mark;
1854+
v.val = READ_ONCE(sk->sk_mark);
18551855
break;
18561856

18571857
case SO_RCVMARK:

net/dccp/ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
238238
opt = ireq->ipv6_opt;
239239
if (!opt)
240240
opt = rcu_dereference(np->opt);
241-
err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass,
242-
sk->sk_priority);
241+
err = ip6_xmit(sk, skb, &fl6, READ_ONCE(sk->sk_mark), opt,
242+
np->tclass, sk->sk_priority);
243243
rcu_read_unlock();
244244
err = net_xmit_eval(err);
245245
}

net/ipv4/inet_diag.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
150150
}
151151
#endif
152152

153-
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
153+
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, READ_ONCE(sk->sk_mark)))
154154
goto errout;
155155

156156
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
@@ -799,7 +799,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
799799
entry.ifindex = sk->sk_bound_dev_if;
800800
entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0;
801801
if (sk_fullsock(sk))
802-
entry.mark = sk->sk_mark;
802+
entry.mark = READ_ONCE(sk->sk_mark);
803803
else if (sk->sk_state == TCP_NEW_SYN_RECV)
804804
entry.mark = inet_rsk(inet_reqsk(sk))->ir_mark;
805805
else if (sk->sk_state == TCP_TIME_WAIT)

net/ipv4/ip_output.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
186186

187187
skb->priority = sk->sk_priority;
188188
if (!skb->mark)
189-
skb->mark = sk->sk_mark;
189+
skb->mark = READ_ONCE(sk->sk_mark);
190190

191191
/* Send it out. */
192192
return ip_local_out(net, skb->sk, skb);
@@ -529,7 +529,7 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
529529

530530
/* TODO : should we use skb->sk here instead of sk ? */
531531
skb->priority = sk->sk_priority;
532-
skb->mark = sk->sk_mark;
532+
skb->mark = READ_ONCE(sk->sk_mark);
533533

534534
res = ip_local_out(net, sk, skb);
535535
rcu_read_unlock();

net/ipv4/route.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
518518
const struct inet_sock *inet = inet_sk(sk);
519519

520520
oif = sk->sk_bound_dev_if;
521-
mark = sk->sk_mark;
521+
mark = READ_ONCE(sk->sk_mark);
522522
tos = ip_sock_rt_tos(sk);
523523
scope = ip_sock_rt_scope(sk);
524524
prot = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol;
@@ -552,7 +552,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
552552
inet_opt = rcu_dereference(inet->inet_opt);
553553
if (inet_opt && inet_opt->opt.srr)
554554
daddr = inet_opt->opt.faddr;
555-
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
555+
flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark),
556556
ip_sock_rt_tos(sk) & IPTOS_RT_MASK,
557557
ip_sock_rt_scope(sk),
558558
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,

net/ipv4/tcp_ipv4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ static void tcp_v4_send_ack(const struct sock *sk,
931931
ctl_sk = this_cpu_read(ipv4_tcp_sk);
932932
sock_net_set(ctl_sk, net);
933933
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
934-
inet_twsk(sk)->tw_mark : sk->sk_mark;
934+
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
935935
ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
936936
inet_twsk(sk)->tw_priority : sk->sk_priority;
937937
transmit_time = tcp_transmit_time(sk);

0 commit comments

Comments
 (0)