Patchwork [7/7] libxt_*limit: avoid division by zero

login
register
mail settings
Submitter Jan Engelhardt
Date July 28, 2012, 5:21 p.m.
Message ID <1343496069-5442-8-git-send-email-jengelh@inai.de>
Download mbox | patch
Permalink /patch/173880/
State Accepted
Headers show

Comments

Jan Engelhardt - July 28, 2012, 5:21 p.m.
It was possible to specify -A mychain -m hashlimit --hashlimit
600059/minute; this would convert to r->avg=0, which subsequently
causes a division by zero when printing with -S mychain.

1. Avoid division by zero in print_rate by printing infinity
   instead.
2. Rewrite the test in parse_rate to properly reject too high rates.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 extensions/libxt_hashlimit.c |   17 ++++++++++++-----
 extensions/libxt_limit.c     |   17 ++++++++++++-----
 2 files changed, 24 insertions(+), 10 deletions(-)

Patch

diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c
index 37a3148..831345b 100644
--- a/extensions/libxt_hashlimit.c
+++ b/extensions/libxt_hashlimit.c
@@ -10,6 +10,7 @@ 
  * 
  * Error corections by nmalykh@bilim.com (22.01.2005)
  */
+#include <math.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -250,12 +251,13 @@  int parse_rate(const char *rate, uint32_t *val, struct hashlimit_mt_udata *ud)
 	if (!r)
 		return 0;
 
-	/* This would get mapped to infinite (1/day is minimum they
-           can specify, so we're ok at that end). */
-	if (r / ud->mult > XT_HASHLIMIT_SCALE)
-		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
-
 	*val = XT_HASHLIMIT_SCALE * ud->mult / r;
+	if (*val == 0)
+		/*
+		 * The rate maps to infinity. (1/day is the minimum they can
+		 * specify, so we are ok at that end).
+		 */
+		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
 	return 1;
 }
 
@@ -434,6 +436,11 @@  static uint32_t print_rate(uint32_t period)
 {
 	unsigned int i;
 
+	if (period == 0) {
+		printf(" %f", INFINITY);
+		return 0;
+	}
+
 	for (i = 1; i < ARRAY_SIZE(rates); ++i)
 		if (period > rates[i].mult
             || rates[i].mult/period < rates[i].mult%period)
diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c
index b15b02f..023500c 100644
--- a/extensions/libxt_limit.c
+++ b/extensions/libxt_limit.c
@@ -3,6 +3,7 @@ 
  * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
  * Hervé Eychenne    <rv@wallfire.org>
  */
+#include <math.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -64,12 +65,13 @@  int parse_rate(const char *rate, uint32_t *val)
 	if (!r)
 		return 0;
 
-	/* This would get mapped to infinite (1/day is minimum they
-           can specify, so we're ok at that end). */
-	if (r / mult > XT_LIMIT_SCALE)
-		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
-
 	*val = XT_LIMIT_SCALE * mult / r;
+	if (*val == 0)
+		/*
+		 * The rate maps to infinity. (1/day is the minimum they can
+		 * specify, so we are ok at that end).
+		 */
+		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
 	return 1;
 }
 
@@ -118,6 +120,11 @@  static void print_rate(uint32_t period)
 {
 	unsigned int i;
 
+	if (period == 0) {
+		printf(" %f", INFINITY);
+		return;
+	}
+
 	for (i = 1; i < ARRAY_SIZE(rates); ++i)
 		if (period > rates[i].mult
             || rates[i].mult/period < rates[i].mult%period)