[Saucy] [PATCH] SRU: zerocopy LSO segmenting fixed
Anton Nayshtut
anton at swortex.com
Sun Jun 22 08:07:42 UTC 2014
BugLink: https://bugs.launchpad.net/bugs/1328973
[SRU Justification]
[Setup]
- 2 or more QEMU Guest VMs sharing the the same host
- the Guests are communicating using virtio-net-pci devices
- vhost-net is enabled
[Explanation]
If one Guest VM sends GSO packets to another while GRO is disabled for receiver,
so these packets are segmented by net/core.
In this case, if zero-copy is enabled in vhost-net, the GSO packets TX
completion is reported to userspace as before the TX is actually done.
The vhost-net's zero-copy mechanism is enabled by default since v3.8-rc1
(f9611c43).
[Impact]
Incorrect/junk data sent in case the transmitting Guest OS re-uses/frees the TX
buffer immediately upon TX completion.
[Test Case]
Windows 2008R2 Guest VMs running MS HCK Offload LSO test.
NOTE1: GRO is always disabled in this case because it's not supported by Windows
Guest virtio-net-pci drivers.
NOTE2: MS HCK re-uses the GSO (LSO) buffers, so it reproduces the issue every
time.
skbuff: skb_segment: orphan frags before copying
skb_segment copies frags around, so we need
to copy them carefully to avoid accessing
user memory after reporting completion to userspace
through a callback.
skb_segment doesn't normally happen on datapath:
TSO needs to be disabled - so disabling zero copy
in this case does not look like a big deal.
OriginalAuthor: Michael S. Tsirkin <mst at redhat.com>
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
Acked-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: David S. Miller <davem at davemloft.net>
(cherry picked from commit 1fd819ecb90cc9b822cd84d3056ddba315d3340f)
CVE-2014-0131
Signed-off-by: Andy Whitcroft <apw at canonical.com>
(backported from 0f860fb4f583909ed999df58abf57ff40ec94d6d ubuntu-trusty)
Signed-off-by: Anton Nayshtut <anton at swortex.com>
---
net/core/skbuff.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index abcad83..586bca9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2729,6 +2729,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int doffset = skb->data - skb_mac_header(skb);
+ struct sk_buff *frag_skb = skb;
unsigned int offset = doffset;
unsigned int tnl_hlen = skb_tnl_header_len(skb);
unsigned int headroom;
@@ -2769,6 +2770,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
if (!hsize && i >= nfrags) {
BUG_ON(fskb->len != len);
+ frag_skb = fskb;
pos += len;
nskb = skb_clone(fskb, GFP_ATOMIC);
fskb = fskb->next;
@@ -2838,6 +2840,8 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
while (pos < offset + len && i < nfrags) {
+ if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC)))
+ goto err;
*frag = skb_shinfo(skb)->frags[i];
__skb_frag_ref(frag);
size = skb_frag_size(frag);
--
1.7.9.5
More information about the kernel-team
mailing list