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 /net | |
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>
Diffstat (limited to 'net')
-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 |
4 files changed, 26 insertions, 36 deletions
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, |