diff mbox

[ovs-dev] dpif-netdev: Avoid using uninitialized memory with tunnel options.

Message ID 1450398489-72305-1-git-send-email-jesse@kernel.org
State Accepted
Headers show

Commit Message

Jesse Gross Dec. 18, 2015, 12:28 a.m. UTC
When handling an upcall with the userspace datapath, it's currently
possible for a flow from a packet with no tunnel options to come back
with matches on the options. If that happens, dpif-netdev will
attempt to translate the wildcards provided by ofproto into the format
used by dpif. The translation requires use of the original wildcards
from the flow, which since they didn't exist, is uninitalized memory.

Matching on fields which don't actually exist is itself a bug. However,
this can occur when we attempt to set a tunnel option on the packet -
ofproto generates a match on the field in the original packet. This is
being fixed separately.

In other situations where we have a match on an unexpected field, we
simply ignore it. This happens with tunnel options with the kernel
datapath, non-tunnel fields that don't exist in the packet, and even
with Geneve where we do have some options but not the particular one
that was matched on. This brings the same behavior for this case and
avoids the possibility of accessing uninitialized memory.

Reported-by: Daniele Di Proietto <diproiettod@vmware.com>
Signed-off-by: Jesse Gross <jesse@kernel.org>
---
 lib/dpif-netdev.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

Comments

Daniele Di Proietto Dec. 23, 2015, 12:13 a.m. UTC | #1
On 17/12/2015 16:28, "Jesse Gross" <jesse@kernel.org> wrote:

>When handling an upcall with the userspace datapath, it's currently
>possible for a flow from a packet with no tunnel options to come back
>with matches on the options. If that happens, dpif-netdev will
>attempt to translate the wildcards provided by ofproto into the format
>used by dpif. The translation requires use of the original wildcards
>from the flow, which since they didn't exist, is uninitalized memory.
>
>Matching on fields which don't actually exist is itself a bug. However,
>this can occur when we attempt to set a tunnel option on the packet -
>ofproto generates a match on the field in the original packet. This is
>being fixed separately.
>
>In other situations where we have a match on an unexpected field, we
>simply ignore it. This happens with tunnel options with the kernel
>datapath, non-tunnel fields that don't exist in the packet, and even
>with Geneve where we do have some options but not the particular one
>that was matched on. This brings the same behavior for this case and
>avoids the possibility of accessing uninitialized memory.
>
>Reported-by: Daniele Di Proietto <diproiettod@vmware.com>
>Signed-off-by: Jesse Gross <jesse@kernel.org>

Thanks for fixing this!

Acked-by: Daniele Di Proietto <diproiettod@vmware.com>
Jesse Gross Dec. 23, 2015, 12:22 a.m. UTC | #2
On Tue, Dec 22, 2015 at 7:13 PM, Daniele Di Proietto
<diproiettod@vmware.com> wrote:
>
>
> On 17/12/2015 16:28, "Jesse Gross" <jesse@kernel.org> wrote:
>
>>When handling an upcall with the userspace datapath, it's currently
>>possible for a flow from a packet with no tunnel options to come back
>>with matches on the options. If that happens, dpif-netdev will
>>attempt to translate the wildcards provided by ofproto into the format
>>used by dpif. The translation requires use of the original wildcards
>>from the flow, which since they didn't exist, is uninitalized memory.
>>
>>Matching on fields which don't actually exist is itself a bug. However,
>>this can occur when we attempt to set a tunnel option on the packet -
>>ofproto generates a match on the field in the original packet. This is
>>being fixed separately.
>>
>>In other situations where we have a match on an unexpected field, we
>>simply ignore it. This happens with tunnel options with the kernel
>>datapath, non-tunnel fields that don't exist in the packet, and even
>>with Geneve where we do have some options but not the particular one
>>that was matched on. This brings the same behavior for this case and
>>avoids the possibility of accessing uninitialized memory.
>>
>>Reported-by: Daniele Di Proietto <diproiettod@vmware.com>
>>Signed-off-by: Jesse Gross <jesse@kernel.org>
>
> Thanks for fixing this!
>
> Acked-by: Daniele Di Proietto <diproiettod@vmware.com>

Thanks, I applied this to master and branch-2.5.
diff mbox

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 12cbef8..bda2685 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3069,11 +3069,15 @@  dp_netdev_upcall(struct dp_netdev_pmd_thread *pmd, struct dp_packet *packet_,
             struct geneve_opt opts[TLV_TOT_OPT_SIZE /
                                    sizeof(struct geneve_opt)];
 
-            tun_metadata_to_geneve_udpif_mask(&flow->tunnel,
-                                              &wc->masks.tunnel,
-                                              orig_tunnel.metadata.opts.gnv,
-                                              orig_tunnel.metadata.present.len,
-                                              opts);
+            if (orig_tunnel.flags & FLOW_TNL_F_UDPIF) {
+                tun_metadata_to_geneve_udpif_mask(&flow->tunnel,
+                                                  &wc->masks.tunnel,
+                                                  orig_tunnel.metadata.opts.gnv,
+                                                  orig_tunnel.metadata.present.len,
+                                                  opts);
+            } else {
+                orig_tunnel.metadata.present.len = 0;
+            }
 
             memset(&wc->masks.tunnel.metadata, 0,
                    sizeof wc->masks.tunnel.metadata);