Skip to content

Commit 6c8774a

Browse files
edumazetummakynes
authored andcommitted
netfilter: nftables: avoid potential overflows on 32bit arches
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 <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent a54754e commit 6c8774a

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
41844184
unsigned char *udata;
41854185
struct nft_set *set;
41864186
struct nft_ctx ctx;
4187+
size_t alloc_size;
41874188
u64 timeout;
41884189
char *name;
41894190
int err, i;
@@ -4329,8 +4330,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
43294330
size = 0;
43304331
if (ops->privsize != NULL)
43314332
size = ops->privsize(nla, &desc);
4332-
4333-
set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
4333+
alloc_size = sizeof(*set) + size + udlen;
4334+
if (alloc_size < size)
4335+
return -ENOMEM;
4336+
set = kvzalloc(alloc_size, GFP_KERNEL);
43344337
if (!set)
43354338
return -ENOMEM;
43364339

net/netfilter/nft_set_hash.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ static u64 nft_hash_privsize(const struct nlattr * const nla[],
623623
const struct nft_set_desc *desc)
624624
{
625625
return sizeof(struct nft_hash) +
626-
nft_hash_buckets(desc->size) * sizeof(struct hlist_head);
626+
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head);
627627
}
628628

629629
static int nft_hash_init(const struct nft_set *set,
@@ -663,8 +663,8 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
663663
return false;
664664

665665
est->size = sizeof(struct nft_hash) +
666-
nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
667-
desc->size * sizeof(struct nft_hash_elem);
666+
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
667+
(u64)desc->size * sizeof(struct nft_hash_elem);
668668
est->lookup = NFT_SET_CLASS_O_1;
669669
est->space = NFT_SET_CLASS_O_N;
670670

@@ -681,8 +681,8 @@ static bool nft_hash_fast_estimate(const struct nft_set_desc *desc, u32 features
681681
return false;
682682

683683
est->size = sizeof(struct nft_hash) +
684-
nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
685-
desc->size * sizeof(struct nft_hash_elem);
684+
(u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) +
685+
(u64)desc->size * sizeof(struct nft_hash_elem);
686686
est->lookup = NFT_SET_CLASS_O_1;
687687
est->space = NFT_SET_CLASS_O_N;
688688

0 commit comments

Comments
 (0)