Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / packet / af_packet.c
index 07c04a8..efa8445 100644 (file)
@@ -1676,7 +1676,7 @@ retry:
                        if (len < hhlen)
                                skb_reset_network_header(skb);
                }
-               err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+               err = memcpy_from_msg(skb_put(skb, len), msg, len);
                if (err)
                        goto out_free;
                goto retry;
@@ -2095,6 +2095,18 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
        sock_wfree(skb);
 }
 
+static bool ll_header_truncated(const struct net_device *dev, int len)
+{
+       /* net device doesn't like empty head */
+       if (unlikely(len <= dev->hard_header_len)) {
+               net_warn_ratelimited("%s: packet size is too short (%d < %d)\n",
+                                    current->comm, len, dev->hard_header_len);
+               return true;
+       }
+
+       return false;
+}
+
 static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
                void *frame, struct net_device *dev, int size_max,
                __be16 proto, unsigned char *addr, int hlen)
@@ -2170,12 +2182,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
                if (unlikely(err < 0))
                        return -EINVAL;
        } else if (dev->hard_header_len) {
-               /* net device doesn't like empty head */
-               if (unlikely(tp_len <= dev->hard_header_len)) {
-                       pr_err("packet size is too short (%d < %d)\n",
-                              tp_len, dev->hard_header_len);
+               if (ll_header_truncated(dev, tp_len))
                        return -EINVAL;
-               }
 
                skb_push(skb, dev->hard_header_len);
                err = skb_store_bits(skb, 0, data,
@@ -2400,6 +2408,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        unsigned short gso_type = 0;
        int hlen, tlen;
        int extra_len = 0;
+       struct iov_iter from;
+       ssize_t n;
+
+       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        /*
         *      Get and verify the address.
@@ -2438,9 +2450,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 
                len -= vnet_hdr_len;
 
-               err = memcpy_fromiovec((void *)&vnet_hdr, msg->msg_iov,
-                                      vnet_hdr_len);
-               if (err < 0)
+               err = -EFAULT;
+               n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
+               if (n != vnet_hdr_len)
                        goto out_unlock;
 
                if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -2500,12 +2512,17 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        skb_set_network_header(skb, reserve);
 
        err = -EINVAL;
-       if (sock->type == SOCK_DGRAM &&
-           (offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len)) < 0)
-               goto out_free;
+       if (sock->type == SOCK_DGRAM) {
+               offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len);
+               if (unlikely(offset) < 0)
+                       goto out_free;
+       } else {
+               if (ll_header_truncated(dev, len))
+                       goto out_free;
+       }
 
        /* Returns -EFAULT on error */
-       err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
+       err = skb_copy_datagram_from_iter(skb, offset, &from, len);
        if (err)
                goto out_free;
 
@@ -2937,8 +2954,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
                        vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;
                } /* else everything is zero */
 
-               err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr,
-                                    vnet_hdr_len);
+               err = memcpy_to_msg(msg, (void *)&vnet_hdr, vnet_hdr_len);
                if (err < 0)
                        goto out_free;
        }
@@ -2953,7 +2969,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free;