diff options
| author | Ben Pfaff <blp@nicira.com> | 2011-03-24 17:06:58 -0700 |
|---|---|---|
| committer | Ben Pfaff <blp@nicira.com> | 2011-03-24 17:06:58 -0700 |
| commit | e5cad95833eea4a1d68fe490812ec81048c98979 (patch) | |
| tree | 8b37f315ed5423d1312fe2cf4ebd6d6fdb93bb64 /datapath/datapath.c | |
| parent | a58727fb4007caf91d6eb615a123f161e4f4b9af (diff) | |
| download | openvswitch-e5cad95833eea4a1d68fe490812ec81048c98979.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>
Diffstat (limited to 'datapath/datapath.c')
| -rw-r--r-- | datapath/datapath.c | 24 |
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; } |
