[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openvswitch-dev
Subject:    [ovs-dev] [VLAN/SNAP 2/3] dpif-netdev: Tolerate undersized packets.
From:       blp () nicira ! com (Ben Pfaff)
Date:       2010-07-28 21:01:36
Message-ID: 1280350897-11621-2-git-send-email-blp () nicira ! com
[Download RAW message or body]

Actions that modify packets need to tolerate packets that are too small.
Most of the actions already implicitly do this check, since they check
for appropriate values in the flow key that would only be there if the
corresponding data was present.  But a few don't seem to have any
guarantee, so this adds checks.

Problem found by code inspection.
---
 lib/dpif-netdev.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 15ff0d5..29071b3 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1099,6 +1099,10 @@ dp_netdev_modify_vlan_tci(struct ofpbuf *packet, const flow_t *key,
 {
     struct vlan_eth_header *veh;
 
+    if (packet->size < sizeof(struct eth_header)) {
+        return;
+    }
+
     if (key->dl_vlan != htons(ODP_VLAN_NONE)) {
         /* Clear 'mask' bits, but maintain other TCI bits. */
         veh = packet->l2;
@@ -1124,7 +1128,8 @@ static void
 dp_netdev_strip_vlan(struct ofpbuf *packet)
 {
     struct vlan_eth_header *veh = packet->l2;
-    if (veh->veth_type == htons(ETH_TYPE_VLAN)) {
+    if (packet->size >= sizeof *veh
+        && veh->veth_type == htons(ETH_TYPE_VLAN)) {
         struct eth_header tmp;
 
         memcpy(tmp.eth_dst, veh->veth_dst, ETH_ADDR_LEN);
@@ -1142,14 +1147,18 @@ static void
 dp_netdev_set_dl_src(struct ofpbuf *packet, const uint8_t dl_addr[ETH_ADDR_LEN])
 {
     struct eth_header *eh = packet->l2;
-    memcpy(eh->eth_src, dl_addr, sizeof eh->eth_src);
+    if (packet->size >= sizeof *eh) {
+        memcpy(eh->eth_src, dl_addr, sizeof eh->eth_src);
+    }
 }
 
 static void
 dp_netdev_set_dl_dst(struct ofpbuf *packet, const uint8_t dl_addr[ETH_ADDR_LEN])
 {
     struct eth_header *eh = packet->l2;
-    memcpy(eh->eth_dst, dl_addr, sizeof eh->eth_dst);
+    if (packet->size >= sizeof *eh) {
+        memcpy(eh->eth_dst, dl_addr, sizeof eh->eth_dst);
+    }
 }
 
 static void
-- 
1.7.1




[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic