summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-02-27 19:42:35 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-26 11:02:21 +0200
commit764f2162d97a498269c9b67607fe163692a79aa7 (patch)
tree95ebfe25a9b8e93883e2e343a615d26204780401
parent8d92d53365395c97cf819a10cda4693f792cd5b6 (diff)
downloadlinux-stable-764f2162d97a498269c9b67607fe163692a79aa7.tar.gz
linux-stable-764f2162d97a498269c9b67607fe163692a79aa7.tar.bz2
linux-stable-764f2162d97a498269c9b67607fe163692a79aa7.zip
netfilter: compat: reject huge allocation requests
commit 7d7d7e02111e9a4dc9d0658597f528f815d820fd upstream. no need to bother even trying to allocating huge compat offset arrays, such ruleset is rejected later on anyway becaus we refuse to allocate overly large rule blobs. However, compat translation happens before blob allocation, so we should add a check there too. This is supposed to help with fuzzing by avoiding oom-killer. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/netfilter/x_tables.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 7ad3d861cb83..926e7d76ac2e 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -555,14 +555,8 @@ int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
{
struct xt_af *xp = &xt[af];
- if (!xp->compat_tab) {
- if (!xp->number)
- return -EINVAL;
- xp->compat_tab = vmalloc(sizeof(struct compat_delta) * xp->number);
- if (!xp->compat_tab)
- return -ENOMEM;
- xp->cur = 0;
- }
+ if (WARN_ON(!xp->compat_tab))
+ return -ENOMEM;
if (xp->cur >= xp->number)
return -EINVAL;
@@ -607,6 +601,22 @@ EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
int xt_compat_init_offsets(u8 af, unsigned int number)
{
+ size_t mem;
+
+ if (!number || number > (INT_MAX / sizeof(struct compat_delta)))
+ return -EINVAL;
+
+ if (WARN_ON(xt[af].compat_tab))
+ return -EINVAL;
+
+ mem = sizeof(struct compat_delta) * number;
+ if (mem > XT_MAX_TABLE_SIZE)
+ return -ENOMEM;
+
+ xt[af].compat_tab = vmalloc(mem);
+ if (!xt[af].compat_tab)
+ return -ENOMEM;
+
xt[af].number = number;
xt[af].cur = 0;