summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2018-06-01 20:59:14 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2018-06-01 20:59:14 +0200
commitcef553009b5181ae3c9f465c0e300ec8c8b37fbd (patch)
treed29251244ca4ff0d8a737c474971c90e87c3e2a8
parent8b140bd12daffd6b3c6e50af9c55f8a601900664 (diff)
Limit max timeout value to (UINT_MAX >> 1)/MSEC_PER_SEC
Due to the negative value condition in msecs_to_jiffies(), the real max possible timeout value must be set to (UINT_MAX >> 1)/MSEC_PER_SEC. Neutron Soutmun proposed the proper fix, but an insufficient one was applied, see https://patchwork.ozlabs.org/patch/400405/.
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_timeout.h10
-rw-r--r--kernel/net/netfilter/xt_set.c8
-rw-r--r--lib/parse.c2
-rw-r--r--src/ipset.83
4 files changed, 13 insertions, 10 deletions
diff --git a/kernel/include/linux/netfilter/ipset/ip_set_timeout.h b/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
index 7ad8ddf..8ce271e 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -23,6 +23,9 @@
/* Set is defined with timeout support: timeout value may be 0 */
#define IPSET_NO_TIMEOUT UINT_MAX
+/* Max timeout value, see msecs_to_jiffies() in jiffies.h */
+#define IPSET_MAX_TIMEOUT (UINT_MAX >> 1)/MSEC_PER_SEC
+
#define ip_set_adt_opt_timeout(opt, set) \
((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
@@ -32,11 +35,10 @@ ip_set_timeout_uget(struct nlattr *tb)
unsigned int timeout = ip_set_get_h32(tb);
/* Normalize to fit into jiffies */
- if (timeout > UINT_MAX/MSEC_PER_SEC)
- timeout = UINT_MAX/MSEC_PER_SEC;
+ if (timeout > IPSET_MAX_TIMEOUT)
+ timeout = IPSET_MAX_TIMEOUT;
- /* Userspace supplied TIMEOUT parameter: adjust crazy size */
- return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
+ return timeout;
}
static inline bool
diff --git a/kernel/net/netfilter/xt_set.c b/kernel/net/netfilter/xt_set.c
index f10c6de..43e54ef 100644
--- a/kernel/net/netfilter/xt_set.c
+++ b/kernel/net/netfilter/xt_set.c
@@ -407,8 +407,8 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
/* Normalize to fit into jiffies */
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
- add_opt.ext.timeout > UINT_MAX / MSEC_PER_SEC)
- add_opt.ext.timeout = UINT_MAX / MSEC_PER_SEC;
+ add_opt.ext.timeout > IPSET_MAX_TIMEOUT)
+ add_opt.ext.timeout = IPSET_MAX_TIMEOUT;
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_add(info->add_set.index, skb, CAST_TO_MATCH par,
&add_opt);
@@ -444,8 +444,8 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
/* Normalize to fit into jiffies */
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
- add_opt.ext.timeout > UINT_MAX / MSEC_PER_SEC)
- add_opt.ext.timeout = UINT_MAX / MSEC_PER_SEC;
+ add_opt.ext.timeout > IPSET_MAX_TIMEOUT)
+ add_opt.ext.timeout = IPSET_MAX_TIMEOUT;
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_add(info->add_set.index, skb, CAST_TO_MATCH par,
&add_opt);
diff --git a/lib/parse.c b/lib/parse.c
index 7cd6436..9a79ccd 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -1334,7 +1334,7 @@ ipset_parse_timeout(struct ipset_session *session,
assert(opt == IPSET_OPT_TIMEOUT);
assert(str);
- err = string_to_number_ll(session, str, 0, UINT_MAX/1000, &llnum);
+ err = string_to_number_ll(session, str, 0, (UINT_MAX>>1)/1000, &llnum);
if (err == 0) {
/* Timeout is expected to be 32bits wide, so we have
to convert it here */
diff --git a/src/ipset.8 b/src/ipset.8
index cd8c3ad..87fb938 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -271,7 +271,8 @@ for new entries. If a set is created with timeout support, then the same
\fBtimeout\fR option can be used to specify non\-default timeout values
when adding entries. Zero timeout value means the entry is added permanent to the set.
The timeout value of already added elements can be changed by re-adding the element
-using the \fB\-exist\fR option. Example:
+using the \fB\-exist\fR option. The largest possible timeout value is 2147483
+(in seconds). Example:
.IP
ipset create test hash:ip timeout 300
.IP