aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fwestphal@astaro.com>2010-02-15 12:17:10 -0500
committerPatrick McHardy <kaber@trash.net>2010-02-15 12:17:10 -0500
commit3e5e524ffb5fcf2447eb5dd9f8e54ad22dd9baa7 (patch)
treea78b8d92a63dd217e114a02e1ff0902e5e23cc41
parentfc0e3df4f00a5f62c2f2fce84bf496136b58c474 (diff)
netfilter: CONFIG_COMPAT: allow delta to exceed 32767
with 32 bit userland and 64 bit kernels, it is unlikely but possible that insertion of new rules fails even tough there are only about 2000 iptables rules. This happens because the compat delta is using a short int. Easily reproducible via "iptables -m limit" ; after about 2050 rules inserting new ones fails with -ELOOP. Note that compat_delta included 2 bytes of padding on x86_64, so structure size remains the same. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/linux/netfilter/x_tables.h2
-rw-r--r--net/netfilter/x_tables.c6
2 files changed, 4 insertions, 4 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index c61758f4be31..a18119fb88f0 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -588,7 +588,7 @@ extern void xt_compat_unlock(u_int8_t af);
588 588
589extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta); 589extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta);
590extern void xt_compat_flush_offsets(u_int8_t af); 590extern void xt_compat_flush_offsets(u_int8_t af);
591extern short xt_compat_calc_jump(u_int8_t af, unsigned int offset); 591extern int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
592 592
593extern int xt_compat_match_offset(const struct xt_match *match); 593extern int xt_compat_match_offset(const struct xt_match *match);
594extern int xt_compat_match_from_user(struct xt_entry_match *m, 594extern int xt_compat_match_from_user(struct xt_entry_match *m,
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 69c56287d518..0a12cedfe9e3 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -39,7 +39,7 @@ MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
39struct compat_delta { 39struct compat_delta {
40 struct compat_delta *next; 40 struct compat_delta *next;
41 unsigned int offset; 41 unsigned int offset;
42 short delta; 42 int delta;
43}; 43};
44 44
45struct xt_af { 45struct xt_af {
@@ -439,10 +439,10 @@ void xt_compat_flush_offsets(u_int8_t af)
439} 439}
440EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); 440EXPORT_SYMBOL_GPL(xt_compat_flush_offsets);
441 441
442short xt_compat_calc_jump(u_int8_t af, unsigned int offset) 442int xt_compat_calc_jump(u_int8_t af, unsigned int offset)
443{ 443{
444 struct compat_delta *tmp; 444 struct compat_delta *tmp;
445 short delta; 445 int delta;
446 446
447 for (tmp = xt[af].compat_offsets, delta = 0; tmp; tmp = tmp->next) 447 for (tmp = xt[af].compat_offsets, delta = 0; tmp; tmp = tmp->next)
448 if (tmp->offset < offset) 448 if (tmp->offset < offset)