Hi Pablo, While checking netfilter backports to the stable series, I noticed that 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.") was backported in various series for stable, and included in 4.14.316, 4.19.284, 5.4.244, 5.15.32, 5.16.18, 5.17.1, where the original fix was in 5.18-rc1. While the commit has Fixes: 49499c3e6e18 ("netfilter: nf_tables: switch registers to 32 bit addressing") the 6e1acfa387b9 change got not backported to the 5.10.y series. The backports to the other series are https://lore.kernel.org/stable/20230516151606.4892-1-pablo@xxxxxxxxxxxxx/ https://lore.kernel.org/stable/20230516150613.4566-1-pablo@xxxxxxxxxxxxx/ https://lore.kernel.org/stable/20230516144435.4010-1-pablo@xxxxxxxxxxxxx/ Pablo, was this an oversight and can the change as well be applied to 5.10.y? >From looking at the 5.4.y series, from the stable dependencies, 08a01c11a5bb ("netfilter: nftables: statify nft_parse_register()") is missing in 5.10.y, then 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.") can be applied (almost, the comment needs to be dropped, as done in the backports). I'm right now not understanding what I'm missing that it was for 5.4.y but not 5.10.y after the report of the failed apply by Greg. At least the two attached bring 5.10.y inline with 5.4.y up to 4) from https://lore.kernel.org/stable/20230516144435.4010-1-pablo@xxxxxxxxxxxxx/ but I'm unsure if you want/need as well the remaining 5), 6), 7), 8) and 9). Regards, Salvatore
>From f53985195412088bec0aec9eb4283d669472c608 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> Date: Mon, 25 Jan 2021 23:19:17 +0100 Subject: [PATCH 1/2] netfilter: nftables: statify nft_parse_register() commit 08a01c11a5bb3de9b0a9c9b2685867e50eda9910 upstream. This function is not used anymore by any extension, statify it. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/net/netfilter/nf_tables.h | 1 - net/netfilter/nf_tables_api.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 564fbe0c865f..030237f3d82a 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -205,7 +205,6 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) } int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); -unsigned int nft_parse_register(const struct nlattr *attr); int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index fe51cedd9cc3..e1e1cde42075 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -8489,7 +8489,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check); * Registers used to be 128 bit wide, these register numbers will be * mapped to the corresponding 32 bit register numbers. */ -unsigned int nft_parse_register(const struct nlattr *attr) +static unsigned int nft_parse_register(const struct nlattr *attr) { unsigned int reg; @@ -8501,7 +8501,6 @@ unsigned int nft_parse_register(const struct nlattr *attr) return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; } } -EXPORT_SYMBOL_GPL(nft_parse_register); /** * nft_dump_register - dump a register value to a netlink attribute -- 2.40.1
>From cfc6c33490e1b9c8c6a9a74f5540ccd3840ae545 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> Date: Thu, 17 Mar 2022 11:59:26 +0100 Subject: [PATCH 2/2] netfilter: nf_tables: validate registers coming from userspace. commit 6e1acfa387b9ff82cfc7db8cc3b6959221a95851 upstream. Bail out in case userspace uses unsupported registers. Fixes: 49499c3e6e18 ("netfilter: nf_tables: switch registers to 32 bit addressing") Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- net/netfilter/nf_tables_api.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index e1e1cde42075..e430788d6d19 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -8480,26 +8480,23 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) } EXPORT_SYMBOL_GPL(nft_parse_u32_check); -/** - * nft_parse_register - parse a register value from a netlink attribute - * - * @attr: netlink attribute - * - * Parse and translate a register value from a netlink attribute. - * Registers used to be 128 bit wide, these register numbers will be - * mapped to the corresponding 32 bit register numbers. - */ -static unsigned int nft_parse_register(const struct nlattr *attr) +static unsigned int nft_parse_register(const struct nlattr *attr, u32 *preg) { unsigned int reg; reg = ntohl(nla_get_be32(attr)); switch (reg) { case NFT_REG_VERDICT...NFT_REG_4: - return reg * NFT_REG_SIZE / NFT_REG32_SIZE; + *preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE; + break; + case NFT_REG32_00...NFT_REG32_15: + *preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; + break; default: - return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; + return -ERANGE; } + + return 0; } /** @@ -8550,7 +8547,10 @@ int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len) u32 reg; int err; - reg = nft_parse_register(attr); + err = nft_parse_register(attr, ®); + if (err < 0) + return err; + err = nft_validate_register_load(reg, len); if (err < 0) return err; @@ -8619,7 +8619,10 @@ int nft_parse_register_store(const struct nft_ctx *ctx, int err; u32 reg; - reg = nft_parse_register(attr); + err = nft_parse_register(attr, ®); + if (err < 0) + return err; + err = nft_validate_register_store(ctx, reg, data, type, len); if (err < 0) return err; -- 2.40.1