patches.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org, netfilter-devel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Pablo Neira Ayuso <pablo@netfilter.org>
Subject: [PATCH 5.15 76/89] netfilter: nf_tables: report use refcount overflow
Date: Sun, 13 Aug 2023 23:20:07 +0200	[thread overview]
Message-ID: <20230813211713.054482840@linuxfoundation.org> (raw)
In-Reply-To: <20230813211710.787645394@linuxfoundation.org>

From: Pablo Neira Ayuso <pablo@netfilter.org>

commit 1689f25924ada8fe14a4a82c38925d04994c7142 upstream.

Overflow use refcount checks are not complete.

Add helper function to deal with object reference counter tracking.
Report -EMFILE in case UINT_MAX is reached.

nft_use_dec() splats in case that reference counter underflows,
which should not ever happen.

Add nft_use_inc_restore() and nft_use_dec_restore() which are used
to restore reference counter from error and abort paths.

Use u32 in nft_flowtable and nft_object since helper functions cannot
work on bitfields.

Remove the few early incomplete checks now that the helper functions
are in place and used to check for refcount overflow.

Fixes: 96518518cc41 ("netfilter: add nftables")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/netfilter/nf_tables.h |   31 ++++++-
 net/netfilter/nf_tables_api.c     |  164 +++++++++++++++++++++++---------------
 net/netfilter/nft_flow_offload.c  |    6 -
 net/netfilter/nft_immediate.c     |    8 -
 net/netfilter/nft_objref.c        |    8 +
 5 files changed, 141 insertions(+), 76 deletions(-)

