Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1467177

[PATCH 3.10 021/180] netfilter: x_tables: do compat validation via translate_table

From Willy Tarreau <w@1wt.eu>
Newsgroups linux.kernel
Subject [PATCH 3.10 021/180] netfilter: x_tables: do compat validation via translate_table
Date 2016-08-21 18:20 +0200
Message-ID <s8DDA-2Bs-11@gated-at.bofh.it> (permalink)
References <s8D0R-26R-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Florian Westphal <fw@strlen.de>

commit 09d9686047dbbe1cf4faa558d3ecc4aae2046054 upstream.

This looks like refactoring, but its also a bug fix.

Problem is that the compat path (32bit iptables, 64bit kernel) lacks a few
sanity tests that are done in the normal path.

For example, we do not check for underflows and the base chain policies.

While its possible to also add such checks to the compat path, its more
copy&pastry, for instance we cannot reuse check_underflow() helper as
e->target_offset differs in the compat case.

Other problem is that it makes auditing for validation errors harder; two
places need to be checked and kept in sync.

At a high level 32 bit compat works like this:
1- initial pass over blob:
   validate match/entry offsets, bounds checking
   lookup all matches and targets
   do bookkeeping wrt. size delta of 32/64bit structures
   assign match/target.u.kernel pointer (points at kernel
   implementation, needed to access ->compatsize etc.)

2- allocate memory according to the total bookkeeping size to
   contain the translated ruleset

3- second pass over original blob:
   for each entry, copy the 32bit representation to the newly allocated
   memory.  This also does any special match translations (e.g.
   adjust 32bit to 64bit longs, etc).

4- check if ruleset is free of loops (chase all jumps)

5-first pass over translated blob:
   call the checkentry function of all matches and targets.

The alternative implemented by this patch is to drop steps 3&4 from the
compat process, the translation is changed into an intermediate step
rather than a full 1:1 translate_table replacement.

In the 2nd pass (step #3), change the 64bit ruleset back to a kernel
representation, i.e. put() the kernel pointer and restore ->u.user.name .

This gets us a 64bit ruleset that is in the format generated by a 64bit
iptables userspace -- we can then use translate_table() to get the
'native' sanity checks.

This has two drawbacks:

1. we re-validate all the match and target entry structure sizes even
though compat translation is supposed to never generate bogus offsets.
2. we put and then re-lookup each match and target.

THe upside is that we get all sanity tests and ruleset validations
provided by the normal path and can remove some duplicated compat code.

iptables-restore time of autogenerated ruleset with 300k chains of form
-A CHAIN0001 -m limit --limit 1/s -j CHAIN0002
-A CHAIN0002 -m limit --limit 1/s -j CHAIN0003

shows no noticeable differences in restore times:
old:   0m30.796s
new:   0m31.521s
64bit: 0m25.674s

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
 net/ipv4/netfilter/arp_tables.c | 109 ++++++-----------------------
 net/ipv4/netfilter/ip_tables.c  | 151 ++++++++--------------------------------
 net/ipv6/netfilter/ip6_tables.c | 145 ++++++--------------------------------
 net/netfilter/x_tables.c        |   8 +++
 4 files changed, 80 insertions(+), 333 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b65b562..2339399 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1222,19 +1222,17 @@ static inline void compat_release_entry(struct compat_arpt_entry *e)
 	module_put(t->u.kernel.target->me);
 }
 
-static inline int
+static int
 check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows)
