diff options
author | David S. Miller <davem@davemloft.net> | 2016-07-25 01:02:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-25 01:02:36 -0400 |
commit | c42d7121fbee1ee30fd9221d594e9c5a4bc1fed6 (patch) | |
tree | 37ccf6ebfc28dc4aad92e9d3831d8825eafb7a5a /net/ipv6 | |
parent | de0ba9a0d8909996f9e293d311c2cc459fa77d67 (diff) | |
parent | 4b512e1c1f8de6b9ceb796ecef8658e0a083cab7 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says:
====================
Netfilter/IPVS updates for net-next
The following patchset contains Netfilter/IPVS updates for net-next,
they are:
1) Count pre-established connections as active in "least connection"
schedulers such that pre-established connections to avoid overloading
backend servers on peak demands, from Michal Kubecek via Simon Horman.
2) Address a race condition when resizing the conntrack table by caching
the bucket size when fulling iterating over the hashtable in these
three possible scenarios: 1) dump via /proc/net/nf_conntrack,
2) unlinking userspace helper and 3) unlinking custom conntrack timeout.
From Liping Zhang.
3) Revisit early_drop() path to perform lockless traversal on conntrack
eviction under stress, use del_timer() as synchronization point to
avoid two CPUs evicting the same entry, from Florian Westphal.
4) Move NAT hlist_head to nf_conn object, this simplifies the existing
NAT extension and it doesn't increase size since recent patches to
align nf_conn, from Florian.
5) Use rhashtable for the by-source NAT hashtable, also from Florian.
6) Don't allow --physdev-is-out from OUTPUT chain, just like
--physdev-out is not either, from Hangbin Liu.
7) Automagically set on nf_conntrack counters if the user tries to
match ct bytes/packets from nftables, from Liping Zhang.
8) Remove possible_net_t fields in nf_tables set objects since we just
simply pass the net pointer to the backend set type implementations.
9) Fix possible off-by-one in h323, from Toby DiPasquale.
10) early_drop() may be called from ctnetlink patch, so we must hold
rcu read size lock from them too, this amends Florian's patch #3
coming in this batch, from Liping Zhang.
11) Use binary search to validate jump offset in x_tables, this
addresses the O(n!) validation that was introduced recently
resolve security issues with unpriviledge namespaces, from Florian.
12) Fix reference leak to connlabel in error path of nft_ct, from Zhang.
13) Three updates for nft_log: Fix log prefix leak in error path. Bail
out on loglevel larger than debug in nft_log and set on the new
NF_LOG_F_COPY_LEN flag when snaplen is specified. Again from Zhang.
14) Allow to filter rule dumps in nf_tables based on table and chain
names.
15) Simplify connlabel to always use 128 bits to store labels and
get rid of unused function in xt_connlabel, from Florian.
16) Replace set_expect_timeout() by mod_timer() from the h323 conntrack
helper, by Gao Feng.
17) Put back x_tables module reference in nft_compat on error, from
Liping Zhang.
18) Add a reference count to the x_tables extensions cache in
nft_compat, so we can remove them when unused and avoid a crash
if the extensions are rmmod, again from Zhang.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 61ed95054efa..552fac2f390a 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -402,23 +402,12 @@ ip6t_do_table(struct sk_buff *skb, | |||
402 | else return verdict; | 402 | else return verdict; |
403 | } | 403 | } |
404 | 404 | ||
405 | static bool find_jump_target(const struct xt_table_info *t, | ||
406 | const struct ip6t_entry *target) | ||
407 | { | ||
408 | struct ip6t_entry *iter; | ||
409 | |||
410 | xt_entry_foreach(iter, t->entries, t->size) { | ||
411 | if (iter == target) | ||
412 | return true; | ||
413 | } | ||
414 | return false; | ||
415 | } | ||
416 | |||
417 | /* Figures out from what hook each rule can be called: returns 0 if | 405 | /* Figures out from what hook each rule can be called: returns 0 if |
418 | there are loops. Puts hook bitmask in comefrom. */ | 406 | there are loops. Puts hook bitmask in comefrom. */ |
419 | static int | 407 | static int |
420 | mark_source_chains(const struct xt_table_info *newinfo, | 408 | mark_source_chains(const struct xt_table_info *newinfo, |
421 | unsigned int valid_hooks, void *entry0) | 409 | unsigned int valid_hooks, void *entry0, |
410 | unsigned int *offsets) | ||
422 | { | 411 | { |
423 | unsigned int hook; | 412 | unsigned int hook; |
424 | 413 | ||
@@ -487,10 +476,11 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
487 | XT_STANDARD_TARGET) == 0 && | 476 | XT_STANDARD_TARGET) == 0 && |
488 | newpos >= 0) { | 477 | newpos >= 0) { |
489 | /* This a jump; chase it. */ | 478 | /* This a jump; chase it. */ |
479 | if (!xt_find_jump_offset(offsets, newpos, | ||
480 | newinfo->number)) | ||
481 | return 0; | ||
490 | e = (struct ip6t_entry *) | 482 | e = (struct ip6t_entry *) |
491 | (entry0 + newpos); | 483 | (entry0 + newpos); |
492 | if (!find_jump_target(newinfo, e)) | ||
493 | return 0; | ||
494 | } else { | 484 | } else { |
495 | /* ... this is a fallthru */ | 485 | /* ... this is a fallthru */ |
496 | newpos = pos + e->next_offset; | 486 | newpos = pos + e->next_offset; |
@@ -724,6 +714,7 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
724 | const struct ip6t_replace *repl) | 714 | const struct ip6t_replace *repl) |
725 | { | 715 | { |
726 | struct ip6t_entry *iter; | 716 | struct ip6t_entry *iter; |
717 | unsigned int *offsets; | ||
727 | unsigned int i; | 718 | unsigned int i; |
728 | int ret = 0; | 719 | int ret = 0; |
729 | 720 | ||
@@ -736,6 +727,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
736 | newinfo->underflow[i] = 0xFFFFFFFF; | 727 | newinfo->underflow[i] = 0xFFFFFFFF; |
737 | } | 728 | } |
738 | 729 | ||
730 | offsets = xt_alloc_entry_offsets(newinfo->number); | ||
731 | if (!offsets) | ||
732 | return -ENOMEM; | ||
739 | i = 0; | 733 | i = 0; |
740 | /* Walk through entries, checking offsets. */ | 734 | /* Walk through entries, checking offsets. */ |
741 | xt_entry_foreach(iter, entry0, newinfo->size) { | 735 | xt_entry_foreach(iter, entry0, newinfo->size) { |
@@ -745,15 +739,18 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
745 | repl->underflow, | 739 | repl->underflow, |
746 | repl->valid_hooks); | 740 | repl->valid_hooks); |
747 | if (ret != 0) | 741 | if (ret != 0) |
748 | return ret; | 742 | goto out_free; |
743 | if (i < repl->num_entries) | ||
744 | offsets[i] = (void *)iter - entry0; | ||
749 | ++i; | 745 | ++i; |
750 | if (strcmp(ip6t_get_target(iter)->u.user.name, | 746 | if (strcmp(ip6t_get_target(iter)->u.user.name, |
751 | XT_ERROR_TARGET) == 0) | 747 | XT_ERROR_TARGET) == 0) |
752 | ++newinfo->stacksize; | 748 | ++newinfo->stacksize; |
753 | } | 749 | } |
754 | 750 | ||
751 | ret = -EINVAL; | ||
755 | if (i != repl->num_entries) | 752 | if (i != repl->num_entries) |
756 | return -EINVAL; | 753 | goto out_free; |
757 | 754 | ||
758 | /* Check hooks all assigned */ | 755 | /* Check hooks all assigned */ |
759 | for (i = 0; i < NF_INET_NUMHOOKS; i++) { | 756 | for (i = 0; i < NF_INET_NUMHOOKS; i++) { |
@@ -761,13 +758,16 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
761 | if (!(repl->valid_hooks & (1 << i))) | 758 | if (!(repl->valid_hooks & (1 << i))) |
762 | continue; | 759 | continue; |
763 | if (newinfo->hook_entry[i] == 0xFFFFFFFF) | 760 | if (newinfo->hook_entry[i] == 0xFFFFFFFF) |
764 | return -EINVAL; | 761 | goto out_free; |
765 | if (newinfo->underflow[i] == 0xFFFFFFFF) | 762 | if (newinfo->underflow[i] == 0xFFFFFFFF) |
766 | return -EINVAL; | 763 | goto out_free; |
767 | } | 764 | } |
768 | 765 | ||
769 | if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) | 766 | if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) { |
770 | return -ELOOP; | 767 | ret = -ELOOP; |
768 | goto out_free; | ||
769 | } | ||
770 | kvfree(offsets); | ||
771 | 771 | ||
772 | /* Finally, each sanity check must pass */ | 772 | /* Finally, each sanity check must pass */ |
773 | i = 0; | 773 | i = 0; |
@@ -788,6 +788,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
788 | } | 788 | } |
789 | 789 | ||
790 | return ret; | 790 | return ret; |
791 | out_free: | ||
792 | kvfree(offsets); | ||
793 | return ret; | ||
791 | } | 794 | } |
792 | 795 | ||
793 | static void | 796 | static void |