Skip to content

Commit

Permalink
netfilter: nftables: avoid potential overflows on 32bit arches
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric Dumazet authored and ummakynes committed May 7, 2021
1 parent a54754e commit 6c8774a
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
Original file line number Diff line number Diff line change
Expand Up @@ -4184,6 +4184,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
unsigned char *udata;
struct nft_set *set;
struct nft_ctx ctx;
size_t alloc_size;
u64 timeout;
char *name;
int err, i;
Expand Down Expand Up @@ -4329,8 +4330,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
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
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,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 @@ -663,8 +663,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 @@ -681,8 +681,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 6c8774a

Please sign in to comment.