From 983d67f10dbf725be12c3f19d8a2eea71912bd0c Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 13 Sep 2022 16:47:56 +0800 Subject: [PATCH] netfilter: nf_tables: do not allow SET_ID to refer to another table stable inclusion from stable-v5.10.137 commit 1a4b18b1ff11ba26f9a852019d674fde9d1d1cff category: bugfix bugzilla: 187457, https://gitee.com/src-openeuler/kernel/issues/I5MEZD CVE: CVE-2022-2586 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1a4b18b1ff11ba26f9a852019d674fde9d1d1cff -------------------------------- commit 470ee20e069a6d05ae549f7d0ef2bdbcee6a81b2 upstream. When doing lookups for sets on the same batch by using its ID, a set from a different table can be used. Then, when the table is removed, a reference to the set may be kept after the set is freed, leading to a potential use-after-free. When looking for sets by ID, use the table that was used for the lookup by name, and only return sets belonging to that same table. This fixes CVE-2022-2586, also reported as ZDI-CAN-17470. Reported-by: Team Orca of Sea Security (@seasecresponse) Fixes: 958bee14d071 ("netfilter: nf_tables: use new transaction infrastructure to handle sets") Signed-off-by: Thadeu Lima de Souza Cascardo Cc: Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lu Wei Reviewed-by: Wei Yongjun Reviewed-by: Yue Haibing Signed-off-by: Zheng Zengkai --- net/netfilter/nf_tables_api.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 560a93aad5b6..7b0497da2d94 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3638,6 +3638,7 @@ static struct nft_set *nft_set_lookup_byhandle(const struct nft_table *table, } static struct nft_set *nft_set_lookup_byid(const struct net *net, + const struct nft_table *table, const struct nlattr *nla, u8 genmask) { struct nft_trans *trans; @@ -3648,6 +3649,7 @@ static struct nft_set *nft_set_lookup_byid(const struct net *net, struct nft_set *set = nft_trans_set(trans); if (id == nft_trans_set_id(trans) && + set->table == table && nft_active_genmask(set, genmask)) return set; } @@ -3668,7 +3670,7 @@ struct nft_set *nft_set_lookup_global(const struct net *net, if (!nla_set_id) return set; - set = nft_set_lookup_byid(net, nla_set_id, genmask); + set = nft_set_lookup_byid(net, table, nla_set_id, genmask); } return set; } -- GitLab