aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorVishwanath Pai <vpai@akamai.com>2017-09-08 01:38:58 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2017-09-08 12:55:53 -0400
commit90c4ae4e2c1da9f1eaf846136861af43d4c1ff34 (patch)
tree3d78647f4cf96a1ef30a8169d461cf0a46a86899 /net
parent05d0eae7c1cf6bf7b19c02b3a97ff457b3317323 (diff)
netfilter: xt_hashlimit: fix build error caused by 64bit division
64bit division causes build/link errors on 32bit architectures. It prints out error messages like: ERROR: "__aeabi_uldivmod" [net/netfilter/xt_hashlimit.ko] undefined! The value of avg passed through by userspace in BYTE mode cannot exceed U32_MAX. Which means 64bit division in user2rate_bytes is unnecessary. To fix this I have changed the type of param 'user' to u32. Since anything greater than U32_MAX is an invalid input we error out in hashlimit_mt_check_common() when this is the case. Changes in v2: Making return type as u32 would cause an overflow for small values of 'user' (for example 2, 3 etc). To avoid this I bumped up 'r' to u64 again as well as the return type. This is OK since the variable that stores the result is u64. We still avoid 64bit division here since 'user' is u32. Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode") Signed-off-by: Vishwanath Pai <vpai@akamai.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_hashlimit.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 962ea4a63d9f..5da8746f7b88 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -35,6 +35,7 @@
35#include <linux/netfilter_ipv6/ip6_tables.h> 35#include <linux/netfilter_ipv6/ip6_tables.h>
36#include <linux/netfilter/xt_hashlimit.h> 36#include <linux/netfilter/xt_hashlimit.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38#include <linux/kernel.h>
38 39
39MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
40MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 41MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
@@ -527,12 +528,12 @@ static u64 user2rate(u64 user)
527 } 528 }
528} 529}
529 530
530static u64 user2rate_bytes(u64 user) 531static u64 user2rate_bytes(u32 user)
531{ 532{
532 u64 r; 533 u64 r;
533 534
534 r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL; 535 r = user ? U32_MAX / user : U32_MAX;
535 r = (r - 1) << 4; 536 r = (r - 1) << XT_HASHLIMIT_BYTE_SHIFT;
536 return r; 537 return r;
537} 538}
538 539
@@ -588,7 +589,8 @@ static void rateinfo_init(struct dsthash_ent *dh,
588 dh->rateinfo.prev_window = 0; 589 dh->rateinfo.prev_window = 0;
589 dh->rateinfo.current_rate = 0; 590 dh->rateinfo.current_rate = 0;
590 if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { 591 if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) {
591 dh->rateinfo.rate = user2rate_bytes(hinfo->cfg.avg); 592 dh->rateinfo.rate =
593 user2rate_bytes((u32)hinfo->cfg.avg);
592 if (hinfo->cfg.burst) 594 if (hinfo->cfg.burst)
593 dh->rateinfo.burst = 595 dh->rateinfo.burst =
594 hinfo->cfg.burst * dh->rateinfo.rate; 596 hinfo->cfg.burst * dh->rateinfo.rate;
@@ -870,7 +872,7 @@ static int hashlimit_mt_check_common(const struct xt_mtchk_param *par,
870 872
871 /* Check for overflow. */ 873 /* Check for overflow. */
872 if (revision >= 3 && cfg->mode & XT_HASHLIMIT_RATE_MATCH) { 874 if (revision >= 3 && cfg->mode & XT_HASHLIMIT_RATE_MATCH) {
873 if (cfg->avg == 0) { 875 if (cfg->avg == 0 || cfg->avg > U32_MAX) {
874 pr_info("hashlimit invalid rate\n"); 876 pr_info("hashlimit invalid rate\n");
875 return -ERANGE; 877 return -ERANGE;
876 } 878 }