forked from mirrors/linux
		
	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) | ||||
| { | ||||
| 	lock_sock(sk); | ||||
| 	sk->sk_priority = priority; | ||||
| 	WRITE_ONCE(sk->sk_priority, priority); | ||||
| 	release_sock(sk); | ||||
| } | ||||
| EXPORT_SYMBOL(sock_set_priority); | ||||
|  | @ -1216,7 +1216,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; | ||||
|  | @ -1685,7 +1685,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: | ||||
|  |  | |||
|  | @ -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); | ||||
| 	} | ||||
| 
 | ||||
| 	skb->priority = sk->sk_priority; | ||||
| 	skb->priority = READ_ONCE(sk->sk_priority); | ||||
| 	if (!skb->mark) | ||||
| 		skb->mark = READ_ONCE(sk->sk_mark); | ||||
| 
 | ||||
|  | @ -528,7 +528,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); | ||||
|  |  | |||
|  | @ -592,7 +592,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); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -348,7 +348,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); | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -614,7 +614,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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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, | ||||
| 			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)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2050,7 +2050,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; | ||||
| 
 | ||||
|  | @ -2585,7 +2585,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); | ||||
|  | @ -3061,7 +3061,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; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric Dumazet
						Eric Dumazet