--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1144,6 +1144,29 @@ int __nft_release_basechain(struct nft_c
 
 unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
 
+static inline bool nft_use_inc(u32 *use)
+{
+	if (*use == UINT_MAX)
+		return false;
+
+	(*use)++;
+
+	return true;
+}
+
+static inline void nft_use_dec(u32 *use)
+{
+	WARN_ON_ONCE((*use)-- == 0);
+}
+
+/* For error and abort path: restore use counter to previous state. */
+static inline void nft_use_inc_restore(u32 *use)
+{
+	WARN_ON_ONCE(!nft_use_inc(use));
+}
+
+#define nft_use_dec_restore	nft_use_dec
+
 /**
  *	struct nft_table - nf_tables table
  *
@@ -1227,8 +1250,8 @@ struct nft_object {
 	struct list_head		list;
 	struct rhlist_head		rhlhead;
 	struct nft_object_hash_key	key;
-	u32				genmask:2,
-					use:30;
+	u32				genmask:2;
+	u32				use;
 	u64				handle;
 	u16				udlen;
 	u8				*udata;
@@ -1330,8 +1353,8 @@ struct nft_flowtable {
 	char				*name;
 	int				hooknum;
 	int				ops_len;
-	u32				genmask:2,
-					use:30;
+	u32				genmask:2;
+	u32				use;
 	u64				handle;
 	/* runtime data below here */
 	struct list_head		hook_list ____cacheline_aligned;
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -255,8 +255,10 @@ int nf_tables_bind_chain(const struct nf
 	if (chain->bound)
 		return -EBUSY;
 
+	if (!nft_use_inc(&chain->use))
+		return -EMFILE;
+
 	chain->bound = true;
-	chain->use++;
 	nft_chain_trans_bind(ctx, chain);
 
 	return 0;
@@ -439,7 +441,7 @@ static int nft_delchain(struct nft_ctx *
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 	nft_deactivate_next(ctx->net, ctx->chain);
 
 	return 0;
@@ -478,7 +480,7 @@ nf_tables_delrule_deactivate(struct nft_
 	/* You cannot delete the same rule twice */
 	if (nft_is_active_next(ctx->net, rule)) {
 		nft_deactivate_next(ctx->net, rule);
-		ctx->chain->use--;
+		nft_use_dec(&ctx->chain->use);
 		return 0;
 	}
 	return -ENOENT;
@@ -645,7 +647,7 @@ static int nft_delset(const struct nft_c
 		nft_map_deactivate(ctx, set);
 
 	nft_deactivate_next(ctx->net, set);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -677,7 +679,7 @@ static int nft_delobj(struct nft_ctx *ct
 		return err;
 
 	nft_deactivate_next(ctx->net, obj);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -712,7 +714,7 @@ static int nft_delflowtable(struct nft_c
 		return err;
 
 	nft_deactivate_next(ctx->net, flowtable);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -2263,9 +2265,6 @@ static int nf_tables_addchain(struct nft
 	struct nft_rule **rules;
 	int err;
 
-	if (table->use == UINT_MAX)
-		return -EOVERFLOW;
-
 	if (nla[NFTA_CHAIN_HOOK]) {
 		struct nft_stats __percpu *stats = NULL;
 		struct nft_chain_hook hook;
@@ -2362,6 +2361,11 @@ static int nf_tables_addchain(struct nft
 	if (err < 0)
 		goto err_destroy_chain;
 
+	if (!nft_use_inc(&table->use)) {
+		err = -EMFILE;
+		goto err_use;
+	}
+
 	trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
 	if (IS_ERR(trans)) {
 		err = PTR_ERR(trans);
@@ -2378,10 +2382,11 @@ static int nf_tables_addchain(struct nft
 		goto err_unregister_hook;
 	}
 
-	table->use++;
-
 	return 0;
+
 err_unregister_hook:
+	nft_use_dec_restore(&table->use);
+err_use:
 	nf_tables_unregister_hook(net, table, chain);
 err_destroy_chain:
 	nf_tables_chain_destroy(ctx);
@@ -3566,9 +3571,6 @@ static int nf_tables_newrule(struct sk_b
 			return -EINVAL;
 		handle = nf_tables_alloc_handle(table);
 
-		if (chain->use == UINT_MAX)
-			return -EOVERFLOW;
-
 		if (nla[NFTA_RULE_POSITION]) {
 			pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
 			old_rule = __nft_rule_lookup(chain, pos_handle);
@@ -3662,6 +3664,11 @@ static int nf_tables_newrule(struct sk_b
 		}
 	}
 
+	if (!nft_use_inc(&chain->use)) {
+		err = -EMFILE;
+		goto err_release_rule;
+	}
+
 	if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
 		err = nft_delrule(&ctx, old_rule);
 		if (err < 0)
@@ -3693,7 +3700,6 @@ static int nf_tables_newrule(struct sk_b
 		}
 	}
 	kvfree(expr_info);
-	chain->use++;
 
 	if (flow)
 		nft_trans_flow_rule(trans) = flow;
@@ -3704,6 +3710,7 @@ static int nf_tables_newrule(struct sk_b
 	return 0;
 
 err_destroy_flow_rule:
+	nft_use_dec_restore(&chain->use);
 	if (flow)
 		nft_flow_rule_destroy(flow);
 err_release_rule:
@@ -4721,9 +4728,15 @@ static int nf_tables_newset(struct sk_bu
 	alloc_size = sizeof(*set) + size + udlen;
 	if (alloc_size < size || alloc_size > INT_MAX)
 		return -ENOMEM;
+
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	set = kvzalloc(alloc_size, GFP_KERNEL);
-	if (!set)
-		return -ENOMEM;
+	if (!set) {
+		err = -ENOMEM;
+		goto err_alloc;
+	}
 
 	name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
 	if (!name) {
@@ -4781,7 +4794,7 @@ static int nf_tables_newset(struct sk_bu
 		goto err_set_expr_alloc;
 
 	list_add_tail_rcu(&set->list, &table->sets);
-	table->use++;
+
 	return 0;
 
 err_set_expr_alloc:
@@ -4793,6 +4806,9 @@ err_set_init:
 	kfree(set->name);
 err_set_name:
 	kvfree(set);
+err_alloc:
+	nft_use_dec_restore(&table->use);
+
 	return err;
 }
 
@@ -4927,9 +4943,6 @@ int nf_tables_bind_set(const struct nft_
 	struct nft_set_binding *i;
 	struct nft_set_iter iter;
 
-	if (set->use == UINT_MAX)
-		return -EOVERFLOW;
-
 	if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
 		return -EBUSY;
 
@@ -4957,10 +4970,12 @@ int nf_tables_bind_set(const struct nft_
 			return iter.err;
 	}
 bind:
+	if (!nft_use_inc(&set->use))
+		return -EMFILE;
+
 	binding->chain = ctx->chain;
 	list_add_tail_rcu(&binding->list, &set->bindings);
 	nft_set_trans_bind(ctx, set);
-	set->use++;
 
 	return 0;
 }
@@ -5034,7 +5049,7 @@ void nf_tables_activate_set(const struct
 		nft_clear(ctx->net, set);
 	}
 
-	set->use++;
+	nft_use_inc_restore(&set->use);
 }
 EXPORT_SYMBOL_GPL(nf_tables_activate_set);
 
@@ -5050,7 +5065,7 @@ void nf_tables_deactivate_set(const stru
 		else
 			list_del_rcu(&binding->list);
 
-		set->use--;
+		nft_use_dec(&set->use);
 		break;
 	case NFT_TRANS_PREPARE:
 		if (nft_set_is_anonymous(set)) {
@@ -5059,7 +5074,7 @@ void nf_tables_deactivate_set(const stru
 
 			nft_deactivate_next(ctx->net, set);
 		}
-		set->use--;
+		nft_use_dec(&set->use);
 		return;
 	case NFT_TRANS_ABORT:
 	case NFT_TRANS_RELEASE:
@@ -5067,7 +5082,7 @@ void nf_tables_deactivate_set(const stru
 		    set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
 			nft_map_deactivate(ctx, set);
 
-		set->use--;
+		nft_use_dec(&set->use);
 		fallthrough;
 	default:
 		nf_tables_unbind_set(ctx, set, binding,
@@ -5803,7 +5818,7 @@ void nft_set_elem_destroy(const struct n
 		nft_set_elem_expr_destroy(&ctx, nft_set_ext_expr(ext));
 
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use--;
+		nft_use_dec(&(*nft_set_ext_obj(ext))->use);
 	kfree(elem);
 }
 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
@@ -6294,8 +6309,16 @@ static int nft_add_set_elem(struct nft_c
 				     set->objtype, genmask);
 		if (IS_ERR(obj)) {
 			err = PTR_ERR(obj);
+			obj = NULL;
+			goto err_parse_key_end;
+		}
+
+		if (!nft_use_inc(&obj->use)) {
+			err = -EMFILE;
+			obj = NULL;
 			goto err_parse_key_end;
 		}
+
 		err = nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
 		if (err < 0)
 			goto err_parse_key_end;
@@ -6367,10 +6390,9 @@ static int nft_add_set_elem(struct nft_c
 		udata->len = ulen - 1;
 		nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
 	}
-	if (obj) {
+	if (obj)
 		*nft_set_ext_obj(ext) = obj;
-		obj->use++;
-	}
+
 	err = nft_set_elem_expr_setup(ctx, ext, expr_array, num_exprs);
 	if (err < 0)
 		goto err_elem_expr;
@@ -6425,14 +6447,14 @@ err_set_full:
 err_element_clash:
 	kfree(trans);
 err_elem_expr:
-	if (obj)
-		obj->use--;
-
 	nf_tables_set_elem_destroy(ctx, set, elem.priv);
 err_parse_data:
 	if (nla[NFTA_SET_ELEM_DATA] != NULL)
 		nft_data_release(&elem.data.val, desc.type);
 err_parse_key_end:
+	if (obj)
+		nft_use_dec_restore(&obj->use);
+
 	nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
 err_parse_key:
 	nft_data_release(&elem.key.val, NFT_DATA_VALUE);
@@ -6511,7 +6533,7 @@ void nft_data_hold(const struct nft_data
 		case NFT_JUMP:
 		case NFT_GOTO:
 			chain = data->verdict.chain;
-			chain->use++;
+			nft_use_inc_restore(&chain->use);
 			break;
 		}
 	}
@@ -6526,7 +6548,7 @@ static void nft_setelem_data_activate(co
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
 		nft_data_hold(nft_set_ext_data(ext), set->dtype);
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use++;
+		nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
 }
 
 static void nft_setelem_data_deactivate(const struct net *net,
@@ -6538,7 +6560,7 @@ static void nft_setelem_data_deactivate(
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
 		nft_data_release(nft_set_ext_data(ext), set->dtype);
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use--;
+		nft_use_dec(&(*nft_set_ext_obj(ext))->use);
 }
 
 static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
@@ -7073,9 +7095,14 @@ static int nf_tables_newobj(struct sk_bu
 
 	nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla);
 
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	type = nft_obj_type_get(net, objtype);
-	if (IS_ERR(type))
-		return PTR_ERR(type);
+	if (IS_ERR(type)) {
+		err = PTR_ERR(type);
+		goto err_type;
+	}
 
 	obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
 	if (IS_ERR(obj)) {
@@ -7109,7 +7136,7 @@ static int nf_tables_newobj(struct sk_bu
 		goto err_obj_ht;
 
 	list_add_tail_rcu(&obj->list, &table->objects);
-	table->use++;
+
 	return 0;
 err_obj_ht:
 	/* queued in transaction log */
@@ -7125,6 +7152,9 @@ err_strdup:
 	kfree(obj);
 err_init:
 	module_put(type->owner);
+err_type:
+	nft_use_dec_restore(&table->use);
+
 	return err;
 }
 
@@ -7515,7 +7545,7 @@ void nf_tables_deactivate_flowtable(cons
 	case NFT_TRANS_PREPARE:
 	case NFT_TRANS_ABORT:
 	case NFT_TRANS_RELEASE:
-		flowtable->use--;
+		nft_use_dec(&flowtable->use);
 		fallthrough;
 	default:
 		return;
@@ -7863,9 +7893,14 @@ static int nf_tables_newflowtable(struct
 
 	nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla);
 
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
-	if (!flowtable)
-		return -ENOMEM;
+	if (!flowtable) {
+		err = -ENOMEM;
+		goto flowtable_alloc;
+	}
 
 	flowtable->table = table;
 	flowtable->handle = nf_tables_alloc_handle(table);
@@ -7920,7 +7955,6 @@ static int nf_tables_newflowtable(struct
 		goto err5;
 
 	list_add_tail_rcu(&flowtable->list, &table->flowtables);
-	table->use++;
 
 	return 0;
 err5:
@@ -7937,6 +7971,9 @@ err2:
 	kfree(flowtable->name);
 err1:
 	kfree(flowtable);
+flowtable_alloc:
+	nft_use_dec_restore(&table->use);
+
 	return err;
 }
 
@@ -9173,7 +9210,7 @@ static int nf_tables_commit(struct net *
 				 */
 				if (nft_set_is_anonymous(nft_trans_set(trans)) &&
 				    !list_empty(&nft_trans_set(trans)->bindings))
-					trans->ctx.table->use--;
+					nft_use_dec(&trans->ctx.table->use);
 			}
 			nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
 					     NFT_MSG_NEWSET, GFP_KERNEL);
@@ -9392,7 +9429,7 @@ static int __nf_tables_abort(struct net
 					nft_trans_destroy(trans);
 					break;
 				}
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				nft_chain_del(trans->ctx.chain);
 				nf_tables_unregister_hook(trans->ctx.net,
 							  trans->ctx.table,
@@ -9400,7 +9437,7 @@ static int __nf_tables_abort(struct net
 			}
 			break;
 		case NFT_MSG_DELCHAIN:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, trans->ctx.chain);
 			nft_trans_destroy(trans);
 			break;
@@ -9409,7 +9446,7 @@ static int __nf_tables_abort(struct net
 				nft_trans_destroy(trans);
 				break;
 			}
-			trans->ctx.chain->use--;
+			nft_use_dec_restore(&trans->ctx.chain->use);
 			list_del_rcu(&nft_trans_rule(trans)->list);
 			nft_rule_expr_deactivate(&trans->ctx,
 						 nft_trans_rule(trans),
@@ -9418,7 +9455,7 @@ static int __nf_tables_abort(struct net
 				nft_flow_rule_destroy(nft_trans_flow_rule(trans));
 			break;
 		case NFT_MSG_DELRULE:
-			trans->ctx.chain->use++;
+			nft_use_inc_restore(&trans->ctx.chain->use);
 			nft_clear(trans->ctx.net, nft_trans_rule(trans));
 			nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
 			if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
@@ -9431,7 +9468,7 @@ static int __nf_tables_abort(struct net
 				nft_trans_destroy(trans);
 				break;
 			}
-			trans->ctx.table->use--;
+			nft_use_dec_restore(&trans->ctx.table->use);
 			if (nft_trans_set_bound(trans)) {
 				nft_trans_destroy(trans);
 				break;
@@ -9439,7 +9476,7 @@ static int __nf_tables_abort(struct net
 			list_del_rcu(&nft_trans_set(trans)->list);
 			break;
 		case NFT_MSG_DELSET:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, nft_trans_set(trans));
 			if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
 				nft_map_activate(&trans->ctx, nft_trans_set(trans));
@@ -9482,12 +9519,12 @@ static int __nf_tables_abort(struct net
 				nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans));
 				nft_trans_destroy(trans);
 			} else {
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				nft_obj_del(nft_trans_obj(trans));
 			}
 			break;
 		case NFT_MSG_DELOBJ:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, nft_trans_obj(trans));
 			nft_trans_destroy(trans);
 			break;
@@ -9496,7 +9533,7 @@ static int __nf_tables_abort(struct net
 				nft_unregister_flowtable_net_hooks(net,
 						&nft_trans_flowtable_hooks(trans));
 			} else {
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				list_del_rcu(&nft_trans_flowtable(trans)->list);
 				nft_unregister_flowtable_net_hooks(net,
 						&nft_trans_flowtable(trans)->hook_list);
@@ -9507,7 +9544,7 @@ static int __nf_tables_abort(struct net
 				list_splice(&nft_trans_flowtable_hooks(trans),
 					    &nft_trans_flowtable(trans)->hook_list);
 			} else {
-				trans->ctx.table->use++;
+				nft_use_inc_restore(&trans->ctx.table->use);
 				nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
 			}
 			nft_trans_destroy(trans);
@@ -9960,8 +9997,9 @@ static int nft_verdict_init(const struct
 		if (desc->flags & NFT_DATA_DESC_SETELEM &&
 		    chain->flags & NFT_CHAIN_BINDING)
 			return -EINVAL;
+		if (!nft_use_inc(&chain->use))
+			return -EMFILE;
 
-		chain->use++;
 		data->verdict.chain = chain;
 		break;
 	}
@@ -9979,7 +10017,7 @@ static void nft_verdict_uninit(const str
 	case NFT_JUMP:
 	case NFT_GOTO:
 		chain = data->verdict.chain;
-		chain->use--;
+		nft_use_dec(&chain->use);
 		break;
 	}
 }
@@ -10148,11 +10186,11 @@ int __nft_release_basechain(struct nft_c
 	nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
 	list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
 		list_del(&rule->list);
-		ctx->chain->use--;
+		nft_use_dec(&ctx->chain->use);
 		nf_tables_rule_release(ctx, rule);
 	}
 	nft_chain_del(ctx->chain);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 	nf_tables_chain_destroy(ctx);
 
 	return 0;
@@ -10205,18 +10243,18 @@ static void __nft_release_table(struct n
 		ctx.chain = chain;
 		list_for_each_entry_safe(rule, nr, &chain->rules, list) {
 			list_del(&rule->list);
-			chain->use--;
+			nft_use_dec(&chain->use);
 			nf_tables_rule_release(&ctx, rule);
 		}
 	}
 	list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
 		list_del(&flowtable->list);
-		table->use--;
+		nft_use_dec(&table->use);
 		nf_tables_flowtable_destroy(flowtable);
 	}
 	list_for_each_entry_safe(set, ns, &table->sets, list) {
 		list_del(&set->list);
-		table->use--;
+		nft_use_dec(&table->use);
 		if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
 			nft_map_deactivate(&ctx, set);
 
@@ -10224,13 +10262,13 @@ static void __nft_release_table(struct n
 	}
 	list_for_each_entry_safe(obj, ne, &table->objects, list) {
 		nft_obj_del(obj);
-		table->use--;
+		nft_use_dec(&table->use);
 		nft_obj_destroy(&ctx, obj);
 	}
 	list_for_each_entry_safe(chain, nc, &table->chains, list) {
 		ctx.chain = chain;
 		nft_chain_del(chain);
-		table->use--;
+		nft_use_dec(&table->use);
 		nf_tables_chain_destroy(&ctx);
 	}
 	nf_tables_table_destroy(&ctx);
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -381,8 +381,10 @@ static int nft_flow_offload_init(const s
 	if (IS_ERR(flowtable))
 		return PTR_ERR(flowtable);
 
+	if (!nft_use_inc(&flowtable->use))
+		return -EMFILE;
+
 	priv->flowtable = flowtable;
-	flowtable->use++;
 
 	return nf_ct_netns_get(ctx->net, ctx->family);
 }
@@ -401,7 +403,7 @@ static void nft_flow_offload_activate(co
 {
 	struct nft_flow_offload *priv = nft_expr_priv(expr);
 
-	priv->flowtable->use++;
+	nft_use_inc_restore(&priv->flowtable->use);
 }
 
 static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -168,7 +168,7 @@ static void nft_immediate_deactivate(con
 				nft_immediate_chain_deactivate(ctx, chain, phase);
 				nft_chain_del(chain);
 				chain->bound = false;
-				chain->table->use--;
+				nft_use_dec(&chain->table->use);
 				break;
 			}
 			break;
@@ -207,7 +207,7 @@ static void nft_immediate_destroy(const
 		 * let the transaction records release this chain and its rules.
 		 */
 		if (chain->bound) {
-			chain->use--;
+			nft_use_dec(&chain->use);
 			break;
 		}
 
@@ -215,9 +215,9 @@ static void nft_immediate_destroy(const
 		chain_ctx = *ctx;
 		chain_ctx.chain = chain;
 
-		chain->use--;
+		nft_use_dec(&chain->use);
 		list_for_each_entry_safe(rule, n, &chain->rules, list) {
-			chain->use--;
+			nft_use_dec(&chain->use);
 			list_del(&rule->list);
 			nf_tables_rule_destroy(&chain_ctx, rule);
 		}
--- a/net/netfilter/nft_objref.c
+++ b/net/netfilter/nft_objref.c
@@ -41,8 +41,10 @@ static int nft_objref_init(const struct
 	if (IS_ERR(obj))
 		return -ENOENT;
 
+	if (!nft_use_inc(&obj->use))
+		return -EMFILE;
+
 	nft_objref_priv(expr) = obj;
-	obj->use++;
 
 	return 0;
 }
@@ -71,7 +73,7 @@ static void nft_objref_deactivate(const
 	if (phase == NFT_TRANS_COMMIT)
 		return;
 
-	obj->use--;
+	nft_use_dec(&obj->use);
 }
 
 static void nft_objref_activate(const struct nft_ctx *ctx,
@@ -79,7 +81,7 @@ static void nft_objref_activate(const st
 {
 	struct nft_object *obj = nft_objref_priv(expr);
 
-	obj->use++;
+	nft_use_inc_restore(&obj->use);
 }
 
 static struct nft_expr_type nft_objref_type;



  parent reply	other threads:[~2023-08-13 21:46 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-13 21:18 [PATCH 5.15 00/89] 5.15.127-rc1 review Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 01/89] ksmbd: validate command request size Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 02/89] ksmbd: fix wrong next length validation of ea buffer in smb2_set_ea() Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 03/89] wireguard: allowedips: expand maximum node depth Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 04/89] mmc: moxart: read scr register without changing byte order Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 05/89] ipv6: adjust ndisc_is_useropt() to also return true for PIO Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 06/89] dmaengine: pl330: Return DMA_PAUSED when transaction is paused Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 07/89] riscv,mmio: Fix readX()-to-delay() ordering Greg Kroah-Hartman
2023-08-13 21:18 ` [PATCH 5.15 08/89] drm/nouveau/gr: enable memory loads on helper invocation on all channels Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 09/89] drm/shmem-helper: Reset vma->vm_ops before calling dma_buf_mmap() Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 10/89] drm/amd/display: check attr flag before set cursor degamma on DCN3+ Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 11/89] hwmon: (pmbus/bel-pfe) Enable PMBUS_SKIP_STATUS_CHECK for pfe1100 Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 12/89] radix tree test suite: fix incorrect allocation size for pthreads Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 13/89] nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 14/89] bpf: allow precision tracking for programs with subprogs Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 15/89] bpf: stop setting precise in current state Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 16/89] bpf: aggressively forget precise markings during state checkpointing Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 17/89] selftests/bpf: make test_align selftest more robust Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 18/89] selftests/bpf: Workaround verification failure for fexit_bpf2bpf/func_replace_return_code Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 19/89] selftests/bpf: Fix sk_assign on s390x Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 20/89] io_uring: correct check for O_TMPFILE Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 21/89] iio: cros_ec: Fix the allocation size for cros_ec_command Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 22/89] iio: adc: ina2xx: avoid NULL pointer dereference on OF device match Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 23/89] binder: fix memory leak in binder_init() Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 24/89] misc: rtsx: judge ASPM Mode to set PETXCFG Reg Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 25/89] usb-storage: alauda: Fix uninit-value in alauda_check_media() Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 26/89] usb: dwc3: Properly handle processing of pending events Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 27/89] usb: common: usb-conn-gpio: Prevent bailing out if initial role is none Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 28/89] usb: typec: tcpm: Fix response to vsafe0V event Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 29/89] x86/srso: Fix build breakage with the LLVM linker Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 30/89] x86/cpu/amd: Enable Zenbleed fix for AMD Custom APU 0405 Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 31/89] x86/mm: Fix VDSO and VVAR placement on 5-level paging machines Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 32/89] x86/speculation: Add cpu_show_gds() prototype Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 33/89] x86: Move gds_ucode_mitigated() declaration to header Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 34/89] drm/nouveau/disp: Revert a NULL check inside nouveau_connector_get_modes Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 35/89] netfilter: nf_tables: dont skip expired elements during walk Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 36/89] selftests/rseq: Fix build with undefined __weak Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 37/89] selftests: forwarding: Add a helper to skip test when using veth pairs Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 38/89] selftests: forwarding: ethtool: Skip " Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 39/89] selftests: forwarding: ethtool_extended_state: " Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 40/89] selftests: forwarding: Skip test when no interfaces are specified Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 41/89] selftests: forwarding: Switch off timeout Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 42/89] selftests: forwarding: tc_flower: Relax success criterion Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 43/89] net: core: remove unnecessary frame_sz check in bpf_xdp_adjust_tail() Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 44/89] bpf, sockmap: Fix map type error in sock_map_del_link Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 45/89] bpf, sockmap: Fix bug that strp_done cannot be called Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 46/89] mISDN: Update parameter type of dsp_cmx_send() Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 47/89] net/packet: annotate data-races around tp->status Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 48/89] tunnels: fix kasan splat when generating ipv4 pmtu error Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 49/89] xsk: fix refcount underflow in error path Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 50/89] bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 51/89] dccp: fix data-race around dp->dccps_mss_cache Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 52/89] drivers: net: prevent tun_build_skb() to exceed the packet size limit Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 53/89] iavf: fix potential races for FDIR filters Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 54/89] IB/hfi1: Fix possible panic during hotplug remove Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 55/89] drm/rockchip: Dont spam logs in atomic check Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 56/89] wifi: cfg80211: fix sband iftype data lookup for AP_VLAN Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 57/89] RDMA/umem: Set iova in ODP flow Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 58/89] net: phy: at803x: remove set/get wol callbacks for AR8032 Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 59/89] net: hns3: refactor hclge_mac_link_status_wait for interface reuse Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 60/89] net: hns3: add wait until mac link down Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 61/89] nexthop: Fix infinite nexthop dump when using maximum nexthop ID Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 62/89] nexthop: Make nexthop bucket dump more efficient Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 63/89] nexthop: Fix infinite nexthop bucket dump when using maximum nexthop ID Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 64/89] dmaengine: mcf-edma: Fix a potential un-allocated memory access Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 65/89] net/mlx5: Allow 0 for total host VFs Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 66/89] net/mlx5: Skip clock update work when device is in error state Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 67/89] ibmvnic: Enforce stronger sanity checks on login response Greg Kroah-Hartman
2023-08-13 21:19 ` [PATCH 5.15 68/89] ibmvnic: Unmap DMA login rsp buffer on send login fail Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 69/89] ibmvnic: Handle DMA unmapping of login buffs in release functions Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 70/89] btrfs: dont stop integrity writeback too early Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 71/89] btrfs: exit gracefully if reloc roots dont match Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 72/89] btrfs: reject invalid reloc tree root keys with stack dump Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 73/89] btrfs: set cache_block_group_error if we find an error Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 74/89] nvme-tcp: fix potential unbalanced freeze & unfreeze Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 75/89] nvme-rdma: " Greg Kroah-Hartman
2023-08-13 21:20 ` Greg Kroah-Hartman [this message]
2023-08-13 21:20 ` [PATCH 5.15 77/89] scsi: core: Fix legacy /proc parsing buffer overflow Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 78/89] scsi: storvsc: Fix handling of virtual Fibre Channel timeouts Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 79/89] scsi: 53c700: Check that command slot is not NULL Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 80/89] scsi: snic: Fix possible memory leak if device_add() fails Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 81/89] scsi: core: " Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 82/89] scsi: fnic: Replace return codes in fnic_clean_pending_aborts() Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 83/89] scsi: qedi: Fix firmware halt over suspend and resume Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 84/89] scsi: qedf: " Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 85/89] alpha: remove __init annotation from exported page_is_ram() Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 86/89] sch_netem: fix issues in netem_change() vs get_dist_table() Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 87/89] tick: Detect and fix jiffies update stall Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 88/89] timers/nohz: Switch to ONESHOT_STOPPED in the low-res handler when the tick is stopped Greg Kroah-Hartman
2023-08-13 21:20 ` [PATCH 5.15 89/89] timers/nohz: Last resort update jiffies on nohz_full IRQ entry Greg Kroah-Hartman
2023-08-14 14:49 ` [PATCH 5.15 00/89] 5.15.127-rc1 review Thierry Reding
2023-08-14 17:33 ` SeongJae Park
2023-08-14 18:27 ` Guenter Roeck
2023-08-15  0:33 ` Ron Economos
2023-08-15  0:50 ` Shuah Khan
2023-08-15  1:42 ` Harshit Mogalapalli
2023-08-15  5:04 ` Daniel Díaz
2023-08-15 16:37 ` Florian Fainelli
2023-08-15 17:07 ` Allen Pais
2023-08-16 16:36 ` Thierry Reding
2023-08-16 22:26 ` Joel Fernandes

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=20230813211713.054482840@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=patches@lists.linux.dev \
    --cc=stable@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).