diff options
author | Florian Westphal <fw@strlen.de> | 2019-11-03 14:54:28 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-11-04 14:58:34 -0500 |
commit | b23c0742c2ce7e33ed79d10e451f70fdb5ca85d1 (patch) | |
tree | eeaa498c92df51c2684353329d289d88b3c987db /net/bridge | |
parent | 9fedd894b4e1c7ad5e5f711899f6a0a1da01d996 (diff) |
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 | |||
20 | ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) | 20 | ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) |
21 | { | 21 | { |
22 | const struct ebt_nat_info *info = par->targinfo; | 22 | const struct ebt_nat_info *info = par->targinfo; |
23 | struct net_device *dev; | ||
24 | 23 | ||
25 | if (skb_ensure_writable(skb, ETH_ALEN)) | 24 | if (skb_ensure_writable(skb, ETH_ALEN)) |
26 | return EBT_DROP; | 25 | return EBT_DROP; |
@@ -33,10 +32,22 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
33 | else | 32 | else |
34 | skb->pkt_type = PACKET_MULTICAST; | 33 | skb->pkt_type = PACKET_MULTICAST; |
35 | } else { | 34 | } else { |
36 | if (xt_hooknum(par) != NF_BR_BROUTING) | 35 | const struct net_device *dev; |
37 | dev = br_port_get_rcu(xt_in(par))->br->dev; | 36 | |
38 | else | 37 | switch (xt_hooknum(par)) { |
38 | case NF_BR_BROUTING: | ||
39 | dev = xt_in(par); | 39 | dev = xt_in(par); |
40 | break; | ||
41 | case NF_BR_PRE_ROUTING: | ||
42 | dev = br_port_get_rcu(xt_in(par))->br->dev; | ||
43 | break; | ||
44 | default: | ||
45 | dev = NULL; | ||
46 | break; | ||
47 | } | ||
48 | |||
49 | if (!dev) /* NF_BR_LOCAL_OUT */ | ||
50 | return info->target; | ||
40 | 51 | ||
41 | if (ether_addr_equal(info->mac, dev->dev_addr)) | 52 | if (ether_addr_equal(info->mac, dev->dev_addr)) |
42 | skb->pkt_type = PACKET_HOST; | 53 | skb->pkt_type = PACKET_HOST; |