netfilter: nf_tables: sanitize nft_set_desc_concat_parse()
commit fecf31ee395b0295f2d7260aa29946b7605f7c85 upstream.
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: f3a2181e16
("netfilter: nf_tables: Support for sets with multiple ranged fields")
Reported-by: <zhangziming.zzm@antgroup.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
44f1ce5530
commit
c0aff1faf6
@@ -4051,6 +4051,9 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
|
|||||||
u32 len;
|
u32 len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (desc->field_count >= ARRAY_SIZE(desc->field_len))
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
|
err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
|
||||||
nft_concat_policy, NULL);
|
nft_concat_policy, NULL);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -4060,9 +4063,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
|
len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
|
||||||
|
if (!len || len > U8_MAX)
|
||||||
if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT)
|
return -EINVAL;
|
||||||
return -E2BIG;
|
|
||||||
|
|
||||||
desc->field_len[desc->field_count++] = len;
|
desc->field_len[desc->field_count++] = len;
|
||||||
|
|
||||||
@@ -4073,7 +4075,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
|
|||||||
const struct nlattr *nla)
|
const struct nlattr *nla)
|
||||||
{
|
{
|
||||||
struct nlattr *attr;
|
struct nlattr *attr;
|
||||||
int rem, err;
|
u32 num_regs = 0;
|
||||||
|
int rem, err, i;
|
||||||
|
|
||||||
nla_for_each_nested(attr, nla, rem) {
|
nla_for_each_nested(attr, nla, rem) {
|
||||||
if (nla_type(attr) != NFTA_LIST_ELEM)
|
if (nla_type(attr) != NFTA_LIST_ELEM)
|
||||||
@@ -4084,6 +4087,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < desc->field_count; i++)
|
||||||
|
num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
|
||||||
|
|
||||||
|
if (num_regs > NFT_REG32_COUNT)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user