summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch84
1 files changed, 84 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch
new file mode 100644
index 00000000..a46ddcbc
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0020-macvtap-zerocopy-validate-vectors-before-building-sk.patch
@@ -0,0 +1,84 @@
1From c93ad33631e3efbb6f02f24c6b6817227b2c9252 Mon Sep 17 00:00:00 2001
2From: Jason Wang <jasowang@redhat.com>
3Date: Wed, 2 May 2012 11:42:15 +0800
4Subject: [PATCH 020/109] macvtap: zerocopy: validate vectors before building
5 skb
6
7commit b92946e2919134ebe2a4083e4302236295ea2a73 upstream.
8
9There're several reasons that the vectors need to be validated:
10
11- Return error when caller provides vectors whose num is greater than UIO_MAXIOV.
12- Linearize part of skb when userspace provides vectors grater than MAX_SKB_FRAGS.
13- Return error when userspace provides vectors whose total length may exceed
14- MAX_SKB_FRAGS * PAGE_SIZE.
15
16Signed-off-by: Jason Wang <jasowang@redhat.com>
17Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
18Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
19---
20 drivers/net/macvtap.c | 25 +++++++++++++++++++++----
21 1 files changed, 21 insertions(+), 4 deletions(-)
22
23diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
24index 7fecd66..26106c0 100644
25--- a/drivers/net/macvtap.c
26+++ b/drivers/net/macvtap.c
27@@ -528,9 +528,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
28 }
29 base = (unsigned long)from->iov_base + offset;
30 size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
31+ if (i + size > MAX_SKB_FRAGS)
32+ return -EMSGSIZE;
33 num_pages = get_user_pages_fast(base, size, 0, &page[i]);
34- if ((num_pages != size) ||
35- (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags)) {
36+ if (num_pages != size) {
37 for (i = 0; i < num_pages; i++)
38 put_page(page[i]);
39 return -EFAULT;
40@@ -650,7 +651,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
41 int err;
42 struct virtio_net_hdr vnet_hdr = { 0 };
43 int vnet_hdr_len = 0;
44- int copylen;
45+ int copylen = 0;
46 bool zerocopy = false;
47
48 if (q->flags & IFF_VNET_HDR) {
49@@ -679,15 +680,31 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
50 if (unlikely(len < ETH_HLEN))
51 goto err;
52
53+ err = -EMSGSIZE;
54+ if (unlikely(count > UIO_MAXIOV))
55+ goto err;
56+
57 if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY))
58 zerocopy = true;
59
60 if (zerocopy) {
61+ /* Userspace may produce vectors with count greater than
62+ * MAX_SKB_FRAGS, so we need to linearize parts of the skb
63+ * to let the rest of data to be fit in the frags.
64+ */
65+ if (count > MAX_SKB_FRAGS) {
66+ copylen = iov_length(iv, count - MAX_SKB_FRAGS);
67+ if (copylen < vnet_hdr_len)
68+ copylen = 0;
69+ else
70+ copylen -= vnet_hdr_len;
71+ }
72 /* There are 256 bytes to be copied in skb, so there is enough
73 * room for skb expand head in case it is used.
74 * The rest buffer is mapped from userspace.
75 */
76- copylen = vnet_hdr.hdr_len;
77+ if (copylen < vnet_hdr.hdr_len)
78+ copylen = vnet_hdr.hdr_len;
79 if (!copylen)
80 copylen = GOODCOPY_LEN;
81 } else
82--
831.7.7.6
84