Revert "net: Fix skb_set_peeked use-after-free bug"
authorSasha Levin <sasha.levin@oracle.com>
Mon, 14 Dec 2015 17:11:09 +0000 (12:11 -0500)
committerSasha Levin <sasha.levin@oracle.com>
Mon, 14 Dec 2015 17:17:34 +0000 (12:17 -0500)
This reverts commit d9a1133495b487154ac351cd33b26b416e966d2d.

net/core/datagram.c

index 61e99f315ed9ac9b047651ab1e88b1a68731a83a..3a402a7b20e9ee5880adce23fa3f18a91f22a8d5 100644 (file)
@@ -130,35 +130,6 @@ static int wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
        goto out;
 }
 
-static int skb_set_peeked(struct sk_buff *skb)
-{
-       struct sk_buff *nskb;
-
-       if (skb->peeked)
-               return 0;
-
-       /* We have to unshare an skb before modifying it. */
-       if (!skb_shared(skb))
-               goto done;
-
-       nskb = skb_clone(skb, GFP_ATOMIC);
-       if (!nskb)
-               return -ENOMEM;
-
-       skb->prev->next = nskb;
-       skb->next->prev = nskb;
-       nskb->prev = skb->prev;
-       nskb->next = skb->next;
-
-       consume_skb(skb);
-       skb = nskb;
-
-done:
-       skb->peeked = 1;
-
-       return 0;
-}
-
 /**
  *     __skb_recv_datagram - Receive a datagram skbuff
  *     @sk: socket
@@ -193,9 +164,7 @@ static int skb_set_peeked(struct sk_buff *skb)
 struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
                                    int *peeked, int *off, int *err)
 {
-       struct sk_buff_head *queue = &sk->sk_receive_queue;
        struct sk_buff *skb, *last;
-       unsigned long cpu_flags;
        long timeo;
        /*
         * Caller is allowed not to check sk->sk_err before skb_recv_datagram()
@@ -214,6 +183,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
                 * Look at current nfs client by the way...
                 * However, this function was correct in any case. 8)
                 */
+               unsigned long cpu_flags;
+               struct sk_buff_head *queue = &sk->sk_receive_queue;
                int _off = *off;
 
                last = (struct sk_buff *)queue;
@@ -227,11 +198,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
                                        _off -= skb->len;
                                        continue;
                                }
-
-                               error = skb_set_peeked(skb);
-                               if (error)
-                                       goto unlock_err;
-
+                               skb->peeked = 1;
                                atomic_inc(&skb->users);
                        } else
                                __skb_unlink(skb, queue);
@@ -255,8 +222,6 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
 
        return NULL;
 
-unlock_err:
-       spin_unlock_irqrestore(&queue->lock, cpu_flags);
 no_packet:
        *err = error;
        return NULL;