Use kfree_rcu() to release flowtable from error path, since a hook that already refers to this flowtable can be already registered, exposing this flowtable to packet path and nfnetlink_hook control plane. Uncovered by KASAN reported as use-after-free from nfnetlink_hook path when dumping hooks. The number of flowtable objects in a ruleset are expected to be small, the increment is memory consumption should be negligible. In older kernels, users could mistype device names leading to this error path, I prefer struct rcu_head here instead of explicit synchronize_rcu() call. Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend") Reported-by: Yiming Qian Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 2 ++ net/netfilter/nf_tables_api.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 3c8a60ec1cc4..ae9905b5ba72 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1483,6 +1483,7 @@ void nft_unregister_obj(struct nft_object_type *obj_type); * @genmask: generation mask * @use: number of references to this flow table * @handle: unique object handle + * @rcu_head: deferred release for error path * @hook_list: hook list for hooks per net_device in flowtables * @data: rhashtable and garbage collector */ @@ -1495,6 +1496,7 @@ struct nft_flowtable { u32 genmask:2; u32 use; u64 handle; + struct rcu_head rcu_head; /* runtime data below here */ struct list_head hook_list ____cacheline_aligned; struct nf_flowtable data; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 2f19c155069e..16b80e17247f 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -9229,7 +9229,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb, err2: kfree(flowtable->name); err1: - kfree(flowtable); + kfree_rcu(flowtable, rcu_head); flowtable_alloc: nft_use_dec_restore(&table->use); -- 2.47.3