Skip to content

Commit

Permalink
netfilter: nftables: avoid potential overflows on 32bit arches
Browse files Browse the repository at this point in the history
commit 6c8774a upstream.

User space could ask for very large hash tables, we need to make sure
our size computations wont overflow.

nf_tables_newset() needs to double check the u64 size
will fit into size_t field.

Fixes: 0ed6389 ("netfilter: nf_tables: rename set implementations")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Eric Dumazet authored and gregkh committed Sep 12, 2021
1 parent cad6239 commit 3fda454
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 7 deletions.
7 changes: 5 additions & 2 deletions net/netfilter/nf_tables_api.c
Expand Up @@ -4115,6 +4115,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
struct nft_table *table;
struct nft_set *set;
struct nft_ctx ctx;
size_t alloc_size;
char *name;
u64 size;
u64 timeout;
Expand Down Expand Up @@ -4263,8 +4264,10 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
size = 0;
if (ops->privsize != NULL)
size = ops->privsize(nla, &desc);

set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
alloc_size = sizeof(*set) + size + udlen;
if (alloc_size < size)
return -ENOMEM;
set = kvzalloc(alloc_size, GFP_KERNEL);
if (!set)
return -ENOMEM;

Expand Down
10 changes: 5 additions & 5 deletions net/netfilter/nft_set_hash.c
Expand Up @@ -604,7 +604,7 @@ static u64 nft_hash_privsize(const struct nlattr * const nla[],
const struct nft_set_desc *desc)
{
return sizeof(struct nft_hash) +
nft_hash_buckets(desc->size) * sizeof(struct hlist_head);
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head);
}

static int nft_hash_init(const struct nft_set *set,
Expand Down Expand Up @@ -644,8 +644,8 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
return false;

est->size = sizeof(struct nft_hash) +
nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
desc->size * sizeof(struct nft_hash_elem);
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
(u64)desc->size * sizeof(struct nft_hash_elem);
est->lookup = NFT_SET_CLASS_O_1;
est->space = NFT_SET_CLASS_O_N;

Expand All @@ -662,8 +662,8 @@ static bool nft_hash_fast_estimate(const struct nft_set_desc *desc, u32 features
return false;

est->size = sizeof(struct nft_hash) +
nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
desc->size * sizeof(struct nft_hash_elem);
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
(u64)desc->size * sizeof(struct nft_hash_elem);
est->lookup = NFT_SET_CLASS_O_1;
est->space = NFT_SET_CLASS_O_N;

Expand Down

0 comments on commit 3fda454

Please sign in to comment.