Commit fcd53c51 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: nf_dup_netdev: add and use recursion counter

Now that the egress function can be called from egress hook, we need
to avoid recursive calls into the nf_tables traverser, else crash.

Fixes: f87b9464 ("netfilter: nft_fwd_netdev: Support egress hook")
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 574a5b85
...@@ -13,20 +13,31 @@ ...@@ -13,20 +13,31 @@
#include <net/netfilter/nf_tables_offload.h> #include <net/netfilter/nf_tables_offload.h>
#include <net/netfilter/nf_dup_netdev.h> #include <net/netfilter/nf_dup_netdev.h>
#define NF_RECURSION_LIMIT 2
static DEFINE_PER_CPU(u8, nf_dup_skb_recursion);
static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev, static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev,
enum nf_dev_hooks hook) enum nf_dev_hooks hook)
{ {
if (__this_cpu_read(nf_dup_skb_recursion) > NF_RECURSION_LIMIT)
goto err;
if (hook == NF_NETDEV_INGRESS && skb_mac_header_was_set(skb)) { if (hook == NF_NETDEV_INGRESS && skb_mac_header_was_set(skb)) {
if (skb_cow_head(skb, skb->mac_len)) { if (skb_cow_head(skb, skb->mac_len))
kfree_skb(skb); goto err;
return;
}
skb_push(skb, skb->mac_len); skb_push(skb, skb->mac_len);
} }
skb->dev = dev; skb->dev = dev;
skb_clear_tstamp(skb); skb_clear_tstamp(skb);
__this_cpu_inc(nf_dup_skb_recursion);
dev_queue_xmit(skb); dev_queue_xmit(skb);
__this_cpu_dec(nf_dup_skb_recursion);
return;
err:
kfree_skb(skb);
} }
void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif) void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment