netfilter: fix crash in flow offload by adding netns support
authorHsiuWen Yen <y.hsiuwen@gmail.com>
Thu, 20 Jun 2019 16:44:42 +0000 (00:44 +0800)
committerPetr Štetiar <ynezz@true.cz>
Mon, 24 Jun 2019 16:34:04 +0000 (18:34 +0200)
Commit fcb41decf6c6 ("config: enable some useful features on
!SMALL_FLASH devices") enabled netns, which in turn lead to the crash in
the flow offload target.

When the flow offloading framework intends to delete a flow from the
hardware table, it is necessary to retrieve the namespace from
nf_flowtable->ft_net. However, no one ever wrote the namespace into
nf_flowtable->ft_net in advance. So the framework will mistakenly use a
NULL namespace to execute dev_get_by_index_rcu(net, ifindex), leading to
the kernel panic.

Ref: FS#2321
Fixes: fcb41decf6c6 ("config: enable some useful features on !SMALL_FLASH devices")
Tested-by: Simon Tretter <simon@mediaarchitectu.re>
Signed-off-by: HsiuWen Yen <y.hsiuwen@gmail.com>
[merged patch into offload patch, fix for 4.19, SOB fix, commit subj/msg touches]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch
target/linux/generic/hack-4.19/650-netfilter-add-xt_OFFLOAD-target.patch

index b78ba1f53f52c566a4d2728511ac3717d5f9769f..9692aa8a2bf01830286fc3a7f275639b1c2b403a 100644 (file)
@@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
 --- /dev/null
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,403 @@
+@@ -0,0 +1,408 @@
 +/*
 + * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
 + *
@@ -342,12 +342,13 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
 +{
 +      const struct xt_flowoffload_target_info *info = par->targinfo;
++      const struct nf_conn_help *help;
 +      enum ip_conntrack_info ctinfo;
 +      enum ip_conntrack_dir dir;
 +      struct nf_flow_route route;
 +      struct flow_offload *flow;
 +      struct nf_conn *ct;
-+      const struct nf_conn_help *help;
++      struct net *net;
 +
 +      if (xt_flowoffload_skip(skb))
 +              return XT_CONTINUE;
@@ -396,6 +397,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +      xt_flowoffload_check_device(xt_in(par));
 +      xt_flowoffload_check_device(xt_out(par));
 +
++      net = read_pnet(&nf_flowtable.ft_net);
++      if (!net)
++              write_pnet(&nf_flowtable.ft_net, xt_net(par));
++
 +      if (info->flags & XT_FLOWOFFLOAD_HW)
 +              nf_flow_offload_hw_add(xt_net(par), flow, ct);
 +
index 8ebea32a822d7b7e25d6fd2572b6fcb34565cbfe..b207f9d084a7243d65d1fd185cc649b584fffc29 100644 (file)
@@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
 --- /dev/null
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,366 @@
+@@ -0,0 +1,371 @@
 +/*
 + * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
 + *
@@ -344,6 +344,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +      struct nf_flow_route route;
 +      struct flow_offload *flow;
 +      struct nf_conn *ct;
++      struct net *net;
 +
 +      if (xt_flowoffload_skip(skb))
 +              return XT_CONTINUE;
@@ -391,6 +392,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +      xt_flowoffload_check_device(xt_in(par));
 +      xt_flowoffload_check_device(xt_out(par));
 +
++      net = read_pnet(&nf_flowtable.ft_net);
++      if (!net)
++              write_pnet(&nf_flowtable.ft_net, xt_net(par));
++
 +      if (info->flags & XT_FLOWOFFLOAD_HW)
 +              nf_flow_offload_hw_add(xt_net(par), flow, ct);
 +