mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
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>
This commit is contained in:
commit
0c12d91b70
5 changed files with 28 additions and 38 deletions
|
@ -4654,8 +4654,8 @@ L: netfilter@vger.kernel.org
|
||||||
L: coreteam@netfilter.org
|
L: coreteam@netfilter.org
|
||||||
W: http://www.netfilter.org/
|
W: http://www.netfilter.org/
|
||||||
W: http://www.iptables.org/
|
W: http://www.iptables.org/
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git
|
T: git git://1984.lsi.us.es/nf
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git
|
T: git git://1984.lsi.us.es/nf-next
|
||||||
S: Supported
|
S: Supported
|
||||||
F: include/linux/netfilter*
|
F: include/linux/netfilter*
|
||||||
F: include/linux/netfilter/
|
F: include/linux/netfilter/
|
||||||
|
|
|
@ -639,6 +639,14 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ip_set_none(struct sock *ctnl, struct sk_buff *skb,
|
||||||
|
const struct nlmsghdr *nlh,
|
||||||
|
const struct nlattr * const attr[])
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ip_set_create(struct sock *ctnl, struct sk_buff *skb,
|
ip_set_create(struct sock *ctnl, struct sk_buff *skb,
|
||||||
const struct nlmsghdr *nlh,
|
const struct nlmsghdr *nlh,
|
||||||
|
@ -1539,6 +1547,10 @@ ip_set_protocol(struct sock *ctnl, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = {
|
static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = {
|
||||||
|
[IPSET_CMD_NONE] = {
|
||||||
|
.call = ip_set_none,
|
||||||
|
.attr_count = IPSET_ATTR_CMD_MAX,
|
||||||
|
},
|
||||||
[IPSET_CMD_CREATE] = {
|
[IPSET_CMD_CREATE] = {
|
||||||
.call = ip_set_create,
|
.call = ip_set_create,
|
||||||
.attr_count = IPSET_ATTR_CMD_MAX,
|
.attr_count = IPSET_ATTR_CMD_MAX,
|
||||||
|
|
|
@ -38,30 +38,6 @@ struct iface_node {
|
||||||
|
|
||||||
#define iface_data(n) (rb_entry(n, struct iface_node, node)->iface)
|
#define iface_data(n) (rb_entry(n, struct iface_node, node)->iface)
|
||||||
|
|
||||||
static inline long
|
|
||||||
ifname_compare(const char *_a, const char *_b)
|
|
||||||
{
|
|
||||||
const long *a = (const long *)_a;
|
|
||||||
const long *b = (const long *)_b;
|
|
||||||
|
|
||||||
BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
|
|
||||||
if (a[0] != b[0])
|
|
||||||
return a[0] - b[0];
|
|
||||||
if (IFNAMSIZ > sizeof(long)) {
|
|
||||||
if (a[1] != b[1])
|
|
||||||
return a[1] - b[1];
|
|
||||||
}
|
|
||||||
if (IFNAMSIZ > 2 * sizeof(long)) {
|
|
||||||
if (a[2] != b[2])
|
|
||||||
return a[2] - b[2];
|
|
||||||
}
|
|
||||||
if (IFNAMSIZ > 3 * sizeof(long)) {
|
|
||||||
if (a[3] != b[3])
|
|
||||||
return a[3] - b[3];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rbtree_destroy(struct rb_root *root)
|
rbtree_destroy(struct rb_root *root)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +75,7 @@ iface_test(struct rb_root *root, const char **iface)
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
const char *d = iface_data(n);
|
const char *d = iface_data(n);
|
||||||
long res = ifname_compare(*iface, d);
|
int res = strcmp(*iface, d);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
n = n->rb_left;
|
n = n->rb_left;
|
||||||
|
@ -121,7 +97,7 @@ iface_add(struct rb_root *root, const char **iface)
|
||||||
|
|
||||||
while (*n) {
|
while (*n) {
|
||||||
char *ifname = iface_data(*n);
|
char *ifname = iface_data(*n);
|
||||||
long res = ifname_compare(*iface, ifname);
|
int res = strcmp(*iface, ifname);
|
||||||
|
|
||||||
p = *n;
|
p = *n;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -366,7 +342,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||||
struct hash_netiface4_elem data = { .cidr = HOST_MASK };
|
struct hash_netiface4_elem data = { .cidr = HOST_MASK };
|
||||||
u32 ip = 0, ip_to, last;
|
u32 ip = 0, ip_to, last;
|
||||||
u32 timeout = h->timeout;
|
u32 timeout = h->timeout;
|
||||||
char iface[IFNAMSIZ] = {};
|
char iface[IFNAMSIZ];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(!tb[IPSET_ATTR_IP] ||
|
if (unlikely(!tb[IPSET_ATTR_IP] ||
|
||||||
|
@ -663,7 +639,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct hash_netiface6_elem data = { .cidr = HOST_MASK };
|
struct hash_netiface6_elem data = { .cidr = HOST_MASK };
|
||||||
u32 timeout = h->timeout;
|
u32 timeout = h->timeout;
|
||||||
char iface[IFNAMSIZ] = {};
|
char iface[IFNAMSIZ];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(!tb[IPSET_ATTR_IP] ||
|
if (unlikely(!tb[IPSET_ATTR_IP] ||
|
||||||
|
|
|
@ -76,19 +76,19 @@ static void __ip_vs_del_service(struct ip_vs_service *svc);
|
||||||
|
|
||||||
#ifdef CONFIG_IP_VS_IPV6
|
#ifdef CONFIG_IP_VS_IPV6
|
||||||
/* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */
|
/* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */
|
||||||
static int __ip_vs_addr_is_local_v6(struct net *net,
|
static bool __ip_vs_addr_is_local_v6(struct net *net,
|
||||||
const struct in6_addr *addr)
|
const struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
struct rt6_info *rt;
|
|
||||||
struct flowi6 fl6 = {
|
struct flowi6 fl6 = {
|
||||||
.daddr = *addr,
|
.daddr = *addr,
|
||||||
};
|
};
|
||||||
|
struct dst_entry *dst = ip6_route_output(net, NULL, &fl6);
|
||||||
|
bool is_local;
|
||||||
|
|
||||||
rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
|
is_local = !dst->error && dst->dev && (dst->dev->flags & IFF_LOOPBACK);
|
||||||
if (rt && rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
dst_release(dst);
|
||||||
|
return is_local;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -169,8 +169,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||||
|
|
||||||
err = nla_parse(cda, ss->cb[cb_id].attr_count,
|
err = nla_parse(cda, ss->cb[cb_id].attr_count,
|
||||||
attr, attrlen, ss->cb[cb_id].policy);
|
attr, attrlen, ss->cb[cb_id].policy);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
|
rcu_read_unlock();
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (nc->call_rcu) {
|
if (nc->call_rcu) {
|
||||||
err = nc->call_rcu(net->nfnl, skb, nlh,
|
err = nc->call_rcu(net->nfnl, skb, nlh,
|
||||||
|
|
Loading…
Reference in a new issue