From 7219d88329cabcdd05df9477af6e2dee007b60b1 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Fri, 4 May 2012 21:37:28 +0200 Subject: Fix timeout value overflow bug at large timeout parameters Large timeout parameters could result wrong timeout values due to an overflow at msec to jiffies conversion (reported by Andreas Herz) --- lib/ipset_bitmap_ip.c | 4 ++-- lib/ipset_bitmap_ipmac.c | 4 ++-- lib/ipset_bitmap_port.c | 4 ++-- lib/ipset_hash_ip.c | 4 ++-- lib/ipset_hash_ipport.c | 4 ++-- lib/ipset_hash_ipportip.c | 4 ++-- lib/ipset_hash_ipportnet.c | 6 +++--- lib/ipset_hash_net.c | 6 +++--- lib/ipset_hash_netiface.c | 6 +++--- lib/ipset_hash_netport.c | 6 +++--- lib/ipset_list_set.c | 4 ++-- lib/parse.c | 31 ++++++++++++++++++++++++++++++- 12 files changed, 56 insertions(+), 27 deletions(-) (limited to 'lib') diff --git a/lib/ipset_bitmap_ip.c b/lib/ipset_bitmap_ip.c index 8b8220d..9e97b67 100644 --- a/lib/ipset_bitmap_ip.c +++ b/lib/ipset_bitmap_ip.c @@ -21,7 +21,7 @@ static const struct ipset_arg bitmap_ip_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "from", NULL }, @@ -42,7 +42,7 @@ static const struct ipset_arg bitmap_ip_create_args[] = { static const struct ipset_arg bitmap_ip_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_bitmap_ipmac.c b/lib/ipset_bitmap_ipmac.c index d822bf6..2a58019 100644 --- a/lib/ipset_bitmap_ipmac.c +++ b/lib/ipset_bitmap_ipmac.c @@ -17,7 +17,7 @@ static const struct ipset_arg bitmap_ipmac_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "from", NULL }, @@ -38,7 +38,7 @@ static const struct ipset_arg bitmap_ipmac_create_args[] = { static const struct ipset_arg bitmap_ipmac_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_bitmap_port.c b/lib/ipset_bitmap_port.c index 69be809..3101b22 100644 --- a/lib/ipset_bitmap_port.c +++ b/lib/ipset_bitmap_port.c @@ -17,7 +17,7 @@ static const struct ipset_arg bitmap_port_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "from", NULL }, @@ -34,7 +34,7 @@ static const struct ipset_arg bitmap_port_create_args[] = { static const struct ipset_arg bitmap_port_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_hash_ip.c b/lib/ipset_hash_ip.c index 912b991..e885b13 100644 --- a/lib/ipset_hash_ip.c +++ b/lib/ipset_hash_ip.c @@ -39,7 +39,7 @@ static const struct ipset_arg hash_ip_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Ignored options: backward compatibilty */ { .name = { "probes", NULL }, @@ -60,7 +60,7 @@ static const struct ipset_arg hash_ip_create_args[] = { static const struct ipset_arg hash_ip_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c index 748e452..54664e1 100644 --- a/lib/ipset_hash_ipport.c +++ b/lib/ipset_hash_ipport.c @@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipport_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "probes", NULL }, @@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipport_create_args[] = { static const struct ipset_arg hash_ipport_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_hash_ipportip.c b/lib/ipset_hash_ipportip.c index 7c046a3..4599b01 100644 --- a/lib/ipset_hash_ipportip.c +++ b/lib/ipset_hash_ipportip.c @@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipportip_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "probes", NULL }, @@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipportip_create_args[] = { static const struct ipset_arg hash_ipportip_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; diff --git a/lib/ipset_hash_ipportnet.c b/lib/ipset_hash_ipportnet.c index 0813b7d..af85639 100644 --- a/lib/ipset_hash_ipportnet.c +++ b/lib/ipset_hash_ipportnet.c @@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipportnet_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Backward compatibility */ { .name = { "probes", NULL }, @@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipportnet_create_args[] = { static const struct ipset_arg hash_ipportnet_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -255,7 +255,7 @@ struct ipset_type ipset_hash_ipportnet2 = { static const struct ipset_arg hash_ipportnet3_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { .name = { "nomatch", NULL }, .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, diff --git a/lib/ipset_hash_net.c b/lib/ipset_hash_net.c index 0fd2608..5829f50 100644 --- a/lib/ipset_hash_net.c +++ b/lib/ipset_hash_net.c @@ -35,7 +35,7 @@ static const struct ipset_arg hash_net_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, /* Ignored options: backward compatibilty */ { .name = { "probes", NULL }, @@ -52,7 +52,7 @@ static const struct ipset_arg hash_net_create_args[] = { static const struct ipset_arg hash_net_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -165,7 +165,7 @@ struct ipset_type ipset_hash_net1 = { static const struct ipset_arg hash_net2_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { .name = { "nomatch", NULL }, .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, diff --git a/lib/ipset_hash_netiface.c b/lib/ipset_hash_netiface.c index 880ba7d..7fca5fe 100644 --- a/lib/ipset_hash_netiface.c +++ b/lib/ipset_hash_netiface.c @@ -36,7 +36,7 @@ static const struct ipset_arg hash_netiface_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -44,7 +44,7 @@ static const struct ipset_arg hash_netiface_create_args[] = { static const struct ipset_arg hash_netiface_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -121,7 +121,7 @@ struct ipset_type ipset_hash_netiface0 = { static const struct ipset_arg hash_netiface1_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { .name = { "nomatch", NULL }, .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, diff --git a/lib/ipset_hash_netport.c b/lib/ipset_hash_netport.c index b910c81..d8d220e 100644 --- a/lib/ipset_hash_netport.c +++ b/lib/ipset_hash_netport.c @@ -36,7 +36,7 @@ static const struct ipset_arg hash_netport_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -44,7 +44,7 @@ static const struct ipset_arg hash_netport_create_args[] = { static const struct ipset_arg hash_netport_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -201,7 +201,7 @@ struct ipset_type ipset_hash_netport2 = { static const struct ipset_arg hash_netport3_add_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { .name = { "nomatch", NULL }, .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, diff --git a/lib/ipset_list_set.c b/lib/ipset_list_set.c index d95290b..67c29b6 100644 --- a/lib/ipset_list_set.c +++ b/lib/ipset_list_set.c @@ -17,7 +17,7 @@ static const struct ipset_arg list_set_create_args[] = { }, { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { }, }; @@ -25,7 +25,7 @@ static const struct ipset_arg list_set_create_args[] = { static const struct ipset_arg list_set_adt_args[] = { { .name = { "timeout", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, + .parse = ipset_parse_timeout, .print = ipset_print_number, }, { .name = { "before", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NAMEREF, diff --git a/lib/parse.c b/lib/parse.c index 30efdb6..2cbd30e 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -1129,6 +1129,35 @@ ipset_parse_ip4_net6(struct ipset_session *session, } +/** + * ipset_parse_timeout - parse timeout parameter + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string as a timeout parameter. We have to take into account + * the jiffies storage in kernel. + * + * Returns 0 on success or a negative error code. + */ +int +ipset_parse_timeout(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + int err; + unsigned long long num = 0; + + assert(session); + assert(opt == IPSET_OPT_TIMEOUT); + assert(str); + + err = string_to_number_ll(session, str, 0, UINT_MAX/1000, &num); + if (err == 0) + return ipset_session_data_set(session, opt, &num); + + return err; +} + /** * ipset_parse_iptimeout - parse IPv4|IPv6 address and timeout * @session: session structure @@ -1171,7 +1200,7 @@ ipset_parse_iptimeout(struct ipset_session *session, *a++ = '\0'; err = parse_ip(session, opt, tmp, IPADDR_ANY); if (!err) - err = ipset_parse_uint32(session, IPSET_OPT_TIMEOUT, a); + err = ipset_parse_timeout(session, IPSET_OPT_TIMEOUT, a); free(saved); return err; -- cgit v1.2.3