+				  const unsigned char *limit)
 {
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
@@ -1279,17 +1277,6 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 	if (ret)
 		goto release_target;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 release_target:
@@ -1339,7 +1326,7 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_arpt_entry *iter0;
-	struct arpt_entry *iter1;
+	struct arpt_replace repl;
 	unsigned int size;
 	int ret = 0;
 
@@ -1348,12 +1335,6 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 	size = compatr->size;
 	info->number = compatr->num_entries;
 
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
-
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(NFPROTO_ARP);
@@ -1362,9 +1343,7 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + compatr->size,
-							compatr->hook_entry,
-							compatr->underflow);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
@@ -1377,23 +1356,6 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(compatr->valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, info->hook_entry[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, info->underflow[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
@@ -1410,51 +1372,25 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 	xt_entry_foreach(iter0, entry0, compatr->size)
 		compat_copy_entry_from_user(iter0, &pos, &size,
 					    newinfo, entry1);
+
+	/* all module references in entry0 are now gone */
+
 	xt_compat_flush_offsets(NFPROTO_ARP);
 	xt_compat_unlock(NFPROTO_ARP);
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = check_target(iter1, compatr->name);
-		if (ret != 0)
-			break;
-		++i;
-		if (strcmp(arpt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
-	/* And one copy for every other CPU */
-	for_each_possible_cpu(i)
-		if (newinfo->entries[i] && newinfo->entries[i] != entry1)
-			memcpy(newinfo->entries[i], entry1, newinfo->size);
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
 
 	*pinfo = newinfo;
 	*pentry0 = entry1;
@@ -1463,17 +1399,16 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(NFPROTO_ARP);
+	xt_compat_unlock(NFPROTO_ARP);
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(NFPROTO_ARP);
-	xt_compat_unlock(NFPROTO_ARP);
-	goto out;
 }
 
 static int compat_do_replace(struct net *net, void __user *user,
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index b9dd1fd..c48b86a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1477,16 +1477,14 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows)
+				  const unsigned char *limit)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
 	unsigned int j;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
@@ -1539,17 +1537,6 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 	if (ret)
 		goto out;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 out:
@@ -1592,6 +1579,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 	xt_compat_target_from_user(t, dstptr, size);
 
 	de->next_offset = e->next_offset - (origsize - *size);
+
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)de - base < newinfo->hook_entry[h])
 			newinfo->hook_entry[h] -= origsize - *size;
@@ -1601,41 +1589,6 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 }
 
 static int
-compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
-{
-	struct xt_entry_match *ematch;
-	struct xt_mtchk_param mtpar;
-	unsigned int j;
-	int ret = 0;
-
-	j = 0;
-	mtpar.net	= net;
-	mtpar.table     = name;
-	mtpar.entryinfo = &e->ip;
-	mtpar.hook_mask = e->comefrom;
-	mtpar.family    = NFPROTO_IPV4;
-	xt_ematch_foreach(ematch, e) {
-		ret = check_match(ematch, &mtpar);
-		if (ret != 0)
-			goto cleanup_matches;
-		++j;
-	}
-
-	ret = check_target(e, net, name);
-	if (ret)
-		goto cleanup_matches;
-	return 0;
-
- cleanup_matches:
-	xt_ematch_foreach(ematch, e) {
-		if (j-- == 0)
-			break;
-		cleanup_match(ematch, net);
-	}
-	return ret;
-}
-
-static int
 translate_compat_table(struct net *net,
 		       struct xt_table_info **pinfo,
 		       void **pentry0,
@@ -1645,7 +1598,7 @@ translate_compat_table(struct net *net,
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_ipt_entry *iter0;
-	struct ipt_entry *iter1;
+	struct ipt_replace repl;
 	unsigned int size;
 	int ret;
 
@@ -1654,12 +1607,6 @@ translate_compat_table(struct net *net,
 	size = compatr->size;
 	info->number = compatr->num_entries;
 
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
-
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET);
@@ -1668,9 +1615,7 @@ translate_compat_table(struct net *net,
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + compatr->size,
-							compatr->hook_entry,
-							compatr->underflow);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
@@ -1683,23 +1628,6 @@ translate_compat_table(struct net *net,
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(compatr->valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, info->hook_entry[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, info->underflow[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
@@ -1707,8 +1635,8 @@ translate_compat_table(struct net *net,
 
 	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		newinfo->hook_entry[i] = info->hook_entry[i];
-		newinfo->underflow[i] = info->underflow[i];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
@@ -1717,51 +1645,29 @@ translate_compat_table(struct net *net,
 		compat_copy_entry_from_user(iter0, &pos, &size,
 					    newinfo, entry1);
 
+	/* all module references in entry0 are now gone.
+	 * entry1/newinfo contains a 64bit ruleset that looks exactly as
+	 * generated by 64bit userspace.
+	 *
+	 * Call standard translate_table() to validate all hook_entrys,
+	 * underflows, check for loops, etc.
+	 */
 	xt_compat_flush_offsets(AF_INET);
 	xt_compat_unlock(AF_INET);
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, compatr->name);
-		if (ret != 0)
-			break;
-		++i;
-		if (strcmp(ipt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1, net);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
-	/* And one copy for every other CPU */
-	for_each_possible_cpu(i)
-		if (newinfo->entries[i] && newinfo->entries[i] != entry1)
-			memcpy(newinfo->entries[i], entry1, newinfo->size);
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(net, newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
 
 	*pinfo = newinfo;
 	*pentry0 = entry1;
@@ -1770,17 +1676,16 @@ translate_compat_table(struct net *net,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(AF_INET);
+	xt_compat_unlock(AF_INET);
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(AF_INET);
-	xt_compat_unlock(AF_INET);
-	goto out;
 }
 
 static int
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 6e7f5ac..1e44ad2 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1489,16 +1489,14 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows)
+				  const unsigned char *limit)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
 	unsigned int j;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
@@ -1551,17 +1549,6 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 	if (ret)
 		goto out;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 out:
@@ -1610,41 +1597,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 	}
 }
 
-static int compat_check_entry(struct ip6t_entry *e, struct net *net,
-			      const char *name)
-{
-	unsigned int j;
-	int ret = 0;
-	struct xt_mtchk_param mtpar;
-	struct xt_entry_match *ematch;
-
-	j = 0;
-	mtpar.net	= net;
-	mtpar.table     = name;
-	mtpar.entryinfo = &e->ipv6;
-	mtpar.hook_mask = e->comefrom;
-	mtpar.family    = NFPROTO_IPV6;
-	xt_ematch_foreach(ematch, e) {
-		ret = check_match(ematch, &mtpar);
-		if (ret != 0)
-			goto cleanup_matches;
-		++j;
-	}
-
-	ret = check_target(e, net, name);
-	if (ret)
-		goto cleanup_matches;
-	return 0;
-
- cleanup_matches:
-	xt_ematch_foreach(ematch, e) {
-		if (j-- == 0)
-			break;
-		cleanup_match(ematch, net);
-	}
-	return ret;
-}
-
 static int
 translate_compat_table(struct net *net,
 		       struct xt_table_info **pinfo,
@@ -1655,7 +1607,7 @@ translate_compat_table(struct net *net,
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_ip6t_entry *iter0;
-	struct ip6t_entry *iter1;
+	struct ip6t_replace repl;
 	unsigned int size;
 	int ret = 0;
 
@@ -1664,12 +1616,6 @@ translate_compat_table(struct net *net,
 	size = compatr->size;
 	info->number = compatr->num_entries;
 
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
-
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET6);
@@ -1678,9 +1624,7 @@ translate_compat_table(struct net *net,
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + compatr->size,
-							compatr->hook_entry,
-							compatr->underflow);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
@@ -1693,23 +1637,6 @@ translate_compat_table(struct net *net,
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(compatr->valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, info->hook_entry[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, info->underflow[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
@@ -1717,60 +1644,33 @@ translate_compat_table(struct net *net,
 
 	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		newinfo->hook_entry[i] = info->hook_entry[i];
-		newinfo->underflow[i] = info->underflow[i];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
+	size = compatr->size;
 	xt_entry_foreach(iter0, entry0, compatr->size)
 		compat_copy_entry_from_user(iter0, &pos, &size,
 					    newinfo, entry1);
 
+	/* all module references in entry0 are now gone. */
 	xt_compat_flush_offsets(AF_INET6);
 	xt_compat_unlock(AF_INET6);
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, compatr->name);
-		if (ret != 0)
-			break;
-		++i;
-		if (strcmp(ip6t_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1, net);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
-	/* And one copy for every other CPU */
-	for_each_possible_cpu(i)
-		if (newinfo->entries[i] && newinfo->entries[i] != entry1)
-			memcpy(newinfo->entries[i], entry1, newinfo->size);
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(net, newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
 
 	*pinfo = newinfo;
 	*pentry0 = entry1;
@@ -1779,17 +1679,16 @@ translate_compat_table(struct net *net,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(AF_INET6);
+	xt_compat_unlock(AF_INET6);
 	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(AF_INET6);
-	xt_compat_unlock(AF_INET6);
-	goto out;
 }
 
 static int
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 9cf3039..da11978 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -552,6 +552,7 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 	struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
 	int pad, off = xt_compat_match_offset(match);
 	u_int16_t msize = cm->u.user.match_size;
+	char name[sizeof(m->u.user.name)];
 
 	m = *dstptr;
 	memcpy(m, cm, sizeof(*cm));
@@ -565,6 +566,9 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 
 	msize += off;
 	m->u.user.match_size = msize;
+	strlcpy(name, match->name, sizeof(name));
+	module_put(match->me);
+	strncpy(m->u.user.name, name, sizeof(m->u.user.name));
 
 	*size += off;
 	*dstptr += msize;
@@ -782,6 +786,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
 	struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
 	int pad, off = xt_compat_target_offset(target);
 	u_int16_t tsize = ct->u.user.target_size;
+	char name[sizeof(t->u.user.name)];
 
 	t = *dstptr;
 	memcpy(t, ct, sizeof(*ct));
@@ -795,6 +800,9 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
 
 	tsize += off;
 	t->u.user.target_size = tsize;
+	strlcpy(name, target->name, sizeof(name));
+	module_put(target->me);
+	strncpy(t->u.user.name, name, sizeof(t->u.user.name));
 
 	*size += off;
 	*dstptr += tsize;
-- 
2.8.0.rc2.1.gbe9624a

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 3.10 000/180] 3.10.103-stable review Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 036/180] usb: renesas_usbhs: protect the CFIFOSEL setting in usbhsg_ep_enable() Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 028/180] udp: properly support MSG_PEEK with truncated buffers Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 017/180] netfilter: ip_tables: simplify translate_compat_table args Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 132/180] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 053/180] MIPS: KVM: Propagate kseg0/mapped tlb fault errors Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 008/180] netfilter: x_tables: add and use xt_check_entry_offsets Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 135/180] scsi: fix race between simultaneous decrements of ->host_failed Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 131/180] ALSA: ctl: Stop notification after disconnection Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 178/180] isdn: hfcpci_softirq: get func return to suppress compiler warning Willy Tarreau <w@1wt.eu> - 2016-08-21 17:40 +0200
  [PATCH 3.10 177/180] net: rfkill: Do not ignore errors from regulator_enable() Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 145/180] ARC: use ASL assembler mnemonic Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 093/180] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 153/180] x86/mm: Improve switch_mm() barrier comments Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 061/180] Input: xpad - validate USB endpoint count during probe Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 104/180] sit: correct IP protocol used in ipip6_err Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 162/180] s5p-mfc: Add release callback for memory region devs Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 126/180] iio:ad7266: Fix broken regulator error handling Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 049/180] tcp: consider recv buf for the initial window scale Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 127/180] iio:ad7266: Fix probe deferral for vref Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 054/180] MIPS: math-emu: Fix jalr emulation when rd == $0 Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 173/180] be2iscsi: Fix bogus WARN_ON length check Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 020/180] netfilter: ensure number of counters is >0 in do_replace() Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 109/180] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 019/180] netfilter: x_tables: xt_compat_match_from_user doesn't need a retval Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 165/180] netlabel: add address family checks to netlbl_{sock,req}_delattr() Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 039/180] cdc_ncm: do not call usbnet_link_change from cdc_ncm_bind Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 055/180] MIPS: Fix siginfo.h to use strict posix types Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 071/180] powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 174/180] squash mm: Export migrate_page_... : also make it non-static Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 026/180] signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 129/180] ALSA: dummy: Fix a use-after-free at closing Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 009/180] netfilter: x_tables: kill check_entry helper Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 158/180] net/irda: fix NULL pointer dereference on memory allocation failure Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 015/180] netfilter: x_tables: don't reject valid target size on some architectures Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 058/180] MIPS: KVM: Fix modular KVM under QEMU Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 113/180] x86, build: copy ldlinux.c32 to image.iso Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 112/180] IB/mlx4: Fix the SQ size of an RC QP Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 095/180] arm: oabi compat: add missing access checks Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 096/180] parisc: Fix pagefault crash in unaligned __get_user() call Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 059/180] Input: uinput - handle compat ioctl for UI_SET_PHYS Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 064/180] aacraid: Fix for aac_command_thread hang Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 124/180] staging: iio: accel: fix error check Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 052/180] MIPS: KVM: Fix gfn range check in kseg0 tlb faults Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 012/180] netfilter: x_tables: check standard target size too Willy Tarreau <w@1wt.eu> - 2016-08-21 17:50 +0200
  [PATCH 3.10 176/180] ALSA: oxygen: Fix logical-not-parentheses warning Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 111/180] IB/IPoIB: Don't update neigh validity for unresolved entries Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 163/180] Bluetooth: Fix l2cap_sock_setsockopt() with optname BT_RCVMTU Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 094/180] ARM: fix PTRACE_SETVFPREGS on SMP systems Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 024/180] perf/x86: Honor the architectural performance monitoring version Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 130/180] ALSA: au88x0: Fix calculation in vortex_wtdma_bufshift() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 141/180] arc: unwind: warn only once if DW2_UNWIND is disabled Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 092/180] xfs: skip stale inodes in xfs_iflush_cluster Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 050/180] MIPS: KVM: Fix mapped fault broken commpage handling Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 128/180] tty/vt/keyboard: fix OOB access in do_compute_shiftstate() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 161/180] s5p-mfc: Set device name for reserved memory region devs Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 140/180] fs/nilfs2: fix potential underflow in call to crc32_le Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 068/180] powerpc: Fix definition of SIAR and SDAR registers Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 078/180] drm/radeon: add a delay after ATPX dGPU power off Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 018/180] netfilter: ip6_tables: simplify translate_compat_table args Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 136/180] scsi: remove scsi_end_request Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 152/180] sctp: Prevent soft lockup when sctp_accept() is called during a timeout event Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 062/180] ath5k: Change led pin configuration for compaq c700 laptop Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 100/180] xfs: fix up backport error in fs/xfs/xfs_inode.c Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 076/180] drm/fb_helper: Fix references to dev->mode_config.num_connector Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 099/180] fix d_walk()/non-delayed __d_free() race Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 156/180] block: fix use-after-free in seq file Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 121/180] tracing: Handle NULL formats in hold_module_trace_bprintk_format() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 066/180] rtlwifi: Fix logic error in enter/exit power-save mode Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 167/180] ftrace/recordmcount: Work around for addition of metag magic but not relocations Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 149/180] can: fix oops caused by wrong rtnl dellink usage Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 037/180] x86/mm: Add barriers and document switch_mm()-vs-flush synchronization Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 134/180] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
    Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility  issue with 64 bit Kernel Johannes Berg <johannes@sipsolutions.net> - 2016-08-22 07:40 +0200
      Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue  with 64 bit Kernel Willy Tarreau <w@1wt.eu> - 2016-08-22 07:50 +0200
  [PATCH 3.10 044/180] libceph: apply new_state before new_up_client on incrementals Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 045/180] tmpfs: don't undo fallocate past its last page Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 168/180] metag: Fix __cmpxchg_u32 asm constraint for CMP Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 046/180] tmpfs: fix regression hang in fallocate undo Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 075/180] drm/gma500: Fix possible out of bounds read Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 169/180] ubi: Make volume resize power cut aware Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 179/180] stb6100: fix buffer length check in stb6100_write_reg_range() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 089/180] dma-debug: avoid spinlock recursion when disabling dma-debug Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 139/180] s390/seccomp: fix error return for filtered system calls Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 103/180] crypto: scatterwalk - Fix test in scatterwalk_done Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 147/180] mmc: block: fix packed command header endianness Willy Tarreau <w@1wt.eu> - 2016-08-21 18:00 +0200
  [PATCH 3.10 102/180] crypto: gcm - Filter out async ghash if necessary Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 142/180] xen/pciback: Fix conf_space read/write overlap check. Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
    Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on  error Dave Chinner <david@fromorbit.com> - 2016-08-22 06:30 +0200
      Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on  error Willy Tarreau <w@1wt.eu> - 2016-08-22 07:20 +0200
        Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on  error Willy Tarreau <w@1wt.eu> - 2016-08-22 07:30 +0200
        Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on  error Dave Chinner <dchinner@redhat.com> - 2016-08-22 13:00 +0200
          Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on  error Willy Tarreau <w@1wt.eu> - 2016-08-22 13:10 +0200
  [PATCH 3.10 003/180] netfilter: x_tables: validate e->target_offset early Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 025/180] perf/x86: Fix undefined shift on 32-bit kernels Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 164/180] cifs: Check for existing directory when opening file with O_CREAT Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 091/180] xfs: fix inode validity check in xfs_iflush_cluster Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 038/180] pipe: limit the per-user amount of pages allocated in pipes Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 118/180] UBIFS: Implement ->migratepage() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 175/180] HID: hid-input: Add parentheses to quell gcc warning Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 065/180] PCI: Disable all BAR sizing for devices with non-compliant BARs Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 144/180] ecryptfs: don't allow mmap when the lower fs doesn't support it Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 043/180] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 067/180] powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 157/180] fuse: fix wrong assignment of ->flags in fuse_send_init() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 023/180] netfilter: x_tables: introduce and use xt_copy_counters_from_user Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 011/180] netfilter: x_tables: add compat version of xt_check_entry_offsets Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 122/180] base: make module_create_drivers_dir race-free Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 087/180] ext4: short-cut orphan cleanup on error Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 125/180] iio: accel: kxsd9: fix the usage of spi_w8r8() Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 070/180] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 107/180] mac80211: mesh: flush mesh paths unconditionally Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 138/180] xen/acpi: allow xen-acpi-processor driver to load on Xen 4.7 Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 119/180] cdc_ncm: workaround for EM7455 "silent" data interface Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 106/180] net: alx: Work around the DMA RX overflow issue Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 032/180] USB: EHCI: declare hostpc register as zero-length array Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 031/180] USB: fix up faulty backports Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 150/180] ipr: Clear interrupt on croc/crocodile when running with LSI Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 041/180] mm: migrate dirty page without clear_page_dirty_for_io etc Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 116/180] NFS: Fix another OPEN_DOWNGRADE bug Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 069/180] powerpc: Use privileged SPR number for MMCR2 Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 085/180] ext4: check for extents that wrap around Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 072/180] powerpc/pseries: Fix PCI config address for DDW Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 110/180] IB/security: Restrict use of the write() interface Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 133/180] ALSA: timer: Fix leak in events via snd_timer_user_ccallback Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 123/180] iio: Fix error handling in iio_trigger_attach_poll_func Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 172/180] module: Invalidate signatures on force-loaded modules Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 160/180] hp-wmi: Fix wifi cannot be hard-unblocked Willy Tarreau <w@1wt.eu> - 2016-08-21 18:10 +0200
  [PATCH 3.10 004/180] netfilter: x_tables: make sure e->next_offset covers remaining blob size Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 042/180] printk: do cond_resched() between lines while outputting to consoles Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 001/180] X.509: remove possible code fragility: enumeration values not handled Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 097/180] ecryptfs: forbid opening files without mmap handler Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 021/180] netfilter: x_tables: do compat validation via translate_table Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 030/180] USB: usbfs: fix potential infoleak in devio Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 040/180] KEYS: potential uninitialized variable Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 034/180] usb: musb: Stop bulk endpoint while queue is rotated Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 005/180] netfilter: x_tables: fix unconditional helper Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 014/180] netfilter: x_tables: validate all offsets and sizes in a rule Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200
  [PATCH 3.10 022/180] Revert "netfilter: ensure number of counters is >0 in do_replace()" Willy Tarreau <w@1wt.eu> - 2016-08-21 18:20 +0200

csiph-web