diff mbox

ipset: Adjust the maximum timeout jiffies of set timeout extension

Message ID 20141017033544.GA26660@nitrogen.neutroncom.local
State Changes Requested
Delegated to: Pablo Neira
Headers show

Commit Message

Neutron Soutmun Oct. 17, 2014, 3:35 a.m. UTC
Refer to: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=764328

Marek Lukács has reported that the set with huge default timeout,
2419200 as an example, is replaced by 4294967 which is non-sense.

The msecs_to_jiffies() in kernel/time/time.c has a condition that

500 unsigned long msecs_to_jiffies(const unsigned int m)
501 {
502         /*
503          * Negative value, means infinite timeout:
504          */
505         if ((int)m < 0)
506                 return MAX_JIFFY_OFFSET;

Therefore, the maximum timeout jiffies should be less than or equal to
((UINT_MAX >> 1)) / MSEC_PER_SEC.

Signed-off-by: Neutron Soutmun <neo.neutron@gmail.com>
---
 include/linux/netfilter/ipset/ip_set_timeout.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

Jozsef Kadlecsik Oct. 18, 2014, 8:36 a.m. UTC | #1
Hi,

On Fri, 17 Oct 2014, Neutron Soutmun wrote:

> Refer to: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=764328
> 
> Marek Lukács has reported that the set with huge default timeout,
> 2419200 as an example, is replaced by 4294967 which is non-sense.

There has just been a thread about it on this mailing list. I better 
create a workaround to remove the limitation at ipset level, to support 
huge timeout values.

Best regards,
Jozsef

> The msecs_to_jiffies() in kernel/time/time.c has a condition that
> 
> 500 unsigned long msecs_to_jiffies(const unsigned int m)
> 501 {
> 502         /*
> 503          * Negative value, means infinite timeout:
> 504          */
> 505         if ((int)m < 0)
> 506                 return MAX_JIFFY_OFFSET;
> 
> Therefore, the maximum timeout jiffies should be less than or equal to
> ((UINT_MAX >> 1)) / MSEC_PER_SEC.
> 
> Signed-off-by: Neutron Soutmun <neo.neutron@gmail.com>
> ---
>  include/linux/netfilter/ipset/ip_set_timeout.h | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h
> index 83c2f9e..b1798df 100644
> --- a/include/linux/netfilter/ipset/ip_set_timeout.h
> +++ b/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
>  
> +/* Set maximum jiffies offset, msecs_to_jiffies() condition */
> +#define IPSET_MAX_JIFFY_OFFSET  ((UINT_MAX >> 1))
> +
>  #define ip_set_adt_opt_timeout(opt, set)	\
>  ((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
>  
> @@ -32,8 +35,8 @@ 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 (msecs_to_jiffies(timeout * MSEC_PER_SEC) == MAX_JIFFY_OFFSET)
> +		timeout = IPSET_MAX_JIFFY_OFFSET / MSEC_PER_SEC;
>  
>  	/* Userspace supplied TIMEOUT parameter: adjust crazy size */
>  	return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
> -- 
> 2.1.1
> 
> 

-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary
diff mbox

Patch

diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h
index 83c2f9e..b1798df 100644
--- a/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/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
 
+/* Set maximum jiffies offset, msecs_to_jiffies() condition */
+#define IPSET_MAX_JIFFY_OFFSET  ((UINT_MAX >> 1))
+
 #define ip_set_adt_opt_timeout(opt, set)	\
 ((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
 
@@ -32,8 +35,8 @@  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 (msecs_to_jiffies(timeout * MSEC_PER_SEC) == MAX_JIFFY_OFFSET)
+		timeout = IPSET_MAX_JIFFY_OFFSET / MSEC_PER_SEC;
 
 	/* Userspace supplied TIMEOUT parameter: adjust crazy size */
 	return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;