From 12aa17d045049e8fec6d0fab778fbd0d59035e08 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 28 Jan 2025 12:26:33 +0100 Subject: [PATCH] netfilter: nf_tables: reject mismatching sum of field_len with set key length mainline inclusion from mainline-v6.14-rc1 commit 1b9335a8000fb70742f7db10af314104b6ace220 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBY3Y7 CVE: CVE-2025-21826 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b9335a8000fb70742f7db10af314104b6ace220 ------------------------------------------------- The field length description provides the length of each separated key field in the concatenation, each field gets rounded up to 32-bits to calculate the pipapo rule width from pipapo_init(). The set key length provides the total size of the key aligned to 32-bits. Register-based arithmetics still allows for combining mismatching set key length and field length description, eg. set key length 10 and field description [ 5, 4 ] leading to pipapo width of 12. Cc: stable@vger.kernel.org Fixes: 3ce67e3793f4 ("netfilter: nf_tables: do not allow mismatch field size and set key length") Reported-by: Noam Rathaus Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: xinxin <2271170409@qq.com> --- net/netfilter/nf_tables_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 81caffd53912..4726eb54021e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4351,7 +4351,7 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, static int nft_set_desc_concat(struct nft_set_desc *desc, const struct nlattr *nla) { - u32 num_regs = 0, key_num_regs = 0; + u32 len = 0, num_regs; struct nlattr *attr; int rem, err, i; @@ -4365,12 +4365,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, } for (i = 0; i < desc->field_count; i++) - num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); + len += round_up(desc->field_len[i], sizeof(u32)); - key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); - if (key_num_regs != num_regs) + if (len != desc->klen) return -EINVAL; + num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); if (num_regs > NFT_REG32_COUNT) return -E2BIG; -- Gitee