diff options
| author | David S. Miller <davem@davemloft.net> | 2012-06-29 19:35:53 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-06-29 19:35:53 -0400 |
| commit | 0c12d91b7064e16e96939243187b12fbd99caac7 (patch) | |
| tree | 53fdcb3dda55a4089289856439a654c66839f8f6 | |
| parent | 76fbc247b9aebc30f6d2c8ec1f69edcb68eaa328 (diff) | |
| parent | 4009e18851ea555959c6017d848983b3d60bf667 (diff) | |
Merge branch 'master' of git://1984.lsi.us.es/nf
Pablo Neira Ayuso says:
====================
The following are 4 fixes and the update of the MAINTAINERS file
to point to my Netfilter trees.
They are:
* One refcount leak fix in IPVS IPv6 support from Eric Dumazet.
* One fix for interface comparison in ipset hash-netiface sets
from Florian Westphal.
* One fix for a missing rcu_read_unlock in nfnetlink from
Tomasz Bursztyka.
* One fix for a kernel crash if IPSET_CMD_NONE is set to ipset via
nfnetlink, again from Tomasz Bursztyka.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | MAINTAINERS | 4 | ||||
| -rw-r--r-- | net/netfilter/ipset/ip_set_core.c | 12 | ||||
| -rw-r--r-- | net/netfilter/ipset/ip_set_hash_netiface.c | 32 | ||||
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 14 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink.c | 4 |
5 files changed, 28 insertions, 38 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index eb22272b2116..03df1d15ebf3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4654,8 +4654,8 @@ L: netfilter@vger.kernel.org | |||
| 4654 | L: coreteam@netfilter.org | 4654 | L: coreteam@netfilter.org |
| 4655 | W: http://www.netfilter.org/ | 4655 | W: http://www.netfilter.org/ |
| 4656 | W: http://www.iptables.org/ | 4656 | W: http://www.iptables.org/ |
| 4657 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git | 4657 | T: git git://1984.lsi.us.es/nf |
| 4658 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git | 4658 | T: git git://1984.lsi.us.es/nf-next |
| 4659 | S: Supported | 4659 | S: Supported |
| 4660 | F: include/linux/netfilter* | 4660 | F: include/linux/netfilter* |
| 4661 | F: include/linux/netfilter/ | 4661 | F: include/linux/netfilter/ |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 819c342f5b30..9730882697aa 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
| @@ -640,6 +640,14 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) | |||
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | static int | 642 | static int |
| 643 | ip_set_none(struct sock *ctnl, struct sk_buff *skb, | ||
| 644 | const struct nlmsghdr *nlh, | ||
| 645 | const struct nlattr * const attr[]) | ||
| 646 | { | ||
| 647 | return -EOPNOTSUPP; | ||
| 648 | } | ||
| 649 | |||
| 650 | static int | ||
| 643 | ip_set_create(struct sock *ctnl, struct sk_buff *skb, | 651 | ip_set_create(struct sock *ctnl, struct sk_buff *skb, |
| 644 | const struct nlmsghdr *nlh, | 652 | const struct nlmsghdr *nlh, |
| 645 | const struct nlattr * const attr[]) | 653 | const struct nlattr * const attr[]) |
| @@ -1539,6 +1547,10 @@ nlmsg_failure: | |||
| 1539 | } | 1547 | } |
| 1540 | 1548 | ||
| 1541 | static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { | 1549 | static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { |
| 1550 | [IPSET_CMD_NONE] = { | ||
| 1551 | .call = ip_set_none, | ||
| 1552 | .attr_count = IPSET_ATTR_CMD_MAX, | ||
| 1553 | }, | ||
| 1542 | [IPSET_CMD_CREATE] = { | 1554 | [IPSET_CMD_CREATE] = { |
| 1543 | .call = ip_set_create, | 1555 | .call = ip_set_create, |
| 1544 | .attr_count = IPSET_ATTR_CMD_MAX, | 1556 | .attr_count = IPSET_ATTR_CMD_MAX, |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index ee863943c826..d5d3607ae7bc 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
| @@ -38,30 +38,6 @@ struct iface_node { | |||
| 38 | 38 | ||
| 39 | #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) | 39 | #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) |
| 40 | 40 | ||
| 41 | static inline long | ||
| 42 | ifname_compare(const char *_a, const char *_b) | ||
| 43 | { | ||
| 44 | const long *a = (const long *)_a; | ||
| 45 | const long *b = (const long *)_b; | ||
| 46 | |||
| 47 | BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); | ||
| 48 | if (a[0] != b[0]) | ||
| 49 | return a[0] - b[0]; | ||
| 50 | if (IFNAMSIZ > sizeof(long)) { | ||
| 51 | if (a[1] != b[1]) | ||
| 52 | return a[1] - b[1]; | ||
| 53 | } | ||
| 54 | if (IFNAMSIZ > 2 * sizeof(long)) { | ||
| 55 | if (a[2] != b[2]) | ||
| 56 | return a[2] - b[2]; | ||
| 57 | } | ||
| 58 | if (IFNAMSIZ > 3 * sizeof(long)) { | ||
| 59 | if (a[3] != b[3]) | ||
| 60 | return a[3] - b[3]; | ||
| 61 | } | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static void | 41 | static void |
| 66 | rbtree_destroy(struct rb_root *root) | 42 | rbtree_destroy(struct rb_root *root) |
| 67 | { | 43 | { |
| @@ -99,7 +75,7 @@ iface_test(struct rb_root *root, const char **iface) | |||
| 99 | 75 | ||
| 100 | while (n) { | 76 | while (n) { |
| 101 | const char *d = iface_data(n); | 77 | const char *d = iface_data(n); |
| 102 | long res = ifname_compare(*iface, d); | 78 | int res = strcmp(*iface, d); |
| 103 | 79 | ||
| 104 | if (res < 0) | 80 | if (res < 0) |
| 105 | n = n->rb_left; | 81 | n = n->rb_left; |
| @@ -121,7 +97,7 @@ iface_add(struct rb_root *root, const char **iface) | |||
| 121 | 97 | ||
| 122 | while (*n) { | 98 | while (*n) { |
| 123 | char *ifname = iface_data(*n); | 99 | char *ifname = iface_data(*n); |
| 124 | long res = ifname_compare(*iface, ifname); | 100 | int res = strcmp(*iface, ifname); |
| 125 | 101 | ||
| 126 | p = *n; | 102 | p = *n; |
| 127 | if (res < 0) | 103 | if (res < 0) |
| @@ -366,7 +342,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 366 | struct hash_netiface4_elem data = { .cidr = HOST_MASK }; | 342 | struct hash_netiface4_elem data = { .cidr = HOST_MASK }; |
| 367 | u32 ip = 0, ip_to, last; | 343 | u32 ip = 0, ip_to, last; |
| 368 | u32 timeout = h->timeout; | 344 | u32 timeout = h->timeout; |
| 369 | char iface[IFNAMSIZ] = {}; | 345 | char iface[IFNAMSIZ]; |
| 370 | int ret; | 346 | int ret; |
| 371 | 347 | ||
| 372 | if (unlikely(!tb[IPSET_ATTR_IP] || | 348 | if (unlikely(!tb[IPSET_ATTR_IP] || |
| @@ -663,7 +639,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 663 | ipset_adtfn adtfn = set->variant->adt[adt]; | 639 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 664 | struct hash_netiface6_elem data = { .cidr = HOST_MASK }; | 640 | struct hash_netiface6_elem data = { .cidr = HOST_MASK }; |
| 665 | u32 timeout = h->timeout; | 641 | u32 timeout = h->timeout; |
| 666 | char iface[IFNAMSIZ] = {}; | 642 | char iface[IFNAMSIZ]; |
| 667 | int ret; | 643 | int ret; |
| 668 | 644 | ||
| 669 | if (unlikely(!tb[IPSET_ATTR_IP] || | 645 | if (unlikely(!tb[IPSET_ATTR_IP] || |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index dd811b8dd97c..d43e3c122f7b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -76,19 +76,19 @@ static void __ip_vs_del_service(struct ip_vs_service *svc); | |||
| 76 | 76 | ||
| 77 | #ifdef CONFIG_IP_VS_IPV6 | 77 | #ifdef CONFIG_IP_VS_IPV6 |
| 78 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ | 78 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ |
| 79 | static int __ip_vs_addr_is_local_v6(struct net *net, | 79 | static bool __ip_vs_addr_is_local_v6(struct net *net, |
| 80 | const struct in6_addr *addr) | 80 | const struct in6_addr *addr) |
| 81 | { | 81 | { |
| 82 | struct rt6_info *rt; | ||
| 83 | struct flowi6 fl6 = { | 82 | struct flowi6 fl6 = { |
| 84 | .daddr = *addr, | 83 | .daddr = *addr, |
| 85 | }; | 84 | }; |
| 85 | struct dst_entry *dst = ip6_route_output(net, NULL, &fl6); | ||
| 86 | bool is_local; | ||
| 86 | 87 | ||
| 87 | rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); | 88 | is_local = !dst->error && dst->dev && (dst->dev->flags & IFF_LOOPBACK); |
| 88 | if (rt && rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) | ||
| 89 | return 1; | ||
| 90 | 89 | ||
| 91 | return 0; | 90 | dst_release(dst); |
| 91 | return is_local; | ||
| 92 | } | 92 | } |
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 3e797d1fcb94..791d56bbd74a 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
| @@ -169,8 +169,10 @@ replay: | |||
| 169 | 169 | ||
| 170 | err = nla_parse(cda, ss->cb[cb_id].attr_count, | 170 | err = nla_parse(cda, ss->cb[cb_id].attr_count, |
| 171 | attr, attrlen, ss->cb[cb_id].policy); | 171 | attr, attrlen, ss->cb[cb_id].policy); |
| 172 | if (err < 0) | 172 | if (err < 0) { |
| 173 | rcu_read_unlock(); | ||
| 173 | return err; | 174 | return err; |
| 175 | } | ||
| 174 | 176 | ||
| 175 | if (nc->call_rcu) { | 177 | if (nc->call_rcu) { |
| 176 | err = nc->call_rcu(net->nfnl, skb, nlh, | 178 | err = nc->call_rcu(net->nfnl, skb, nlh, |
