Skip to content

Commit a0abf27

Browse files
netfilter: nf_tables: skip immediate deactivate in _PREPARE_ERROR
jira VULN-8835 cve CVE-2023-4015 commit-author Pablo Neira Ayuso <[email protected]> commit 0a771f7 On error when building the rule, the immediate expression unbinds the chain, hence objects can be deactivated by the transaction records. Otherwise, it is possible to trigger the following warning: WARNING: CPU: 3 PID: 915 at net/netfilter/nf_tables_api.c:2013 nf_tables_chain_destroy+0x1f7/0x210 [nf_tables] CPU: 3 PID: 915 Comm: chain-bind-err- Not tainted 6.1.39 #1 RIP: 0010:nf_tables_chain_destroy+0x1f7/0x210 [nf_tables] Fixes: 4bedf9e ("netfilter: nf_tables: fix chain binding transaction logic") Reported-by: Kevin Rich <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Florian Westphal <[email protected]> (cherry picked from commit 0a771f7) Signed-off-by: Shreeya Patel <[email protected]>
1 parent 2b0d646 commit a0abf27

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

net/netfilter/nft_immediate.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,27 @@ static void nft_immediate_activate(const struct nft_ctx *ctx,
109109
return nft_data_hold(&priv->data, nft_dreg_to_type(priv->dreg));
110110
}
111111

112+
static void nft_immediate_chain_deactivate(const struct nft_ctx *ctx,
113+
struct nft_chain *chain,
114+
enum nft_trans_phase phase)
115+
{
116+
struct nft_ctx chain_ctx;
117+
struct nft_rule *rule;
118+
119+
chain_ctx = *ctx;
120+
chain_ctx.chain = chain;
121+
122+
list_for_each_entry(rule, &chain->rules, list)
123+
nft_rule_expr_deactivate(&chain_ctx, rule, phase);
124+
}
125+
112126
static void nft_immediate_deactivate(const struct nft_ctx *ctx,
113127
const struct nft_expr *expr,
114128
enum nft_trans_phase phase)
115129
{
116130
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
117131
const struct nft_data *data = &priv->data;
118-
struct nft_ctx chain_ctx;
119132
struct nft_chain *chain;
120-
struct nft_rule *rule;
121133

122134
if (priv->dreg == NFT_REG_VERDICT) {
123135
switch (data->verdict.code) {
@@ -127,20 +139,17 @@ static void nft_immediate_deactivate(const struct nft_ctx *ctx,
127139
if (!nft_chain_binding(chain))
128140
break;
129141

130-
chain_ctx = *ctx;
131-
chain_ctx.chain = chain;
132-
133-
list_for_each_entry(rule, &chain->rules, list)
134-
nft_rule_expr_deactivate(&chain_ctx, rule, phase);
135-
136142
switch (phase) {
137143
case NFT_TRANS_PREPARE_ERROR:
138144
nf_tables_unbind_chain(ctx, chain);
139-
fallthrough;
145+
nft_deactivate_next(ctx->net, chain);
146+
break;
140147
case NFT_TRANS_PREPARE:
148+
nft_immediate_chain_deactivate(ctx, chain, phase);
141149
nft_deactivate_next(ctx->net, chain);
142150
break;
143151
default:
152+
nft_immediate_chain_deactivate(ctx, chain, phase);
144153
nft_chain_del(chain);
145154
chain->bound = false;
146155
chain->table->use--;

0 commit comments

Comments
 (0)