[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200131205216.22213-4-xiyou.wangcong@gmail.com>
Date: Fri, 31 Jan 2020 12:52:16 -0800
From: Cong Wang <xiyou.wangcong@...il.com>
To: netdev@...r.kernel.org
Cc: netfilter-devel@...r.kernel.org,
Cong Wang <xiyou.wangcong@...il.com>,
syzbot+adf6c6c2be1c3a718121@...kaller.appspotmail.com,
Pablo Neira Ayuso <pablo@...filter.org>,
Jozsef Kadlecsik <kadlec@...filter.org>,
Florian Westphal <fw@...len.de>
Subject: [Patch nf 3/3] xt_hashlimit: limit the max size of hashtable
The user-specified hashtable size is unbound, this could
easily lead to an OOM or a hung task as we hold the global
mutex while allocating and initializing the new hashtable.
The max value is derived from the max value when chosen by
the kernel.
Reported-and-tested-by: syzbot+adf6c6c2be1c3a718121@...kaller.appspotmail.com
Cc: Pablo Neira Ayuso <pablo@...filter.org>
Cc: Jozsef Kadlecsik <kadlec@...filter.org>
Cc: Florian Westphal <fw@...len.de>
Signed-off-by: Cong Wang <xiyou.wangcong@...il.com>
---
net/netfilter/xt_hashlimit.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 57a2639bcc22..6327134c5886 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -272,6 +272,8 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
}
static void htable_gc(struct work_struct *work);
+#define HASHLIMIT_MAX_SIZE 8192
+
static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
const char *name, u_int8_t family,
struct xt_hashlimit_htable **out_hinfo,
@@ -290,7 +292,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
size = (nr_pages << PAGE_SHIFT) / 16384 /
sizeof(struct hlist_head);
if (nr_pages > 1024 * 1024 * 1024 / PAGE_SIZE)
- size = 8192;
+ size = HASHLIMIT_MAX_SIZE;
if (size < 16)
size = 16;
}
@@ -848,6 +850,8 @@ static int hashlimit_mt_check_common(const struct xt_mtchk_param *par,
if (cfg->gc_interval == 0 || cfg->expire == 0)
return -EINVAL;
+ if (cfg->size > HASHLIMIT_MAX_SIZE)
+ return -ENOMEM;
if (par->family == NFPROTO_IPV4) {
if (cfg->srcmask > 32 || cfg->dstmask > 32)
return -EINVAL;
--
2.21.1
Powered by blists - more mailing lists