@@ -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