Leonardo Bras
2019-Aug-30  18:13 UTC
[Bridge] [PATCH v4 0/2] Drop IPV6 packets if IPv6 is disabled on boot
This patchset was prevously a single patch named:
- netfilter: nf_tables: fib: Drop IPV6 packets if IPv6 is disabled on boot
It fixes a bug where a host, with IPv6 disabled on boot, has to deal with
guest IPv6 packets, that comes from a bridge interface.
When these packets reach the host ip6tables they cause a kernel panic.
---
Changes from v3:
- Move drop logic from nft_fib6_eval{,_type} to nft_fib_netdev_eval
- Add another patch to drop ipv6 packets from bridge when ipv6 disabled  
Changes from v2:
- Replace veredict.code from NF_DROP to NFT_BREAK
- Updated commit message (s/package/packet)
Changes from v1:
- Move drop logic from nft_fib_inet_eval() to nft_fib6_eval{,_type}
so it can affect other usages of these functions.
Leonardo Bras (2):
  netfilter: Terminate rule eval if protocol=IPv6 and ipv6 module is
    disabled
  net: br_netfiler_hooks: Drops IPv6 packets if IPv6 module is not
    loaded
 net/bridge/br_netfilter_hooks.c | 2 ++
 net/netfilter/nft_fib_netdev.c  | 3 +++
 2 files changed, 5 insertions(+)
-- 
2.20.1
Leonardo Bras
2019-Aug-30  18:13 UTC
[Bridge] [PATCH v4 1/2] netfilter: Terminate rule eval if protocol=IPv6 and ipv6 module is disabled
If IPv6 is disabled on boot (ipv6.disable=1), but nft_fib_inet ends up
dealing with a IPv6 packet, it causes a kernel panic in
fib6_node_lookup_1(), crashing in bad_page_fault.
The panic is caused by trying to deference a very low address (0x38
in ppc64le), due to ipv6.fib6_main_tbl = NULL.
BUG: Kernel NULL pointer dereference at 0x00000038
The kernel panic was reproduced in a host that disabled IPv6 on boot and
have to process guest packets (coming from a bridge) using it's ip6tables.
Terminate rule evaluation when packet protocol is IPv6 but the ipv6 module
is not loaded.
Signed-off-by: Leonardo Bras <leonardo at linux.ibm.com>
---
 net/netfilter/nft_fib_netdev.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/net/netfilter/nft_fib_netdev.c b/net/netfilter/nft_fib_netdev.c
index 2cf3f32fe6d2..a2e726ae7f07 100644
--- a/net/netfilter/nft_fib_netdev.c
+++ b/net/netfilter/nft_fib_netdev.c
@@ -14,6 +14,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
+#include <net/ipv6.h>
 
 #include <net/netfilter/nft_fib.h>
 
@@ -34,6 +35,8 @@ static void nft_fib_netdev_eval(const struct nft_expr *expr,
 		}
 		break;
 	case ETH_P_IPV6:
