diff options
author | Florian Westphal <fw@strlen.de> | 2015-06-30 16:27:51 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-07-02 11:59:26 -0400 |
commit | dd302b59bde0149c20df7278c0d36c765e66afbd (patch) | |
tree | 94a1f2b00b55baf735ca1cb299117b6b7a611a1b /net | |
parent | 3bd229976f64bea64c60803f9fc8d9f0059ba2f2 (diff) |
netfilter: bridge: don't leak skb in error paths
br_nf_dev_queue_xmit must free skb in its error path.
NF_DROP is misleading -- its an okfn, not a netfilter hook.
Fixes: 462fb2af9788a ("bridge : Sanitize skb before it enters the IP stack")
Fixes: efb6de9b4ba00 ("netfilter: bridge: forward IPv6 fragmented packets")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_netfilter_hooks.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 8a394bd3af83..c8b9bcfe997e 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c | |||
@@ -744,7 +744,7 @@ static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb) | |||
744 | struct brnf_frag_data *data; | 744 | struct brnf_frag_data *data; |
745 | 745 | ||
746 | if (br_validate_ipv4(skb)) | 746 | if (br_validate_ipv4(skb)) |
747 | return NF_DROP; | 747 | goto drop; |
748 | 748 | ||
749 | IPCB(skb)->frag_max_size = nf_bridge->frag_max_size; | 749 | IPCB(skb)->frag_max_size = nf_bridge->frag_max_size; |
750 | 750 | ||
@@ -769,7 +769,7 @@ static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb) | |||
769 | struct brnf_frag_data *data; | 769 | struct brnf_frag_data *data; |
770 | 770 | ||
771 | if (br_validate_ipv6(skb)) | 771 | if (br_validate_ipv6(skb)) |
772 | return NF_DROP; | 772 | goto drop; |
773 | 773 | ||
774 | IP6CB(skb)->frag_max_size = nf_bridge->frag_max_size; | 774 | IP6CB(skb)->frag_max_size = nf_bridge->frag_max_size; |
775 | 775 | ||
@@ -784,12 +784,16 @@ static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb) | |||
784 | 784 | ||
785 | if (v6ops) | 785 | if (v6ops) |
786 | return v6ops->fragment(sk, skb, br_nf_push_frag_xmit); | 786 | return v6ops->fragment(sk, skb, br_nf_push_frag_xmit); |
787 | else | 787 | |
788 | return -EMSGSIZE; | 788 | kfree_skb(skb); |
789 | return -EMSGSIZE; | ||
789 | } | 790 | } |
790 | #endif | 791 | #endif |
791 | nf_bridge_info_free(skb); | 792 | nf_bridge_info_free(skb); |
792 | return br_dev_queue_push_xmit(sk, skb); | 793 | return br_dev_queue_push_xmit(sk, skb); |
794 | drop: | ||
795 | kfree_skb(skb); | ||
796 | return 0; | ||
793 | } | 797 | } |
794 | 798 | ||
795 | /* PF_BRIDGE/POST_ROUTING ********************************************/ | 799 | /* PF_BRIDGE/POST_ROUTING ********************************************/ |