Skip to content

Commit c213bfc

Browse files
committed
netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound set/chain
jira VULN-6505 cve CVE-2023-3390 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit 26b5a57 upstream-diff: RedHat never back-ported d0e2c7d ("netfilter: nf_tables: add NFT_CHAIN_BINDING") which has a fix netfilter: nf_tables: fix chain binding transaction logic that adds a large switch statement both nft_immediate_deactivate and nft_immediate_activate. This also impacts all the chain bounds as only the sets are valid in this commit. Its only a portion of the original commit. statement and commits for nft_chain transmission stuff Add a new state to deal with rule expressions deactivation from the newrule error path, otherwise the anonymous set remains in the list in inactive state for the next generation. Mark the set/chain transaction as unbound so the abort path releases this object, set it as inactive in the next generation so it is not reachable anymore from this transaction and reference counter is dropped. Fixes: 1240eb9 ("netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 26b5a57) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent fedf7f9 commit c213bfc

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ struct nft_expr_type {
823823

824824
enum nft_trans_phase {
825825
NFT_TRANS_PREPARE,
826+
NFT_TRANS_PREPARE_ERROR,
826827
NFT_TRANS_ABORT,
827828
NFT_TRANS_COMMIT,
828829
NFT_TRANS_RELEASE

net/netfilter/nf_tables_api.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ static void nft_trans_destroy(struct nft_trans *trans)
171171
kfree(trans);
172172
}
173173

174-
static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
174+
static void __nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set,
175+
bool bind)
175176
{
176177
struct net *net = ctx->net;
177178
struct nft_trans *trans;
@@ -183,16 +184,26 @@ static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
183184
switch (trans->msg_type) {
184185
case NFT_MSG_NEWSET:
185186
if (nft_trans_set(trans) == set)
186-
nft_trans_set_bound(trans) = true;
187+
nft_trans_set_bound(trans) = bind;
187188
break;
188189
case NFT_MSG_NEWSETELEM:
189190
if (nft_trans_elem_set(trans) == set)
190-
nft_trans_elem_set_bound(trans) = true;
191+
nft_trans_elem_set_bound(trans) = bind;
191192
break;
192193
}
193194
}
194195
}
195196

197+
static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
198+
{
199+
return __nft_set_trans_bind(ctx, set, true);
200+
}
201+
202+
static void nft_set_trans_unbind(const struct nft_ctx *ctx, struct nft_set *set)
203+
{
204+
return __nft_set_trans_bind(ctx, set, false);
205+
}
206+
196207
static int nft_netdev_register_hooks(struct net *net,
197208
struct list_head *hook_list)
198209
{
@@ -3262,7 +3273,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
32623273
if (flow)
32633274
nft_flow_rule_destroy(flow);
32643275
err_release_rule:
3265-
nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE);
3276+
nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE_ERROR);
32663277
nf_tables_rule_destroy(&ctx, rule);
32673278
err_release_expr:
32683279
for (i = 0; i < n; i++) {
@@ -4451,6 +4462,13 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
44514462
enum nft_trans_phase phase)
44524463
{
44534464
switch (phase) {
4465+
case NFT_TRANS_PREPARE_ERROR:
4466+
nft_set_trans_unbind(ctx, set);
4467+
if (nft_set_is_anonymous(set))
4468+
nft_deactivate_next(ctx->net, set);
4469+
4470+
set->use--;
4471+
break;
44544472
case NFT_TRANS_PREPARE:
44554473
if (nft_set_is_anonymous(set))
44564474
nft_deactivate_next(ctx->net, set);
@@ -6561,6 +6579,7 @@ void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
65616579
enum nft_trans_phase phase)
65626580
{
65636581
switch (phase) {
6582+
case NFT_TRANS_PREPARE_ERROR:
65646583
case NFT_TRANS_PREPARE:
65656584
case NFT_TRANS_ABORT:
65666585
case NFT_TRANS_RELEASE:

0 commit comments

Comments
 (0)