@@ -2654,11 +2654,10 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
int flags, int copied)
{
+ struct sk_buff *unlinked_skb = NULL;
struct unix_sock *u = unix_sk(sk);
if (!unix_skb_len(skb)) {
- struct sk_buff *unlinked_skb = NULL;
-
spin_lock(&sk->sk_receive_queue.lock);
if (copied && (!u->oob_skb || skb == u->oob_skb)) {
@@ -2674,31 +2673,33 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
spin_unlock(&sk->sk_receive_queue.lock);
consume_skb(unlinked_skb);
- } else {
- struct sk_buff *unlinked_skb = NULL;
+ return skb;
+ }
- spin_lock(&sk->sk_receive_queue.lock);
+ spin_lock(&sk->sk_receive_queue.lock);
- if (skb == u->oob_skb) {
- if (copied) {
- skb = NULL;
- } else if (!(flags & MSG_PEEK)) {
- WRITE_ONCE(u->oob_skb, NULL);
-
- if (!sock_flag(sk, SOCK_URGINLINE)) {
- __skb_unlink(skb, &sk->sk_receive_queue);
- unlinked_skb = skb;
- skb = skb_peek(&sk->sk_receive_queue);
- }
- } else if (!sock_flag(sk, SOCK_URGINLINE)) {
- skb = skb_peek_next(skb, &sk->sk_receive_queue);
- }
- }
+ if (skb != u->oob_skb)
+ goto unlock;
- spin_unlock(&sk->sk_receive_queue.lock);
+ if (copied) {
+ skb = NULL;
+ } else if (!(flags & MSG_PEEK)) {
+ WRITE_ONCE(u->oob_skb, NULL);
- kfree_skb(unlinked_skb);
+ if (!sock_flag(sk, SOCK_URGINLINE)) {
+ __skb_unlink(skb, &sk->sk_receive_queue);
+ unlinked_skb = skb;
+ skb = skb_peek(&sk->sk_receive_queue);
+ }
+ } else if (!sock_flag(sk, SOCK_URGINLINE)) {
+ skb = skb_peek_next(skb, &sk->sk_receive_queue);
}
+
+unlock:
+ spin_unlock(&sk->sk_receive_queue.lock);
+
+ kfree_skb(unlinked_skb);
+
return skb;
}
#endif
This is a prep for the later fix. No functional change intended. Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> --- net/unix/af_unix.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-)