diff options
author | Florian Westphal <fw@strlen.de> | 2019-11-03 20:54:28 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-11-04 20:58:34 +0100 |
commit | b23c0742c2ce7e33ed79d10e451f70fdb5ca85d1 (patch) | |
tree | eeaa498c92df51c2684353329d289d88b3c987db /net/bridge | |
parent | netfilter: nf_tables: fix unexpected EOPNOTSUPP error (diff) | |
download | linux-b23c0742c2ce7e33ed79d10e451f70fdb5ca85d1.tar.xz linux-b23c0742c2ce7e33ed79d10e451f70fdb5ca85d1.zip |
bridge: ebtables: don't crash when using dnat target in output chains
xt_in() returns NULL in the output hook, skip the pkt_type change for
that case, redirection only makes sense in broute/prerouting hooks.
Reported-by: Tom Yan <tom.ty89@gmail.com>
Cc: Linus Lüssing <linus.luessing@c0d3.blue>
Fixes: cf3cb246e277d ("bridge: ebtables: fix reception of frames DNAT-ed to bridge device/port")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebt_dnat.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index ed91ea31978a..12a4f4d93681 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -20,7 +20,6 @@ static unsigned int ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct ebt_nat_info *info = par->targinfo; - struct net_device *dev; if (skb_ensure_writable(skb, ETH_ALEN)) return EBT_DROP; @@ -33,10 +32,22 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) else skb->pkt_type = PACKET_MULTICAST; } else { - if (xt_hooknum(par) != NF_BR_BROUTING) - dev = br_port_get_rcu(xt_in(par))->br->dev; - else + const struct net_device *dev; + + switch (xt_hooknum(par)) { + case NF_BR_BROUTING: dev = xt_in(par); + break; + case NF_BR_PRE_ROUTING: + dev = br_port_get_rcu(xt_in(par))->br->dev; + break; + default: + dev = NULL; + break; + } + + if (!dev) /* NF_BR_LOCAL_OUT */ + return info->target; if (ether_addr_equal(info->mac, dev->dev_addr)) skb->pkt_type = PACKET_HOST; |