Skip to content

Commit fecf31e

Browse files
committed
netfilter: nf_tables: sanitize nft_set_desc_concat_parse()
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: f3a2181 ("netfilter: nf_tables: Support for sets with multiple ranged fields") Reported-by: <[email protected]> Reviewed-by: Stefano Brivio <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 09e545f commit fecf31e

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4246,6 +4246,9 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
42464246
u32 len;
42474247
int err;
42484248

4249+
if (desc->field_count >= ARRAY_SIZE(desc->field_len))
4250+
return -E2BIG;
4251+
42494252
err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
42504253
nft_concat_policy, NULL);
42514254
if (err < 0)
@@ -4255,9 +4258,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
42554258
return -EINVAL;
42564259

42574260
len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
4258-
4259-
if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT)
4260-
return -E2BIG;
4261+
if (!len || len > U8_MAX)
4262+
return -EINVAL;
42614263

42624264
desc->field_len[desc->field_count++] = len;
42634265

@@ -4268,7 +4270,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
42684270
const struct nlattr *nla)
42694271
{
42704272
struct nlattr *attr;
4271-
int rem, err;
4273+
u32 num_regs = 0;
4274+
int rem, err, i;
42724275

42734276
nla_for_each_nested(attr, nla, rem) {
42744277
if (nla_type(attr) != NFTA_LIST_ELEM)
@@ -4279,6 +4282,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
42794282
return err;
42804283
}
42814284

4285+
for (i = 0; i < desc->field_count; i++)
4286+
num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
4287+
4288+
if (num_regs > NFT_REG32_COUNT)
4289+
return -E2BIG;
4290+
42824291
return 0;
42834292
}
42844293

0 commit comments

Comments
 (0)