]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - net/socket.c
UBUNTU: Start new release
[mirror_ubuntu-zesty-kernel.git] / net / socket.c
index 0758e13754e2faccb257d2f6ba9cca7b2da1baab..6361d3161120be2ad509b356166e7395afb21b9e 100644 (file)
@@ -654,6 +654,16 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
 }
 EXPORT_SYMBOL(kernel_sendmsg);
 
+static bool skb_is_err_queue(const struct sk_buff *skb)
+{
+       /* pkt_type of skbs enqueued on the error queue are set to
+        * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+        * in recvmsg, since skbs received on a local socket will never
+        * have a pkt_type of PACKET_OUTGOING.
+        */
+       return skb->pkt_type == PACKET_OUTGOING;
+}
+
 /*
  * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
  */
@@ -697,7 +707,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
                put_cmsg(msg, SOL_SOCKET,
                         SCM_TIMESTAMPING, sizeof(tss), &tss);
 
-               if (skb->len && (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS))
+               if (skb_is_err_queue(skb) && skb->len &&
+                   SKB_EXT_ERR(skb)->opt_stats)
                        put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
                                 skb->len, skb->data);
        }
@@ -2228,8 +2239,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                return err;
 
        err = sock_error(sock->sk);
-       if (err)
+       if (err) {
+               datagrams = err;
                goto out_put;
+       }
 
        entry = mmsg;
        compat_entry = (struct compat_mmsghdr __user *)mmsg;