@@ -2147,13 +2147,15 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
2147
2147
maybe_add_creds (skb , sock , other );
2148
2148
skb_get (skb );
2149
2149
2150
+ scm_stat_add (other , skb );
2151
+
2152
+ spin_lock (& other -> sk_receive_queue .lock );
2150
2153
if (ousk -> oob_skb )
2151
2154
consume_skb (ousk -> oob_skb );
2152
-
2153
2155
WRITE_ONCE (ousk -> oob_skb , skb );
2156
+ __skb_queue_tail (& other -> sk_receive_queue , skb );
2157
+ spin_unlock (& other -> sk_receive_queue .lock );
2154
2158
2155
- scm_stat_add (other , skb );
2156
- skb_queue_tail (& other -> sk_receive_queue , skb );
2157
2159
sk_send_sigurg (other );
2158
2160
unix_state_unlock (other );
2159
2161
other -> sk_data_ready (other );
@@ -2538,8 +2540,10 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2538
2540
2539
2541
mutex_lock (& u -> iolock );
2540
2542
unix_state_lock (sk );
2543
+ spin_lock (& sk -> sk_receive_queue .lock );
2541
2544
2542
2545
if (sock_flag (sk , SOCK_URGINLINE ) || !u -> oob_skb ) {
2546
+ spin_unlock (& sk -> sk_receive_queue .lock );
2543
2547
unix_state_unlock (sk );
2544
2548
mutex_unlock (& u -> iolock );
2545
2549
return - EINVAL ;
@@ -2551,6 +2555,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2551
2555
WRITE_ONCE (u -> oob_skb , NULL );
2552
2556
else
2553
2557
skb_get (oob_skb );
2558
+
2559
+ spin_unlock (& sk -> sk_receive_queue .lock );
2554
2560
unix_state_unlock (sk );
2555
2561
2556
2562
chunk = state -> recv_actor (oob_skb , 0 , chunk , state );
@@ -2579,6 +2585,10 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
2579
2585
consume_skb (skb );
2580
2586
skb = NULL ;
2581
2587
} else {
2588
+ struct sk_buff * unlinked_skb = NULL ;
2589
+
2590
+ spin_lock (& sk -> sk_receive_queue .lock );
2591
+
2582
2592
if (skb == u -> oob_skb ) {
2583
2593
if (copied ) {
2584
2594
skb = NULL ;
@@ -2590,13 +2600,19 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
2590
2600
} else if (flags & MSG_PEEK ) {
2591
2601
skb = NULL ;
2592
2602
} else {
2593
- skb_unlink (skb , & sk -> sk_receive_queue );
2603
+ __skb_unlink (skb , & sk -> sk_receive_queue );
2594
2604
WRITE_ONCE (u -> oob_skb , NULL );
2595
- if (!WARN_ON_ONCE (skb_unref (skb )))
2596
- kfree_skb (skb );
2605
+ unlinked_skb = skb ;
2597
2606
skb = skb_peek (& sk -> sk_receive_queue );
2598
2607
}
2599
2608
}
2609
+
2610
+ spin_unlock (& sk -> sk_receive_queue .lock );
2611
+
2612
+ if (unlinked_skb ) {
2613
+ WARN_ON_ONCE (skb_unref (unlinked_skb ));
2614
+ kfree_skb (unlinked_skb );
2615
+ }
2600
2616
}
2601
2617
return skb ;
2602
2618
}
0 commit comments