netfilter: x_tables: enforce unique and ascending entry points
Subsystems (4)
Pablo Neira Ayuso
maintainerPATCH 10/47 netfilter: x_tables: enforce unique and ascending entry points
From: Florian Westphal <[email protected]>
Harmless from kernel point of view, but iptables assumes that this is true when decoding a ruleset.
iptables walks the dumped blob from kernel, and, for each entry that creates a new chain it prints out rule/chain information. Base chains (hook entry points) are thus only shown when they appear in the rule blob. One base chain that is referenced multiple times in hook blob is then only printed once.
--- net/netfilter/x_tables.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
net/netfilter/x_tables.c +30 -1
@@ -529,10 +529,15 @@ static int xt_check_entry_match(const char *match, const char *target,*/ int xt_check_table_hooks (const struct xt_table_info *info,unsigned int valid_hooks) { -unsigned int i; +const char *err ="unsorted underflow" ; +unsigned int i, max_uflow, max_entry; +bool check_hooks = false;BUILD_BUG_ON (ARRAY_SIZE (info->hook_entry) !=ARRAY_SIZE (info->underflow)); + max_entry =0 ; + max_uflow =0 ; +for (i =0 ; i <ARRAY_SIZE (info->hook_entry); i++) {if (!(valid_hooks & (1 << i)))continue ;
@@ -541,9 +546,33 @@ int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_horeturn -EINVAL ;if (info->underflow[i] ==0xFFFFFFFF )return -EINVAL ; + +if (check_hooks) { +if (max_uflow > info->underflow[i]) + goto error; + +if (max_uflow == info->underflow[i]) { + err ="duplicate underflow" ; + goto error; + } +if (max_entry > info->hook_entry[i]) { + err ="unsorted entry" ; + goto error; + } +if (max_entry == info->hook_entry[i]) { + err ="duplicate entry" ; + goto error; + } + } + max_entry = info->hook_entry[i]; + max_uflow = info->underflow[i]; + check_hooks = true; }return 0 ; +error: +pr_err_ratelimited ("%s at hook %d\n" , err, i); +return -EINVAL ; }EXPORT_SYMBOL (xt_check_table_hooks);
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 11/47 netfilter: x_tables: cap allocations at 512 mbyte
From: Florian Westphal <[email protected]>
Arbitrary limit, however, this still allows huge rulesets (> 1 million rules). This helps with automated fuzzer as it prevents oom-killer invocation.
--- net/netfilter/x_tables.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/x_tables.c +2 -1
@@ -40,6 +40,7 @@ MODULE_AUTHOR("Harald Welte <[email protected]>");MODULE_DESCRIPTION ("{ip,ip6,arp,eb}_tables backend module" );#define XT_PCPU_BLOCK_SIZE 4096 +#define XT_MAX_TABLE_SIZE (512 * 1024 * 1024)struct compat_delta {unsigned int offset;/* offset in kernel */
@@ -1117,7 +1118,7 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)struct xt_table_info *info =NULL ;size_t sz =sizeof (*info) + size; -if (sz <sizeof (*info)) +if (sz <sizeof (*info) || sz >=XT_MAX_TABLE_SIZE )return NULL ;/* __GFP_NORETRY is not fully supported by kvmalloc but it should
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 12/47 netfilter: x_tables: limit allocation requests for blob rule heads
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
This is a very conservative limit (134217728 rules), but good enough to not trigger frequent oom from syzkaller.
--- net/netfilter/x_tables.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/x_tables.c +3 -0
@@ -894,6 +894,9 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { +if (size >XT_MAX_TABLE_SIZE /sizeof (unsigned int )) +return NULL ; +return kvmalloc_array (size,sizeof (unsigned int ),GFP_KERNEL | __GFP_ZERO); }
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 13/47 netfilter: x_tables: add counters allocation wrapper
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
allows to have size checks in a single spot.
This is supposed to reduce oom situations when fuzz-testing xtables.
--- include/linux/netfilter/x_tables.h | 1 + net/ipv4/netfilter/arp_tables.c | 2 +- net/ipv4/netfilter/ip_tables.c | 2 +- net/ipv6/netfilter/ip6_tables.c | 2 +- net/netfilter/x_tables.c | 15 +++++++++++++++ 5 files changed, 19 insertions(+), 3 deletions(-)
include/linux/netfilter/x_tables.h +1 -0
@@ -301,6 +301,7 @@ int xt_data_to_user(void __user *dst, const void *src,void *xt_copy_counters_from_user (const void __user *user,unsigned int len,struct xt_counters_info *info,bool compat); +struct xt_counters *xt_counters_alloc (unsigned int counters); struct xt_table *xt_register_table(struct net *net, const struct xt_table *table,
net/ipv4/netfilter/arp_tables.c +1 -1
@@ -883,7 +883,7 @@ static int __do_replace(struct net *net, const char *name,struct arpt_entry *iter; ret =0 ; - counters =vzalloc (num_counters *sizeof (struct xt_counters )); + counters =xt_counters_alloc (num_counters);if (!counters) { ret = -ENOMEM ; goto out;
net/ipv4/netfilter/ip_tables.c +1 -1
@@ -1045,7 +1045,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,struct ipt_entry *iter; ret =0 ; - counters =vzalloc (num_counters *sizeof (struct xt_counters )); + counters =xt_counters_alloc (num_counters);if (!counters) { ret = -ENOMEM ; goto out;
net/ipv6/netfilter/ip6_tables.c +1 -1
@@ -1063,7 +1063,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,struct ip6t_entry *iter; ret =0 ; - counters =vzalloc (num_counters *sizeof (struct xt_counters )); + counters =xt_counters_alloc (num_counters);if (!counters) { ret = -ENOMEM ; goto out;
net/netfilter/x_tables.c +15 -0
@@ -1290,6 +1290,21 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)return 0 ; } +struct xt_counters *xt_counters_alloc (unsigned int counters) +{ +struct xt_counters *mem; + +if (counters ==0 || counters >INT_MAX /sizeof (*mem)) +return NULL ; + + counters *=sizeof (*mem); +if (counters >XT_MAX_TABLE_SIZE ) +return NULL ; + +return vzalloc (counters); +} +EXPORT_SYMBOL (xt_counters_alloc); +struct xt_table_info * xt_replace_table(struct xt_table *table, unsigned int num_counters,
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 14/47 netfilter: compat: prepare xt_compat_init_offsets to return errors
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
should have no impact, function still always returns 0. This patch is only to ease review.
--- include/linux/netfilter/x_tables.h | 2 +- net/bridge/netfilter/ebtables.c | 10 ++++++++-- net/ipv4/netfilter/arp_tables.c | 10 +++++++--- net/ipv4/netfilter/ip_tables.c | 8 ++++++-- net/ipv6/netfilter/ip6_tables.c | 10 +++++++--- net/netfilter/x_tables.c | 4 +++- 6 files changed, 32 insertions(+), 12 deletions(-)
include/linux/netfilter/x_tables.h +1 -1
@@ -510,7 +510,7 @@ void xt_compat_unlock(u_int8_t af);int xt_compat_add_offset (u_int8_t af,unsigned int offset,int delta);void xt_compat_flush_offsets (u_int8_t af); -void xt_compat_init_offsets (u_int8_t af,unsigned int number); +int xt_compat_init_offsets (u8 af,unsigned int number);int xt_compat_calc_jump (u_int8_t af,unsigned int offset);int xt_compat_match_offset (const struct xt_match *match);
net/bridge/netfilter/ebtables.c +8 -2
@@ -1819,10 +1819,14 @@ static int compat_table_info(const struct ebt_table_info *info, {unsigned int size = info->entries_size;const void *entries = info->entries; +int ret; newinfo->entries_size = size; -xt_compat_init_offsets (NFPROTO_BRIDGE , info->nentries); + ret =xt_compat_init_offsets (NFPROTO_BRIDGE , info->nentries); +if (ret) +return ret; +return EBT_ENTRY_ITERATE (entries, size, compat_calc_entry, info, entries, newinfo); }
@@ -2245,7 +2249,9 @@ static int compat_do_replace(struct net *net, void __user *user,xt_compat_lock (NFPROTO_BRIDGE ); -xt_compat_init_offsets (NFPROTO_BRIDGE , tmp.nentries); + ret =xt_compat_init_offsets (NFPROTO_BRIDGE , tmp.nentries); +if (ret <0 ) + goto out_unlock; ret =compat_copy_entries (entries_tmp, tmp.entries_size, &state);if (ret <0 ) goto out_unlock;
net/ipv4/netfilter/arp_tables.c +7 -3
@@ -769,7 +769,9 @@ static int compat_table_info(const struct xt_table_info *info,memcpy (newinfo, info, offsetof(struct xt_table_info , entries)); newinfo->initial_entries =0 ; loc_cpu_entry = info->entries; -xt_compat_init_offsets (NFPROTO_ARP , info->number); + ret =xt_compat_init_offsets (NFPROTO_ARP , info->number); +if (ret) +return ret; xt_entry_foreach(iter, loc_cpu_entry, info->size) { ret =compat_calc_entry (iter, info, loc_cpu_entry, newinfo);if (ret !=0 )
@@ -1156,7 +1158,7 @@ static int translate_compat_table(struct xt_table_info **pinfo,struct compat_arpt_entry *iter0;struct arpt_replace repl;unsigned int size; -int ret =0 ; +int ret; info = *pinfo; entry0 = *pentry0;
@@ -1165,7 +1167,9 @@ static int translate_compat_table(struct xt_table_info **pinfo, j =0 ;xt_compat_lock (NFPROTO_ARP ); -xt_compat_init_offsets (NFPROTO_ARP , compatr->num_entries); + ret =xt_compat_init_offsets (NFPROTO_ARP , compatr->num_entries); +if (ret) + goto out_unlock;/* Walk through entries, checking offsets. */ xt_entry_foreach(iter0, entry0, compatr->size) { ret = check_compat_entry_size_and_hooks(iter0, info, &size,
net/ipv4/netfilter/ip_tables.c +6 -2
@@ -933,7 +933,9 @@ static int compat_table_info(const struct xt_table_info *info,memcpy (newinfo, info, offsetof(struct xt_table_info , entries)); newinfo->initial_entries =0 ; loc_cpu_entry = info->entries; -xt_compat_init_offsets (AF_INET , info->number); + ret =xt_compat_init_offsets (AF_INET , info->number); +if (ret) +return ret; xt_entry_foreach(iter, loc_cpu_entry, info->size) { ret =compat_calc_entry (iter, info, loc_cpu_entry, newinfo);if (ret !=0 )
@@ -1407,7 +1409,9 @@ translate_compat_table(struct net *net, j =0 ;xt_compat_lock (AF_INET ); -xt_compat_init_offsets (AF_INET , compatr->num_entries); + ret =xt_compat_init_offsets (AF_INET , compatr->num_entries); +if (ret) + goto out_unlock;/* Walk through entries, checking offsets. */ xt_entry_foreach(iter0, entry0, compatr->size) { ret = check_compat_entry_size_and_hooks(iter0, info, &size,
net/ipv6/netfilter/ip6_tables.c +7 -3
@@ -950,7 +950,9 @@ static int compat_table_info(const struct xt_table_info *info,memcpy (newinfo, info, offsetof(struct xt_table_info , entries)); newinfo->initial_entries =0 ; loc_cpu_entry = info->entries; -xt_compat_init_offsets (AF_INET6 , info->number); + ret =xt_compat_init_offsets (AF_INET6 , info->number); +if (ret) +return ret; xt_entry_foreach(iter, loc_cpu_entry, info->size) { ret =compat_calc_entry (iter, info, loc_cpu_entry, newinfo);if (ret !=0 )
@@ -1414,7 +1416,7 @@ translate_compat_table(struct net *net,struct compat_ip6t_entry *iter0;struct ip6t_replace repl;unsigned int size; -int ret =0 ; +int ret; info = *pinfo; entry0 = *pentry0;
@@ -1423,7 +1425,9 @@ translate_compat_table(struct net *net, j =0 ;xt_compat_lock (AF_INET6 ); -xt_compat_init_offsets (AF_INET6 , compatr->num_entries); + ret =xt_compat_init_offsets (AF_INET6 , compatr->num_entries); +if (ret) + goto out_unlock;/* Walk through entries, checking offsets. */ xt_entry_foreach(iter0, entry0, compatr->size) { ret = check_compat_entry_size_and_hooks(iter0, info, &size,
net/netfilter/x_tables.c +3 -1
@@ -632,10 +632,12 @@ int xt_compat_calc_jump(u_int8_t af, unsigned int offset) }EXPORT_SYMBOL_GPL (xt_compat_calc_jump); -void xt_compat_init_offsets (u_int8_t af,unsigned int number) +int xt_compat_init_offsets (u8 af,unsigned int number) { xt[af].number = number; xt[af].cur =0 ; + +return 0 ; }EXPORT_SYMBOL (xt_compat_init_offsets);
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 15/47 netfilter: compat: reject huge allocation requests
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
no need to bother even trying to allocating huge compat offset arrays, such ruleset is rejected later on anyway becaus we refuse to allocate overly large rule blobs.
However, compat translation happens before blob allocation, so we should add a check there too.
This is supposed to help with fuzzing by avoiding oom-killer.
--- net/netfilter/x_tables.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
net/netfilter/x_tables.c +18 -8
@@ -582,14 +582,8 @@ int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta) {struct xt_af *xp = &xt[af]; -if (!xp->compat_tab) { -if (!xp->number) -return -EINVAL ; - xp->compat_tab =vmalloc (sizeof (struct compat_delta ) * xp->number); -if (!xp->compat_tab) -return -ENOMEM ; - xp->cur =0 ; - } +if (WARN_ON (!xp->compat_tab)) +return -ENOMEM ;if (xp->cur >= xp->number)return -EINVAL ;
@@ -634,6 +628,22 @@ EXPORT_SYMBOL_GPL(xt_compat_calc_jump);int xt_compat_init_offsets (u8 af,unsigned int number) { +size_t mem; + +if (!number || number > (INT_MAX /sizeof (struct compat_delta ))) +return -EINVAL ; + +if (WARN_ON (xt[af].compat_tab)) +return -EINVAL ; + + mem =sizeof (struct compat_delta ) * number; +if (mem >XT_MAX_TABLE_SIZE ) +return -ENOMEM ; + + xt[af].compat_tab =vmalloc (mem); +if (!xt[af].compat_tab) +return -ENOMEM ; + xt[af].number = number; xt[af].cur =0 ;
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 16/47 netfilter: x_tables: make sure compat af mutex is held
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
--- net/netfilter/x_tables.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/netfilter/x_tables.c +6 -0
@@ -582,6 +582,8 @@ int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta) {struct xt_af *xp = &xt[af]; +WARN_ON (!mutex_is_locked (&xt[af].compat_mutex)); +if (WARN_ON (!xp->compat_tab))return -ENOMEM ;
@@ -599,6 +601,8 @@ EXPORT_SYMBOL_GPL(xt_compat_add_offset);void xt_compat_flush_offsets (u_int8_t af) { +WARN_ON (!mutex_is_locked (&xt[af].compat_mutex)); +if (xt[af].compat_tab) {vfree (xt[af].compat_tab); xt[af].compat_tab =NULL ;
@@ -630,6 +634,8 @@ int xt_compat_init_offsets(u8 af, unsigned int number) {size_t mem; +WARN_ON (!mutex_is_locked (&xt[af].compat_mutex)); +if (!number || number > (INT_MAX /sizeof (struct compat_delta )))return -EINVAL ;
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 17/47 netfilter: x_tables: ensure last rule in base chain matches underflow/policy
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
Harmless from kernel point of view, but again iptables assumes that this is true when decoding ruleset coming from kernel.
If a (syzkaller generated) ruleset doesn't have the underflow/policy stored as the last rule in the base chain, then iptables will abort() because it doesn't find the chain policy.
libiptc assumes that the policy is the last rule in the basechain, which is only true for iptables-generated rulesets.
Unfortunately this needs code duplication -- the functions need the struct layout of the rule head, but that is different for ip/ip6/arptables.
NB: pr_warn could be pr_debug but in case this break rulesets somehow its useful to know why blob was rejected.
--- net/ipv4/netfilter/arp_tables.c | 17 ++++++++++++++++- net/ipv4/netfilter/ip_tables.c | 17 ++++++++++++++++- net/ipv6/netfilter/ip6_tables.c | 17 ++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-)
net/ipv4/netfilter/arp_tables.c +16 -1
@@ -309,10 +309,13 @@ static int mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_ARP_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct arpt_entry *e = entry0 + pos; +unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; + depth =0 ; + last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -343,6 +346,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; +if (depth) + --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -367,6 +372,9 @@ static int mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; + +if (entry0 + newpos !=arpt_next_entry (e)) + ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -377,8 +385,15 @@ static int mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } +if (depth ==0 ) + last_pos = pos; + } +next: +if (last_pos != newinfo->underflow[hook]) { +pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , + last_pos, newinfo->underflow[hook], hook); +return 0 ; } -next: ; }return 1 ; }
net/ipv4/netfilter/ip_tables.c +16 -1
@@ -378,10 +378,13 @@ mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_INET_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct ipt_entry *e = entry0 + pos; +unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; + depth =0 ; + last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -410,6 +413,8 @@ mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; +if (depth) + --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -434,6 +439,9 @@ mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; + +if (entry0 + newpos !=ipt_next_entry (e)) + ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -444,8 +452,15 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } +if (depth ==0 ) + last_pos = pos; + } +next: +if (last_pos != newinfo->underflow[hook]) { +pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , + last_pos, newinfo->underflow[hook], hook); +return 0 ; } -next: ; }return 1 ; }
net/ipv6/netfilter/ip6_tables.c +16 -1
@@ -396,10 +396,13 @@ mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_INET_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct ip6t_entry *e = entry0 + pos; +unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; + depth =0 ; + last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -428,6 +431,8 @@ mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; +if (depth) + --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -452,6 +457,9 @@ mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; + +if (entry0 + newpos !=ip6t_next_entry (e)) + ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -462,8 +470,15 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } +if (depth ==0 ) + last_pos = pos; + } +next: +if (last_pos != newinfo->underflow[hook]) { +pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , + last_pos, newinfo->underflow[hook], hook); +return 0 ; } -next: ; }return 1 ; }
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 18/47 netfilter: make xt_rateest hash table per net
In reply to Pablo Neira AyusoFrom: Cong Wang <[email protected]>
As suggested by Eric, we need to make the xt_rateest hash table and its lock per netns to reduce lock contentions.
--- include/net/netfilter/xt_rateest.h | 4 +- net/netfilter/xt_RATEEST.c | 91 +++++++++++++++++++++++++++----------- net/netfilter/xt_rateest.c | 10 ++--- 3 files changed, 72 insertions(+), 33 deletions(-)
include/net/netfilter/xt_rateest.h +2 -2
@@ -21,7 +21,7 @@ struct xt_rateest { struct net_rate_estimator __rcu *rate_est; }; -struct xt_rateest *xt_rateest_lookup (const char *name); -void xt_rateest_put (struct xt_rateest *est); +struct xt_rateest *xt_rateest_lookup (struct net *net,const char *name); +void xt_rateest_put (struct net *net,struct xt_rateest *est);#endif /* _XT_RATEEST_H */
net/netfilter/xt_RATEEST.c +65 -26
191 lines not on this page · raw message
net/netfilter/xt_rateest.c +5 -5
@@ -95,13 +95,13 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) } ret = -ENOENT ; - est1 =xt_rateest_lookup (info->name1); + est1 =xt_rateest_lookup (par->net, info->name1);if (!est1) goto err1; est2 =NULL ;if (info->flags &XT_RATEEST_MATCH_REL ) { - est2 =xt_rateest_lookup (info->name2); + est2 =xt_rateest_lookup (par->net, info->name2);if (!est2) goto err2; }
@@ -111,7 +111,7 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)return 0 ; err2: -xt_rateest_put (est1); +xt_rateest_put (par->net, est1); err1:return ret; }
@@ -120,9 +120,9 @@ static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par) {struct xt_rateest_match_info *info = par->matchinfo; -xt_rateest_put (info->est1); +xt_rateest_put (par->net, info->est1);if (info->est2) -xt_rateest_put (info->est2); +xt_rateest_put (par->net, info->est2); }static struct xt_match xt_rateest_mt_reg__read_mostly = {
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 19/47 netfilter: xt_limit: Spelling s/maxmum/maximum/
In reply to Pablo Neira AyusoFrom: Geert Uytterhoeven <[email protected]>
--- net/netfilter/xt_limit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/xt_limit.c +1 -1
@@ -46,7 +46,7 @@ MODULE_ALIAS("ip6t_limit");See Alexey's formal explanation in net/sched/sch_tbf.c. -To get the maxmum range, we multiply by this factor (ie. you get N +To get the maximum range, we multiply by this factor (ie. you get N credits per jiffy). We want to allow a rate as low as 1 per day (slowest userspace tool allows), which means CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */
Signature · 1 line
2.11.0