summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-03-24 17:06:58 -0700
committerBen Pfaff <blp@nicira.com>2011-05-17 13:27:30 -0700
commitc651d0eb504984649460f5e085b466cb97ddd4cc (patch)
tree268433f62a13f490f34f73705006635dd50e17a6
parent4180463ae926666ca9256d4a02f562d0f566031e (diff)
downloadopenvswitch-c651d0eb504984649460f5e085b466cb97ddd4cc.tar.gz
datapath: Avoid memory leak in odp_packet_cmd_execute().
The error path needs to free 'packet'. Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--datapath/datapath.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/datapath/datapath.c b/datapath/datapath.c
index 8a5500125..e8ff4a5aa 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -687,16 +687,16 @@ static int odp_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
err = -EINVAL;
if (!a[ODP_PACKET_ATTR_PACKET] || !a[ODP_PACKET_ATTR_ACTIONS] ||
nla_len(a[ODP_PACKET_ATTR_PACKET]) < ETH_HLEN)
- goto exit;
+ goto err;
err = validate_actions(a[ODP_PACKET_ATTR_ACTIONS]);
if (err)
- goto exit;
+ goto err;
packet = skb_clone(skb, GFP_KERNEL);
err = -ENOMEM;
if (!packet)
- goto exit;
+ goto err;
packet->data = nla_data(a[ODP_PACKET_ATTR_PACKET]);
packet->len = nla_len(a[ODP_PACKET_ATTR_PACKET]);
@@ -716,18 +716,24 @@ static int odp_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
err = flow_extract(packet, -1, &key, &is_frag);
if (err)
- goto exit;
+ goto err_kfree_skb;
rcu_read_lock();
dp = get_dp(odp_header->dp_ifindex);
err = -ENODEV;
- if (dp)
- err = execute_actions(dp, packet, &key,
- nla_data(a[ODP_PACKET_ATTR_ACTIONS]),
- nla_len(a[ODP_PACKET_ATTR_ACTIONS]));
+ if (!dp)
+ goto err_unlock;
+ err = execute_actions(dp, packet, &key,
+ nla_data(a[ODP_PACKET_ATTR_ACTIONS]),
+ nla_len(a[ODP_PACKET_ATTR_ACTIONS]));
rcu_read_unlock();
+ return err;
-exit:
+err_unlock:
+ rcu_read_unlock();
+err_kfree_skb:
+ kfree_skb(packet);
+err:
return err;
}