summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>2014-04-09 17:00:30 +0900
committerJiri Slaby <jslaby@suse.cz>2014-05-29 11:38:31 +0200
commit262cacfba2c885aa7b45433e824eb67636323c65 (patch)
tree526309d79a0bbb6a7d938130dad055e33d3db9f8
parent2a0fe092c7eb575a56956ce9dc55a02fe69c3a31 (diff)
bridge: Fix double free and memory leak around br_allowed_ingress
[ Upstream commit eb7076182d1ae4bc4641534134ed707100d76acc ] br_allowed_ingress() has two problems. 1. If br_allowed_ingress() is called by br_handle_frame_finish() and vlan_untag() in br_allowed_ingress() fails, skb will be freed by both vlan_untag() and br_handle_frame_finish(). 2. If br_allowed_ingress() is called by br_dev_xmit() and br_allowed_ingress() fails, the skb will not be freed. Fix these two problems by freeing the skb in br_allowed_ingress() if it fails. Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
-rw-r--r--net/bridge/br_input.c2
-rw-r--r--net/bridge/br_vlan.c7
2 files changed, 5 insertions, 4 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index a2fd37ec35f7..c378750602cd 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -72,7 +72,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
goto drop;
if (!br_allowed_ingress(p->br, nbp_get_vlan_info(p), skb, &vid))
- goto drop;
+ goto out;
/* insert into forwarding database after filtering to avoid spoofing */
br = p->br;
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 53f0990eab58..45a26debe64e 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -201,7 +201,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
* rejected.
*/
if (!v)
- return false;
+ goto drop;
err = br_vlan_get_tag(skb, vid);
if (!*vid) {
@@ -212,7 +212,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
* vlan untagged or priority-tagged traffic belongs to.
*/
if (pvid == VLAN_N_VID)
- return false;
+ goto drop;
/* PVID is set on this port. Any untagged or priority-tagged
* ingress frame is considered to belong to this vlan.
@@ -235,7 +235,8 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
/* Frame had a valid vlan tag. See if vlan is allowed */
if (test_bit(*vid, v->vlan_bitmap))
return true;
-
+drop:
+ kfree_skb(skb);
return false;
}