@@ -2171,13 +2171,15 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
21712171	maybe_add_creds (skb , sock , other );
21722172	skb_get (skb );
21732173
2174+ 	scm_stat_add (other , skb );
2175+ 
2176+ 	spin_lock (& other -> sk_receive_queue .lock );
21742177	if  (ousk -> oob_skb )
21752178		consume_skb (ousk -> oob_skb );
2176- 
21772179	WRITE_ONCE (ousk -> oob_skb , skb );
2180+ 	__skb_queue_tail (& other -> sk_receive_queue , skb );
2181+ 	spin_unlock (& other -> sk_receive_queue .lock );
21782182
2179- 	scm_stat_add (other , skb );
2180- 	skb_queue_tail (& other -> sk_receive_queue , skb );
21812183	sk_send_sigurg (other );
21822184	unix_state_unlock (other );
21832185	other -> sk_data_ready (other );
@@ -2568,8 +2570,10 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
25682570
25692571	mutex_lock (& u -> iolock );
25702572	unix_state_lock (sk );
2573+ 	spin_lock (& sk -> sk_receive_queue .lock );
25712574
25722575	if  (sock_flag (sk , SOCK_URGINLINE ) ||  !u -> oob_skb ) {
2576+ 		spin_unlock (& sk -> sk_receive_queue .lock );
25732577		unix_state_unlock (sk );
25742578		mutex_unlock (& u -> iolock );
25752579		return  - EINVAL ;
@@ -2581,6 +2585,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
25812585		WRITE_ONCE (u -> oob_skb , NULL );
25822586	else 
25832587		skb_get (oob_skb );
2588+ 
2589+ 	spin_unlock (& sk -> sk_receive_queue .lock );
25842590	unix_state_unlock (sk );
25852591
25862592	chunk  =  state -> recv_actor (oob_skb , 0 , chunk , state );
@@ -2609,6 +2615,10 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
26092615		consume_skb (skb );
26102616		skb  =  NULL ;
26112617	} else  {
2618+ 		struct  sk_buff  * unlinked_skb  =  NULL ;
2619+ 
2620+ 		spin_lock (& sk -> sk_receive_queue .lock );
2621+ 
26122622		if  (skb  ==  u -> oob_skb ) {
26132623			if  (copied ) {
26142624				skb  =  NULL ;
@@ -2620,13 +2630,19 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
26202630			} else  if  (flags  &  MSG_PEEK ) {
26212631				skb  =  NULL ;
26222632			} else  {
2623- 				skb_unlink (skb , & sk -> sk_receive_queue );
2633+ 				__skb_unlink (skb , & sk -> sk_receive_queue );
26242634				WRITE_ONCE (u -> oob_skb , NULL );
2625- 				if  (!WARN_ON_ONCE (skb_unref (skb )))
2626- 					kfree_skb (skb );
2635+ 				unlinked_skb  =  skb ;
26272636				skb  =  skb_peek (& sk -> sk_receive_queue );
26282637			}
26292638		}
2639+ 
2640+ 		spin_unlock (& sk -> sk_receive_queue .lock );
2641+ 
2642+ 		if  (unlinked_skb ) {
2643+ 			WARN_ON_ONCE (skb_unref (unlinked_skb ));
2644+ 			kfree_skb (unlinked_skb );
2645+ 		}
26302646	}
26312647	return  skb ;
26322648}
0 commit comments