@@ -2171,13 +2171,15 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
2171
2171
maybe_add_creds (skb , sock , other );
2172
2172
skb_get (skb );
2173
2173
2174
+ scm_stat_add (other , skb );
2175
+
2176
+ spin_lock (& other -> sk_receive_queue .lock );
2174
2177
if (ousk -> oob_skb )
2175
2178
consume_skb (ousk -> oob_skb );
2176
-
2177
2179
WRITE_ONCE (ousk -> oob_skb , skb );
2180
+ __skb_queue_tail (& other -> sk_receive_queue , skb );
2181
+ spin_unlock (& other -> sk_receive_queue .lock );
2178
2182
2179
- scm_stat_add (other , skb );
2180
- skb_queue_tail (& other -> sk_receive_queue , skb );
2181
2183
sk_send_sigurg (other );
2182
2184
unix_state_unlock (other );
2183
2185
other -> sk_data_ready (other );
@@ -2568,8 +2570,10 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2568
2570
2569
2571
mutex_lock (& u -> iolock );
2570
2572
unix_state_lock (sk );
2573
+ spin_lock (& sk -> sk_receive_queue .lock );
2571
2574
2572
2575
if (sock_flag (sk , SOCK_URGINLINE ) || !u -> oob_skb ) {
2576
+ spin_unlock (& sk -> sk_receive_queue .lock );
2573
2577
unix_state_unlock (sk );
2574
2578
mutex_unlock (& u -> iolock );
2575
2579
return - EINVAL ;
@@ -2581,6 +2585,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2581
2585
WRITE_ONCE (u -> oob_skb , NULL );
2582
2586
else
2583
2587
skb_get (oob_skb );
2588
+
2589
+ spin_unlock (& sk -> sk_receive_queue .lock );
2584
2590
unix_state_unlock (sk );
2585
2591
2586
2592
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,
2609
2615
consume_skb (skb );
2610
2616
skb = NULL ;
2611
2617
} else {
2618
+ struct sk_buff * unlinked_skb = NULL ;
2619
+
2620
+ spin_lock (& sk -> sk_receive_queue .lock );
2621
+
2612
2622
if (skb == u -> oob_skb ) {
2613
2623
if (copied ) {
2614
2624
skb = NULL ;
@@ -2620,13 +2630,19 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
2620
2630
} else if (flags & MSG_PEEK ) {
2621
2631
skb = NULL ;
2622
2632
} else {
2623
- skb_unlink (skb , & sk -> sk_receive_queue );
2633
+ __skb_unlink (skb , & sk -> sk_receive_queue );
2624
2634
WRITE_ONCE (u -> oob_skb , NULL );
2625
- if (!WARN_ON_ONCE (skb_unref (skb )))
2626
- kfree_skb (skb );
2635
+ unlinked_skb = skb ;
2627
2636
skb = skb_peek (& sk -> sk_receive_queue );
2628
2637
}
2629
2638
}
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
+ }
2630
2646
}
2631
2647
return skb ;
2632
2648
}
0 commit comments