mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
netfilter: nftables: avoid potential overflows on 32bit arches
commit6c8774a94eupstream. 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:0ed6389c48("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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cad6239f50
commit
3fda454f90
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user