Add several sanity checks for nft_set_desc_concat_parse(): - validate desc->field_count not larger than desc->field_len array. - field length cannot be larger than desc->field_len (ie. U8_MAX) - total length of the concatenation cannot be larger than register array. Joint work with Florian Westphal. Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields") Reported-by: <zhangziming.zzm@xxxxxxxxxxxx> Reviewed-by: Stefano Brivio <sbrivio@xxxxxxxxxx> Reviewed-by: Florian Westphal <fw@xxxxxxxxx> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- net/netfilter/nf_tables_api.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index f4f1d0a2da43..0c7a755dfabb 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4243,8 +4243,11 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, struct nft_set_desc *desc) { struct nlattr *tb[NFTA_SET_FIELD_MAX + 1]; - u32 len; - int err; + u32 len, total = 0; + int err, i; + + if (desc->field_count >= ARRAY_SIZE(desc->field_len)) + return -E2BIG; err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr, nft_concat_policy, NULL); @@ -4255,12 +4258,17 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, return -EINVAL; len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN])); - - if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT) + if (len > U8_MAX) return -E2BIG; desc->field_len[desc->field_count++] = len; + for (i = 0; i < desc->field_count; i++) + total += desc->field_len[i]; + + if (total > U8_MAX || total * BITS_PER_BYTE / 32 > NFT_REG32_COUNT) + return -E2BIG; + return 0; } -- 2.30.2