This is a note to let you know that I've just added the patch titled
macvtap: zerocopy: validate vectors before building skb
to the 3.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
macvtap-zerocopy-validate-vectors-before-building-skb.patch
and it can be found in the queue-3.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
>From b92946e2919134ebe2a4083e4302236295ea2a73 Mon Sep 17 00:00:00 2001
From: Jason Wang <[email protected]>
Date: Wed, 2 May 2012 11:42:15 +0800
Subject: macvtap: zerocopy: validate vectors before building skb
From: Jason Wang <[email protected]>
commit b92946e2919134ebe2a4083e4302236295ea2a73 upstream.
There're several reasons that the vectors need to be validated:
- Return error when caller provides vectors whose num is greater than
UIO_MAXIOV.
- Linearize part of skb when userspace provides vectors grater than
MAX_SKB_FRAGS.
- Return error when userspace provides vectors whose total length may exceed
- MAX_SKB_FRAGS * PAGE_SIZE.
Signed-off-by: Jason Wang <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
Cc: Josh Boyer <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/macvtap.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -528,9 +528,10 @@ static int zerocopy_sg_from_iovec(struct
}
base = (unsigned long)from->iov_base + offset1;
size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
+ if (i + size > MAX_SKB_FRAGS)
+ return -EMSGSIZE;
num_pages = get_user_pages_fast(base, size, 0, &page[i]);
- if ((num_pages != size) ||
- (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags))
+ if (num_pages != size)
/* put_page is in skb free */
return -EFAULT;
skb->data_len += len;
@@ -647,7 +648,7 @@ static ssize_t macvtap_get_user(struct m
int err;
struct virtio_net_hdr vnet_hdr = { 0 };
int vnet_hdr_len = 0;
- int copylen;
+ int copylen = 0;
bool zerocopy = false;
if (q->flags & IFF_VNET_HDR) {
@@ -676,15 +677,31 @@ static ssize_t macvtap_get_user(struct m
if (unlikely(len < ETH_HLEN))
goto err;
+ err = -EMSGSIZE;
+ if (unlikely(count > UIO_MAXIOV))
+ goto err;
+
if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY))
zerocopy = true;
if (zerocopy) {
+ /* Userspace may produce vectors with count greater than
+ * MAX_SKB_FRAGS, so we need to linearize parts of the skb
+ * to let the rest of data to be fit in the frags.
+ */
+ if (count > MAX_SKB_FRAGS) {
+ copylen = iov_length(iv, count - MAX_SKB_FRAGS);
+ if (copylen < vnet_hdr_len)
+ copylen = 0;
+ else
+ copylen -= vnet_hdr_len;
+ }
/* There are 256 bytes to be copied in skb, so there is enough
* room for skb expand head in case it is used.
* The rest buffer is mapped from userspace.
*/
- copylen = vnet_hdr.hdr_len;
+ if (copylen < vnet_hdr.hdr_len)
+ copylen = vnet_hdr.hdr_len;
if (!copylen)
copylen = GOODCOPY_LEN;
} else
Patches currently in stable-queue which might be from [email protected] are
queue-3.4/macvtap-zerocopy-validate-vectors-before-building-skb.patch
queue-3.4/net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html