[Devel] [PATCH rh7 v3 1/1] net/netfilter: handle case when nft_do_chain() is called for wrong netns
Konstantin Khorenko
khorenko at virtuozzo.com
Wed May 6 15:31:34 MSK 2020
nf_nat_ipv{4,6}_fn() functions must notice when do_chain()
(== nft_do_chain()) is called for a skb with netns which does not suit
the chain netns and do not call nf_nat_alloc_null_binding() in that
case.
So introduce a new error code for nft_do_chain() to return
and check it in nf_nat_ipv{4,6}_fn().
https://jira.sw.ru/browse/PSBM-102728
https://jira.sw.ru/browse/PSBM-103746
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
include/uapi/linux/netfilter.h | 4 ++++
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 2 ++
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 2 ++
net/netfilter/nf_tables_core.c | 2 +-
4 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h
index 750c04e41b6d2..4ab88a112d381 100644
--- a/include/uapi/linux/netfilter.h
+++ b/include/uapi/linux/netfilter.h
@@ -14,11 +14,15 @@
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5
+/* NF_WRONG_NETNS is to be used only in nft_do_chain() only */
+#define NF_WRONG_NETNS (NF_VERDICT_MASK - 1)
+/* NF_MAX_VERDICT value is left untouched on purpose */
#define NF_MAX_VERDICT NF_STOP
/* we overload the higher bits for encoding auxiliary data such as the queue
* number or errno values. Not nice, but better than additional function
* arguments. */
+/* If NF_VERDICT_MASK gets changed, check NF_WRONG_NETNS value */
#define NF_VERDICT_MASK 0x000000ff
/* extra verdict flags have mask 0x0000ff00 */
diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
index 3b8b048ffc6cb..4522a01271868 100644
--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
@@ -292,6 +292,8 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
unsigned int ret;
ret = do_chain(ops, skb, state, ct);
+ if (ret == NF_WRONG_NETNS)
+ return NF_ACCEPT;
if (ret != NF_ACCEPT)
return ret;
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index 540dc0fdaf102..ebca2c4e3e57a 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -305,6 +305,8 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
unsigned int ret;
ret = do_chain(ops, skb, state, ct);
+ if (ret == NF_WRONG_NETNS)
+ return NF_ACCEPT;
if (ret != NF_ACCEPT)
return ret;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 81ccbca32fa8a..d2c96afb1ace1 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -134,7 +134,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
/* Ignore chains that are not for the current network namespace */
if (!net_eq(net, chain_net))
- return NF_ACCEPT;
+ return NF_WRONG_NETNS;
info.trace = false;
if (static_key_false(&nft_trace_enabled))
--
2.15.1
More information about the Devel
mailing list