]>
Commit | Line | Data |
---|---|---|
ad0a766e TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Pablo Neira Ayuso <pablo@netfilter.org> | |
3 | Date: Fri, 27 May 2022 09:56:18 +0200 | |
4 | Subject: [PATCH] netfilter: nf_tables: sanitize nft_set_desc_concat_parse() | |
5 | ||
6 | BugLink: https://bugs.launchpad.net/bugs/1976363 (netfilter newset OOB write (LP: #1976363)) | |
7 | ||
8 | Add several sanity checks for nft_set_desc_concat_parse(): | |
9 | ||
10 | - validate desc->field_count not larger than desc->field_len array. | |
11 | - field length cannot be larger than desc->field_len (ie. U8_MAX) | |
12 | - total length of the concatenation cannot be larger than register array. | |
13 | ||
14 | Joint work with Florian Westphal. | |
15 | ||
16 | Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields") | |
17 | Reported-by: <zhangziming.zzm@antgroup.com> | |
18 | Reviewed-by: Stefano Brivio <sbrivio@redhat.com> | |
19 | Signed-off-by: Florian Westphal <fw@strlen.de> | |
20 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |
21 | (cherry picked from commit fecf31ee395b0295f2d7260aa29946b7605f7c85 net.git) | |
22 | Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> | |
23 | Acked-by: Andrea Righi <andrea.righi@canonical.com> | |
24 | Acked-by: Stefan Bader <stefan.bader@canonical.com> | |
25 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
26 | --- | |
27 | net/netfilter/nf_tables_api.c | 17 +++++++++++++---- | |
28 | 1 file changed, 13 insertions(+), 4 deletions(-) | |
29 | ||
30 | diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c | |
31 | index 91865dc2bcbb..ee4edebe6124 100644 | |
32 | --- a/net/netfilter/nf_tables_api.c | |
33 | +++ b/net/netfilter/nf_tables_api.c | |
34 | @@ -4151,6 +4151,9 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, | |
35 | u32 len; | |
36 | int err; | |
37 | ||
38 | + if (desc->field_count >= ARRAY_SIZE(desc->field_len)) | |
39 | + return -E2BIG; | |
40 | + | |
41 | err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr, | |
42 | nft_concat_policy, NULL); | |
43 | if (err < 0) | |
44 | @@ -4160,9 +4163,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, | |
45 | return -EINVAL; | |
46 | ||
47 | len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN])); | |
48 | - | |
49 | - if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT) | |
50 | - return -E2BIG; | |
51 | + if (!len || len > U8_MAX) | |
52 | + return -EINVAL; | |
53 | ||
54 | desc->field_len[desc->field_count++] = len; | |
55 | ||
56 | @@ -4173,7 +4175,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, | |
57 | const struct nlattr *nla) | |
58 | { | |
59 | struct nlattr *attr; | |
60 | - int rem, err; | |
61 | + u32 num_regs = 0; | |
62 | + int rem, err, i; | |
63 | ||
64 | nla_for_each_nested(attr, nla, rem) { | |
65 | if (nla_type(attr) != NFTA_LIST_ELEM) | |
66 | @@ -4184,6 +4187,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, | |
67 | return err; | |
68 | } | |
69 | ||
70 | + for (i = 0; i < desc->field_count; i++) | |
71 | + num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); | |
72 | + | |
73 | + if (num_regs > NFT_REG32_COUNT) | |
74 | + return -E2BIG; | |
75 | + | |
76 | return 0; | |
77 | } | |
78 |