+		if (!ipv6_mod_enabled())
+			break;
 		switch (priv->result) {
 		case NFT_FIB_RESULT_OIF:
 		case NFT_FIB_RESULT_OIFNAME:
-- 
2.20.1
Leonardo Bras
2019-Aug-30  18:13 UTC
[Bridge] [PATCH v4 2/2] net: br_netfiler_hooks: Drops IPv6 packets if IPv6 module is not loaded
A kernel panic can happen if a host has disabled IPv6 on boot and have to
process guest packets (coming from a bridge) using it's ip6tables.
IPv6 packets need to be dropped if the IPv6 module is not loaded.
Signed-off-by: Leonardo Bras <leonardo at linux.ibm.com>
---
 net/bridge/br_netfilter_hooks.c | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index d3f9592f4ff8..5e8693730df1 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -493,6 +493,8 @@ static unsigned int br_nf_pre_routing(void *priv,
 	brnet = net_generic(state->net, brnf_net_id);
 	if (IS_IPV6(skb) || is_vlan_ipv6(skb, state->net) ||
 	    is_pppoe_ipv6(skb, state->net)) {
+		if (!ipv6_mod_enabled())
+			return NF_DROP;
 		if (!brnet->call_ip6tables &&
 		    !br_opt_get(br, BROPT_NF_CALL_IP6TABLES))
 			return NF_ACCEPT;
-- 
2.20.1
Florian Westphal
2019-Aug-30  20:55 UTC
[Bridge] [PATCH v4 2/2] net: br_netfiler_hooks: Drops IPv6 packets if IPv6 module is not loaded
Leonardo Bras <leonardo at linux.ibm.com> wrote:> A kernel panic can happen if a host has disabled IPv6 on boot and have to > process guest packets (coming from a bridge) using it's ip6tables. > > IPv6 packets need to be dropped if the IPv6 module is not loaded. > > Signed-off-by: Leonardo Bras <leonardo at linux.ibm.com> > --- > net/bridge/br_netfilter_hooks.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c > index d3f9592f4ff8..5e8693730df1 100644 > --- a/net/bridge/br_netfilter_hooks.c > +++ b/net/bridge/br_netfilter_hooks.c > @@ -493,6 +493,8 @@ static unsigned int br_nf_pre_routing(void *priv, > brnet = net_generic(state->net, brnf_net_id); > if (IS_IPV6(skb) || is_vlan_ipv6(skb, state->net) || > is_pppoe_ipv6(skb, state->net)) { > + if (!ipv6_mod_enabled()) > + return NF_DROP; > if (!brnet->call_ip6tables && > !br_opt_get(br, BROPT_NF_CALL_IP6TABLES)) > return NF_ACCEPT;No, thats too aggressive and turns the bridge into an ipv6 blackhole. There are two solutions: 1. The above patch, but use NF_ACCEPT instead 2. keep the DROP, but move it below the call_ip6tables test, so that users can tweak call-ip6tables to accept packets. Perhaps it would be good to also add a pr_warn_once() that tells that ipv6 was disabled on command line and call-ip6tables isn't supported in this configuration. I would go with option two.
Florian Westphal
2019-Aug-30  20:58 UTC
[Bridge] [PATCH v4 1/2] netfilter: Terminate rule eval if protocol=IPv6 and ipv6 module is disabled
Leonardo Bras <leonardo at linux.ibm.com> wrote:> If IPv6 is disabled on boot (ipv6.disable=1), but nft_fib_inet ends up > dealing with a IPv6 packet, it causes a kernel panic in > fib6_node_lookup_1(), crashing in bad_page_fault. > > The panic is caused by trying to deference a very low address (0x38 > in ppc64le), due to ipv6.fib6_main_tbl = NULL. > BUG: Kernel NULL pointer dereference at 0x00000038 > > The kernel panic was reproduced in a host that disabled IPv6 on boot and > have to process guest packets (coming from a bridge) using it's ip6tables. > > Terminate rule evaluation when packet protocol is IPv6 but the ipv6 module > is not loaded. > > Signed-off-by: Leonardo Bras <leonardo at linux.ibm.com>Acked-by: Florian Westphal <fw at strlen.de>
Pablo Neira Ayuso
2019-Sep-03  20:55 UTC
[Bridge] [PATCH v4 1/2] netfilter: Terminate rule eval if protocol=IPv6 and ipv6 module is disabled
On Fri, Aug 30, 2019 at 03:13:53PM -0300, Leonardo Bras wrote:> If IPv6 is disabled on boot (ipv6.disable=1), but nft_fib_inet ends up > dealing with a IPv6 packet, it causes a kernel panic in > fib6_node_lookup_1(), crashing in bad_page_fault. > > The panic is caused by trying to deference a very low address (0x38 > in ppc64le), due to ipv6.fib6_main_tbl = NULL. > BUG: Kernel NULL pointer dereference at 0x00000038 > > The kernel panic was reproduced in a host that disabled IPv6 on boot and > have to process guest packets (coming from a bridge) using it's ip6tables. > > Terminate rule evaluation when packet protocol is IPv6 but the ipv6 module > is not loaded.Patch is applied, thanks.