From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 01/13] netfilter: nf_tables: delay chain policy update until transaction is complete
Date: Mon, 13 May 2019 11:56:18 +0200 [thread overview]
Message-ID: <20190513095630.32443-2-pablo@netfilter.org> (raw)
In-Reply-To: <20190513095630.32443-1-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
When we process a long ruleset of the form
chain input {
type filter hook input priority filter; policy drop;
...
}
Then the base chain gets registered early on, we then continue to
process/validate the next messages coming in the same transaction.
Problem is that if the base chain policy is 'drop', it will take effect
immediately, which causes all traffic to get blocked until the
transaction completes or is aborted.
Fix this by deferring the policy until the transaction has been
processed and all of the rules have been flagged as active.
Reported-by: Jann Haber <jann.haber@selfnet.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 50 +++++++++++++++++++++++++++++++++----------
1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 1606eaa5ae0d..f2e12ae50544 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -214,33 +214,33 @@ static int nft_deltable(struct nft_ctx *ctx)
return err;
}
-static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
+static struct nft_trans *nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
{
struct nft_trans *trans;
trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
if (trans == NULL)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
if (msg_type == NFT_MSG_NEWCHAIN)
nft_activate_next(ctx->net, ctx->chain);
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
- return 0;
+ return trans;
}
static int nft_delchain(struct nft_ctx *ctx)
{
- int err;
+ struct nft_trans *trans;
- err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
- if (err < 0)
- return err;
+ trans = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
ctx->table->use--;
nft_deactivate_next(ctx->net, ctx->chain);
- return err;
+ return 0;
}
static void nft_rule_expr_activate(const struct nft_ctx *ctx,
@@ -1615,6 +1615,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
struct nft_base_chain *basechain;
struct nft_stats __percpu *stats;
struct net *net = ctx->net;
+ struct nft_trans *trans;
struct nft_chain *chain;
struct nft_rule **rules;
int err;
@@ -1662,7 +1663,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
ops->dev = hook.dev;
chain->flags |= NFT_BASE_CHAIN;
- basechain->policy = policy;
+ basechain->policy = NF_ACCEPT;
} else {
chain = kzalloc(sizeof(*chain), GFP_KERNEL);
if (chain == NULL)
@@ -1698,13 +1699,18 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
if (err)
goto err2;
- err = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
- if (err < 0) {
+ trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
+ if (IS_ERR(trans)) {
+ err = PTR_ERR(trans);
rhltable_remove(&table->chains_ht, &chain->rhlhead,
nft_chain_ht_params);
goto err2;
}
+ nft_trans_chain_policy(trans) = -1;
+ if (nft_is_base_chain(chain))
+ nft_trans_chain_policy(trans) = policy;
+
table->use++;
list_add_tail_rcu(&chain->list, &table->chains);
@@ -6311,6 +6317,27 @@ static int nf_tables_validate(struct net *net)
return 0;
}
+/* a drop policy has to be deferred until all rules have been activated,
+ * otherwise a large ruleset that contains a drop-policy base chain will
+ * cause all packets to get dropped until the full transaction has been
+ * processed.
+ *
+ * We defer the drop policy until the transaction has been finalized.
+ */
+static void nft_chain_commit_drop_policy(struct nft_trans *trans)
+{
+ struct nft_base_chain *basechain;
+
+ if (nft_trans_chain_policy(trans) != NF_DROP)
+ return;
+
+ if (!nft_is_base_chain(trans->ctx.chain))
+ return;
+
+ basechain = nft_base_chain(trans->ctx.chain);
+ basechain->policy = NF_DROP;
+}
+
static void nft_chain_commit_update(struct nft_trans *trans)
{
struct nft_base_chain *basechain;
@@ -6632,6 +6659,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
/* trans destroyed after rcu grace period */
} else {
+ nft_chain_commit_drop_policy(trans);
nft_clear(net, trans->ctx.chain);
nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
nft_trans_destroy(trans);
--
2.11.0
next prev parent reply other threads:[~2019-05-13 9:56 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-13 9:56 [PATCH 00/13] Netfilter fixes for net Pablo Neira Ayuso
2019-05-13 9:56 ` Pablo Neira Ayuso [this message]
2019-05-13 9:56 ` [PATCH 02/13] netfilter: nft_flow_offload: add entry to flowtable after confirmation Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 03/13] netfilter: nf_flow_table: fix netdev refcnt leak Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 04/13] netfilter: nf_flow_table: check ttl value in flow offload data path Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 05/13] netfilter: nf_conntrack_h323: restore boundary check correctness Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 06/13] netfilter: nf_tables: fix base chain stat rcu_dereference usage Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 07/13] netfilter: nf_flow_table: fix missing error check for rhashtable_insert_fast Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 08/13] netfilter: ctnetlink: Resolve conntrack L3-protocol flush regression Pablo Neira Ayuso
2019-06-24 3:44 ` Felix Kaechele
2019-06-24 23:58 ` Pablo Neira Ayuso
2019-06-25 3:02 ` Felix Kaechele
2019-06-25 8:08 ` Pablo Neira Ayuso
2019-06-25 11:33 ` Felix Kaechele
2019-06-25 11:52 ` Kristian Evensen
2019-06-25 14:45 ` Felix Kaechele
2019-06-25 15:08 ` Kristian Evensen
2019-06-25 16:16 ` Felix Kaechele
2019-06-25 19:45 ` Pablo Neira Ayuso
2019-06-25 15:45 ` Kristian Evensen
2019-06-25 19:40 ` Pablo Neira Ayuso
2019-06-25 19:41 ` Pablo Neira Ayuso
2019-06-25 15:01 ` Nicolas Dichtel
2019-06-25 19:44 ` Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 09/13] netfilter: nf_conntrack_h323: Remove deprecated config check Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 10/13] netfilter: nf_flow_table: do not flow offload deleted conntrack entries Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 11/13] netfilter: ebtables: CONFIG_COMPAT: reject trailing data after last rule Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 12/13] netfilter: nf_tables: remove NFT_CT_TIMEOUT Pablo Neira Ayuso
2019-05-13 9:56 ` [PATCH 13/13] netfilter: nf_tables: correct NFT_LOGLEVEL_MAX value Pablo Neira Ayuso
2019-05-13 16:02 ` [PATCH 00/13] Netfilter fixes for net David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190513095630.32443-2-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).