Skip to content

Commit

Permalink
net: annotate data-races around sk->sk_priority
Browse files Browse the repository at this point in the history
[ Upstream commit 8bf43be ]

sk_getsockopt() runs locklessly. This means sk->sk_priority
can be read while other threads are changing its value.

Other reads also happen without socket lock being held.

Add missing annotations where needed.

Fixes: 1da177e ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Eric Dumazet authored and gregkh committed Aug 11, 2023
1 parent 6326c83 commit 12d4ba1
Show file tree
Hide file tree
Showing 8 changed files with 14 additions and 13 deletions.
6 changes: 3 additions & 3 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ EXPORT_SYMBOL(sock_no_linger);
void sock_set_priority(struct sock *sk, u32 priority)
{
lock_sock(sk);
sk->sk_priority = priority;
WRITE_ONCE(sk->sk_priority, priority);
release_sock(sk);
}
EXPORT_SYMBOL(sock_set_priority);
Expand Down Expand Up @@ -1203,7 +1203,7 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
if ((val >= 0 && val <= 6) ||
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
sk->sk_priority = val;
WRITE_ONCE(sk->sk_priority, val);
else
ret = -EPERM;
break;
Expand Down Expand Up @@ -1670,7 +1670,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
break;

case SO_PRIORITY:
v.val = sk->sk_priority;
v.val = READ_ONCE(sk->sk_priority);
break;

case SO_LINGER:
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
ip_options_build(skb, &opt->opt, daddr, rt);
}

skb->priority = sk->sk_priority;
skb->priority = READ_ONCE(sk->sk_priority);
if (!skb->mark)
skb->mark = READ_ONCE(sk->sk_mark);

Expand Down Expand Up @@ -526,7 +526,7 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
skb_shinfo(skb)->gso_segs ?: 1);

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

res = ip_local_out(net, sk, skb);
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/ip_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ void __ip_sock_set_tos(struct sock *sk, int val)
}
if (inet_sk(sk)->tos != val) {
inet_sk(sk)->tos = val;
sk->sk_priority = rt_tos2priority(val);
WRITE_ONCE(sk->sk_priority, rt_tos2priority(val));
sk_dst_reset(sk);
}
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
goto error;
skb_reserve(skb, hlen);

skb->priority = sk->sk_priority;
skb->priority = READ_ONCE(sk->sk_priority);
skb->mark = sockc->mark;
skb->tstamp = sockc->transmit_time;
skb_dst_set(skb, &rt->dst);
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ static void tcp_v4_send_ack(const struct sock *sk,
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
inet_twsk(sk)->tw_priority : sk->sk_priority;
inet_twsk(sk)->tw_priority : READ_ONCE(sk->sk_priority);
transmit_time = tcp_transmit_time(sk);
ip_send_unicast_reply(ctl_sk,
skb, &TCP_SKB_CB(skb)->header.h4.opt,
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
skb_reserve(skb, hlen);

skb->protocol = htons(ETH_P_IPV6);
skb->priority = sk->sk_priority;
skb->priority = READ_ONCE(sk->sk_priority);
skb->mark = sockc->mark;
skb->tstamp = sockc->transmit_time;

Expand Down
3 changes: 2 additions & 1 deletion net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,8 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index),
ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority,
ipv6_get_dsfield(ipv6_hdr(skb)), 0,
READ_ONCE(sk->sk_priority),
READ_ONCE(tcp_rsk(req)->txhash));
}

Expand Down
6 changes: 3 additions & 3 deletions net/packet/af_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -2052,7 +2052,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg,

skb->protocol = proto;
skb->dev = dev;
skb->priority = sk->sk_priority;
skb->priority = READ_ONCE(sk->sk_priority);
skb->mark = READ_ONCE(sk->sk_mark);
skb->tstamp = sockc.transmit_time;

Expand Down Expand Up @@ -2575,7 +2575,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,

skb->protocol = proto;
skb->dev = dev;
skb->priority = po->sk.sk_priority;
skb->priority = READ_ONCE(po->sk.sk_priority);
skb->mark = READ_ONCE(po->sk.sk_mark);
skb->tstamp = sockc->transmit_time;
skb_setup_tx_timestamp(skb, sockc->tsflags);
Expand Down Expand Up @@ -3052,7 +3052,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)

skb->protocol = proto;
skb->dev = dev;
skb->priority = sk->sk_priority;
skb->priority = READ_ONCE(sk->sk_priority);
skb->mark = sockc.mark;
skb->tstamp = sockc.transmit_time;

Expand Down

0 comments on commit 12d4ba1

Please sign in to comment.