net: annotate data-races around sk->sk_priority
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: 1da177e4c3
("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e5f0d2dd3c
commit
8bf43be799
8 changed files with 14 additions and 13 deletions
|
@ -806,7 +806,7 @@ EXPORT_SYMBOL(sock_no_linger);
|
||||||
void sock_set_priority(struct sock *sk, u32 priority)
|
void sock_set_priority(struct sock *sk, u32 priority)
|
||||||
{
|
{
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
sk->sk_priority = priority;
|
WRITE_ONCE(sk->sk_priority, priority);
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(sock_set_priority);
|
EXPORT_SYMBOL(sock_set_priority);
|
||||||
|
@ -1216,7 +1216,7 @@ set_sndbuf:
|
||||||
if ((val >= 0 && val <= 6) ||
|
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_RAW) ||
|
||||||
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
|
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
|
||||||
sk->sk_priority = val;
|
WRITE_ONCE(sk->sk_priority, val);
|
||||||
else
|
else
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
break;
|
break;
|
||||||
|
@ -1685,7 +1685,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SO_PRIORITY:
|
case SO_PRIORITY:
|
||||||
v.val = sk->sk_priority;
|
v.val = READ_ONCE(sk->sk_priority);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SO_LINGER:
|
case SO_LINGER:
|
||||||
|
|
|
@ -184,7 +184,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
|
||||||
ip_options_build(skb, &opt->opt, daddr, rt);
|
ip_options_build(skb, &opt->opt, daddr, rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
skb->priority = sk->sk_priority;
|
skb->priority = READ_ONCE(sk->sk_priority);
|
||||||
if (!skb->mark)
|
if (!skb->mark)
|
||||||
skb->mark = READ_ONCE(sk->sk_mark);
|
skb->mark = READ_ONCE(sk->sk_mark);
|
||||||
|
|
||||||
|
@ -528,7 +528,7 @@ packet_routed:
|
||||||
skb_shinfo(skb)->gso_segs ?: 1);
|
skb_shinfo(skb)->gso_segs ?: 1);
|
||||||
|
|
||||||
/* TODO : should we use skb->sk here instead of sk ? */
|
/* 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);
|
skb->mark = READ_ONCE(sk->sk_mark);
|
||||||
|
|
||||||
res = ip_local_out(net, sk, skb);
|
res = ip_local_out(net, sk, skb);
|
||||||
|
|
|
@ -592,7 +592,7 @@ void __ip_sock_set_tos(struct sock *sk, int val)
|
||||||
}
|
}
|
||||||
if (inet_sk(sk)->tos != val) {
|
if (inet_sk(sk)->tos != val) {
|
||||||
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);
|
sk_dst_reset(sk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
|
||||||
goto error;
|
goto error;
|
||||||
skb_reserve(skb, hlen);
|
skb_reserve(skb, hlen);
|
||||||
|
|
||||||
skb->priority = sk->sk_priority;
|
skb->priority = READ_ONCE(sk->sk_priority);
|
||||||
skb->mark = sockc->mark;
|
skb->mark = sockc->mark;
|
||||||
skb->tstamp = sockc->transmit_time;
|
skb->tstamp = sockc->transmit_time;
|
||||||
skb_dst_set(skb, &rt->dst);
|
skb_dst_set(skb, &rt->dst);
|
||||||
|
|
|
@ -933,7 +933,7 @@ static void tcp_v4_send_ack(const struct sock *sk,
|
||||||
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
|
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
|
||||||
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
|
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
|
||||||
ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
|
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);
|
transmit_time = tcp_transmit_time(sk);
|
||||||
ip_send_unicast_reply(ctl_sk,
|
ip_send_unicast_reply(ctl_sk,
|
||||||
skb, &TCP_SKB_CB(skb)->header.h4.opt,
|
skb, &TCP_SKB_CB(skb)->header.h4.opt,
|
||||||
|
|
|
@ -614,7 +614,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
|
||||||
skb_reserve(skb, hlen);
|
skb_reserve(skb, hlen);
|
||||||
|
|
||||||
skb->protocol = htons(ETH_P_IPV6);
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
skb->priority = sk->sk_priority;
|
skb->priority = READ_ONCE(sk->sk_priority);
|
||||||
skb->mark = sockc->mark;
|
skb->mark = sockc->mark;
|
||||||
skb->tstamp = sockc->transmit_time;
|
skb->tstamp = sockc->transmit_time;
|
||||||
|
|
||||||
|
|
|
@ -1128,7 +1128,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,
|
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
|
||||||
READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
|
READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
|
||||||
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index),
|
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));
|
READ_ONCE(tcp_rsk(req)->txhash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2050,7 +2050,7 @@ retry:
|
||||||
|
|
||||||
skb->protocol = proto;
|
skb->protocol = proto;
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
skb->priority = sk->sk_priority;
|
skb->priority = READ_ONCE(sk->sk_priority);
|
||||||
skb->mark = READ_ONCE(sk->sk_mark);
|
skb->mark = READ_ONCE(sk->sk_mark);
|
||||||
skb->tstamp = sockc.transmit_time;
|
skb->tstamp = sockc.transmit_time;
|
||||||
|
|
||||||
|
@ -2585,7 +2585,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
|
||||||
|
|
||||||
skb->protocol = proto;
|
skb->protocol = proto;
|
||||||
skb->dev = dev;
|
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->mark = READ_ONCE(po->sk.sk_mark);
|
||||||
skb->tstamp = sockc->transmit_time;
|
skb->tstamp = sockc->transmit_time;
|
||||||
skb_setup_tx_timestamp(skb, sockc->tsflags);
|
skb_setup_tx_timestamp(skb, sockc->tsflags);
|
||||||
|
@ -3061,7 +3061,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||||
|
|
||||||
skb->protocol = proto;
|
skb->protocol = proto;
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
skb->priority = sk->sk_priority;
|
skb->priority = READ_ONCE(sk->sk_priority);
|
||||||
skb->mark = sockc.mark;
|
skb->mark = sockc.mark;
|
||||||
skb->tstamp = sockc.transmit_time;
|
skb->tstamp = sockc.transmit_time;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue