summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2013-01-21 14:40:47 -0800
committerBen Pfaff <blp@nicira.com>2013-01-21 14:40:47 -0800
commit38ab98d2165415289de2dcd17462f70b04e1788a (patch)
treee1ba7839b4d5045bb025e575324f0be61512a2b7
parent52704a5f7aa5230e6a316fe0e15585d98cd26fd3 (diff)
downloadopenvswitch-38ab98d2165415289de2dcd17462f70b04e1788a.tar.gz
datapath: Avoid null deref when GSO is for verifying header integrity only.
skb_gso_segment() has the following comment: * It may return NULL if the skb requires no segmentation. This is * only possible when GSO is used for verifying header integrity. Somehow queue_gso_packets() has never hit this case before, but some failures have suddenly been reported. This commit should fix the problem. Additional commentary by Jesse: We shouldn't normally be hitting this case because we're actually trying to do GSO, not header validation. However, I guess the guest/backend must be generating a packet with an MSS, which tricks us into thinking that it's GSO, but no GSO is actually requested. In the case of the bridge, header validation does take place so the situation is handled already. It seems not ideal that the network backend doesn't sanitize these packets but it's probably good that we handle it in any case. Bug #14772. Reported-by: Deepesh Govindan <dgovindan@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--datapath/datapath.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/datapath/datapath.c b/datapath/datapath.c
index c030cd29d..c4ef0d234 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007-2012 Nicira Networks.
+ * Copyright (c) 2007-2013 Nicira Networks.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -387,6 +387,8 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
segs = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM);
if (IS_ERR(segs))
return PTR_ERR(segs);
+ if (!segs)
+ return queue_userspace_packet(dp_ifindex, skb, upcall_info);
/* Queue all of the segments. */
skb = segs;