All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3.12 01/88] PCI/AER: Clear error status registers during enumeration and restore
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 02/88] MIPS: Fix 64k page support for 32 bit kernels Jiri Slaby
                   ` (88 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Taku Izumi, Bjorn Helgaas, Jiri Slaby

From: Taku Izumi <izumi.taku@jp.fujitsu.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit b07461a8e45b7a62ef7fb46e4f6ada66f63406a8 upstream.

AER errors might be recorded when powering-on devices.  These errors can be
ignored, so firmware usually clears them before the OS enumerates devices.
However, firmware is not involved when devices are added via hotplug, so
the OS may discover power-up errors that should be ignored.  The same may
happen when powering up devices when resuming after suspend.

Clear the AER error status registers during enumeration and resume.

[bhelgaas: changelog, remove repetitive comments]
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/pci/pci.c                  |  3 +++
 drivers/pci/pcie/aer/aerdrv_core.c | 28 ++++++++++++++++++++++++++++
 drivers/pci/probe.c                |  3 +++
 include/linux/aer.h                |  5 +++++
 4 files changed, 39 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1e480a898d28..36c3e71d54b5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -25,6 +25,7 @@
 #include <linux/pci_hotplug.h>
 #include <asm-generic/pci-bridge.h>
 #include <asm/setup.h>
+#include <linux/aer.h>
 #include "pci.h"
 
 const char *pci_power_names[] = {
@@ -1005,6 +1006,8 @@ void pci_restore_state(struct pci_dev *dev)
 	pci_restore_pcie_state(dev);
 	pci_restore_ats_state(dev);
 
+	pci_cleanup_aer_error_status_regs(dev);
+
 	pci_restore_config_space(dev);
 
 	pci_restore_pcix_state(dev);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 28d4c0a0d31a..382eacfd5636 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -74,6 +74,34 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
 
+int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
+{
+	int pos;
+	u32 status;
+	int port_type;
+
+	if (!pci_is_pcie(dev))
+		return -ENODEV;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos)
+		return -EIO;
+
+	port_type = pci_pcie_type(dev);
+	if (port_type == PCI_EXP_TYPE_ROOT_PORT) {
+		pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status);
+		pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, status);
+	}
+
+	pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
+	pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
+
+	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
+	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+
+	return 0;
+}
+
 /**
  * add_error_device - list device to be handled
  * @e_info: pointer to error info
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 53b23ff577b4..4e415a85da29 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/aer.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -1356,6 +1357,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
 
 	/* Enable ACS P2P upstream forwarding */
 	pci_enable_acs(dev);
+
+	pci_cleanup_aer_error_status_regs(dev);
 }
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 4dbaa7081530..1cbc28eb1f90 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -38,6 +38,7 @@ struct aer_capability_regs {
 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
+int pci_cleanup_aer_error_status_regs(struct pci_dev *dev);
 #else
 static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
@@ -51,6 +52,10 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 {
 	return -EINVAL;
 }
+static inline int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
+{
+	return -EINVAL;
+}
 #endif
 
 void cper_print_aer(struct pci_dev *dev, int cper_severity,
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 02/88] MIPS: Fix 64k page support for 32 bit kernels.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 01/88] PCI/AER: Clear error status registers during enumeration and restore Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 03/88] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge Jiri Slaby
                   ` (87 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Ralf Baechle, James Hogan, Jiri Slaby

From: Ralf Baechle <ralf@linux-mips.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d7de413475f443957a0c1d256e405d19b3a2cb22 upstream.

TASK_SIZE was defined as 0x7fff8000UL which for 64k pages is not a
multiple of the page size.  Somewhere further down the math fails
such that executing an ELF binary fails.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Tested-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/mips/include/asm/processor.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 3605b844ad87..efe9964ea9b4 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -51,7 +51,7 @@ extern unsigned int vced_count, vcei_count;
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
-#define TASK_SIZE	0x7fff8000UL
+#define TASK_SIZE	0x80000000UL
 #endif
 
 #ifdef __KERNEL__
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 03/88] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 01/88] PCI/AER: Clear error status registers during enumeration and restore Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 02/88] MIPS: Fix 64k page support for 32 bit kernels Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 04/88] sparc: Fix system call tracing register handling Jiri Slaby
                   ` (86 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Russell Currey, Michael Ellerman, Jiri Slaby

From: Russell Currey <ruscur@russell.cc>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 871e178e0f2c4fa788f694721a10b4758d494ce1 upstream.

In the "ibm,configure-pe" and "ibm,configure-bridge" RTAS calls, the
spec states that values of 9900-9905 can be returned, indicating that
software should delay for 10^x (where x is the last digit, i.e. 990x)
milliseconds and attempt the call again. Currently, the kernel doesn't
know about this, and respecting it fixes some PCI failures when the
hypervisor is busy.

The delay is capped at 0.2 seconds.

Signed-off-by: Russell Currey <ruscur@russell.cc>
Acked-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/platforms/pseries/eeh_pseries.c | 51 ++++++++++++++++++++--------
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 74448701b636..76246a7ef10f 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -612,29 +612,50 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
 {
 	int config_addr;
 	int ret;
+	/* Waiting 0.2s maximum before skipping configuration */
+	int max_wait = 200;
 
 	/* Figure out the PE address */
 	config_addr = pe->config_addr;
 	if (pe->addr)
 		config_addr = pe->addr;
 
-	/* Use new configure-pe function, if supported */
-	if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
-		ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-				config_addr, BUID_HI(pe->phb->buid),
-				BUID_LO(pe->phb->buid));
-	} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
-		ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
-				config_addr, BUID_HI(pe->phb->buid),
-				BUID_LO(pe->phb->buid));
-	} else {
-		return -EFAULT;
-	}
+	while (max_wait > 0) {
+		/* Use new configure-pe function, if supported */
+		if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
+			ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
+					config_addr, BUID_HI(pe->phb->buid),
+					BUID_LO(pe->phb->buid));
+		} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
+			ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
+					config_addr, BUID_HI(pe->phb->buid),
+					BUID_LO(pe->phb->buid));
+		} else {
+			return -EFAULT;
+		}
 
-	if (ret)
-		pr_warning("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
-			__func__, pe->phb->global_number, pe->addr, ret);
+		if (!ret)
+			return ret;
+
+		/*
+		 * If RTAS returns a delay value that's above 100ms, cut it
+		 * down to 100ms in case firmware made a mistake.  For more
+		 * on how these delay values work see rtas_busy_delay_time
+		 */
+		if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
+		    ret <= RTAS_EXTENDED_DELAY_MAX)
+			ret = RTAS_EXTENDED_DELAY_MIN+2;
+
+		max_wait -= rtas_busy_delay_time(ret);
+
+		if (max_wait < 0)
+			break;
+
+		rtas_busy_delay(ret);
+	}
 
+	pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
+		__func__, pe->phb->global_number, pe->addr, ret);
 	return ret;
 }
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 04/88] sparc: Fix system call tracing register handling.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (2 preceding siblings ...)
  2016-07-14  8:14 ` [PATCH 3.12 03/88] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 05/88] sparc64: Fix bootup regressions on some Kconfig combinations Jiri Slaby
                   ` (85 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Mike Frysinger, David S . Miller, Jiri Slaby

From: Mike Frysinger <vapier@gentoo.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 1a40b95374f680625318ab61d81958e949e0afe3 ]

A system call trace trigger on entry allows the tracing
process to inspect and potentially change the traced
process's registers.

Account for that by reloading the %g1 (syscall number)
and %i0-%i5 (syscall argument) values.  We need to be
careful to revalidate the range of %g1, and reload the
system call table entry it corresponds to into %l7.

Reported-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Tested-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/kernel/entry.S    | 17 +++++++++++++++++
 arch/sparc/kernel/syscalls.S | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 33c02b15f478..a83707c83be8 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -948,7 +948,24 @@ linux_syscall_trace:
 	cmp	%o0, 0
 	bne	3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ld	[%sp + STACKFRAME_SZ + PT_G1], %g1
+	sethi	%hi(sys_call_table), %l7
+	ld	[%sp + STACKFRAME_SZ + PT_I0], %i0
+	or	%l7, %lo(sys_call_table), %l7
+	ld	[%sp + STACKFRAME_SZ + PT_I1], %i1
+	ld	[%sp + STACKFRAME_SZ + PT_I2], %i2
+	ld	[%sp + STACKFRAME_SZ + PT_I3], %i3
+	ld	[%sp + STACKFRAME_SZ + PT_I4], %i4
+	ld	[%sp + STACKFRAME_SZ + PT_I5], %i5
+	cmp	%g1, NR_syscalls
+	bgeu	3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	mov	%i0, %o0
+	ld	[%l7 + %l4], %l7
 	mov	%i1, %o1
 	mov	%i2, %o2
 	mov	%i3, %o3
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 6dee79575791..db4408e54bee 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -148,7 +148,25 @@ linux_syscall_trace32:
 	 add	%sp, PTREGS_OFF, %o0
 	brnz,pn	%o0, 3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ldx	[%sp + PTREGS_OFF + PT_V9_G1], %g1
+	sethi	%hi(sys_call_table32), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I0], %i0
+	or	%l7, %lo(sys_call_table32), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I1], %i1
+	ldx	[%sp + PTREGS_OFF + PT_V9_I2], %i2
+	ldx	[%sp + PTREGS_OFF + PT_V9_I3], %i3
+	ldx	[%sp + PTREGS_OFF + PT_V9_I4], %i4
+	ldx	[%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+	cmp	%g1, NR_syscalls
+	bgeu,pn	%xcc, 3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	srl	%i0, 0, %o0
+	lduw	[%l7 + %l4], %l7
 	srl	%i4, 0, %o4
 	srl	%i1, 0, %o1
 	srl	%i2, 0, %o2
@@ -160,7 +178,25 @@ linux_syscall_trace:
 	 add	%sp, PTREGS_OFF, %o0
 	brnz,pn	%o0, 3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ldx	[%sp + PTREGS_OFF + PT_V9_G1], %g1
+	sethi	%hi(sys_call_table64), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I0], %i0
+	or	%l7, %lo(sys_call_table64), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I1], %i1
+	ldx	[%sp + PTREGS_OFF + PT_V9_I2], %i2
+	ldx	[%sp + PTREGS_OFF + PT_V9_I3], %i3
+	ldx	[%sp + PTREGS_OFF + PT_V9_I4], %i4
+	ldx	[%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+	cmp	%g1, NR_syscalls
+	bgeu,pn	%xcc, 3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	mov	%i0, %o0
+	lduw	[%l7 + %l4], %l7
 	mov	%i1, %o1
 	mov	%i2, %o2
 	mov	%i3, %o3
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 05/88] sparc64: Fix bootup regressions on some Kconfig combinations.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (3 preceding siblings ...)
  2016-07-14  8:14 ` [PATCH 3.12 04/88] sparc: Fix system call tracing register handling Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 06/88] sparc64: Fix sparc64_set_context stack handling Jiri Slaby
                   ` (84 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, David S. Miller, Jiri Slaby

From: "David S. Miller" <davem@davemloft.net>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 49fa5230462f9f2c4e97c81356473a6bdf06c422 ]

The system call tracing bug fix mentioned in the Fixes tag
below increased the amount of assembler code in the sequence
of assembler files included by head_64.S

This caused to total set of code to exceed 0x4000 bytes in
size, which overflows the expression in head_64.S that works
to place swapper_tsb at address 0x408000.

When this is violated, the TSB is not properly aligned, and
also the trap table is not aligned properly either.  All of
this together results in failed boots.

So, do two things:

1) Simplify some code by using ba,a instead of ba/nop to get
   those bytes back.

2) Add a linker script assertion to make sure that if this
   happens again the build will fail.

Fixes: 1a40b95374f6 ("sparc: Fix system call tracing register handling.")
Reported-by: Meelis Roos <mroos@linux.ee>
Reported-by: Joerg Abraham <joerg.abraham@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/kernel/cherrs.S      | 14 +++++---------
 arch/sparc/kernel/fpu_traps.S   | 11 +++++------
 arch/sparc/kernel/head_64.S     | 24 ++++++++----------------
 arch/sparc/kernel/misctrap.S    | 12 ++++--------
 arch/sparc/kernel/spiterrs.S    | 18 ++++++------------
 arch/sparc/kernel/utrap.S       |  3 +--
 arch/sparc/kernel/vmlinux.lds.S |  4 ++++
 arch/sparc/kernel/winfixup.S    |  3 +--
 8 files changed, 34 insertions(+), 55 deletions(-)

diff --git a/arch/sparc/kernel/cherrs.S b/arch/sparc/kernel/cherrs.S
index 4ee1ad420862..655628def68e 100644
--- a/arch/sparc/kernel/cherrs.S
+++ b/arch/sparc/kernel/cherrs.S
@@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal:	/* Ok we may use interrupt globals safely. */
 	subcc		%g1, %g2, %g1		! Next cacheline
 	bge,pt		%icc, 1b
 	 nop
-	ba,pt		%xcc, dcpe_icpe_tl1_common
-	 nop
+	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 
 do_dcpe_tl1_fatal:
 	sethi		%hi(1f), %g7
@@ -224,8 +223,7 @@ do_dcpe_tl1_fatal:
 	mov		0x2, %o0
 	call		cheetah_plus_parity_error
 	 add		%sp, PTREGS_OFF, %o1
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_dcpe_tl1,.-do_dcpe_tl1
 
 	.globl		do_icpe_tl1
@@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal:	/* Ok we may use interrupt globals safely. */
 	subcc		%g1, %g2, %g1
 	bge,pt		%icc, 1b
 	 nop
-	ba,pt		%xcc, dcpe_icpe_tl1_common
-	 nop
+	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 
 do_icpe_tl1_fatal:
 	sethi		%hi(1f), %g7
@@ -269,8 +266,7 @@ do_icpe_tl1_fatal:
 	mov		0x3, %o0
 	call		cheetah_plus_parity_error
 	 add		%sp, PTREGS_OFF, %o1
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_icpe_tl1,.-do_icpe_tl1
 	
 	.type		dcpe_icpe_tl1_common,#function
@@ -456,7 +452,7 @@ __cheetah_log_error:
 	 cmp		%g2, 0x63
 	be		c_cee
 	 nop
-	ba,pt		%xcc, c_deferred
+	ba,a,pt		%xcc, c_deferred
 	.size		__cheetah_log_error,.-__cheetah_log_error
 
 	/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
diff --git a/arch/sparc/kernel/fpu_traps.S b/arch/sparc/kernel/fpu_traps.S
index a6864826a4bd..336d2750fe78 100644
--- a/arch/sparc/kernel/fpu_traps.S
+++ b/arch/sparc/kernel/fpu_traps.S
@@ -100,8 +100,8 @@ do_fpdis:
 	fmuld		%f0, %f2, %f26
 	faddd		%f0, %f2, %f28
 	fmuld		%f0, %f2, %f30
-	b,pt		%xcc, fpdis_exit
-	 nop
+	ba,a,pt		%xcc, fpdis_exit
+
 2:	andcc		%g5, FPRS_DU, %g0
 	bne,pt		%icc, 3f
 	 fzero		%f32
@@ -144,8 +144,8 @@ do_fpdis:
 	fmuld		%f32, %f34, %f58
 	faddd		%f32, %f34, %f60
 	fmuld		%f32, %f34, %f62
-	ba,pt		%xcc, fpdis_exit
-	 nop
+	ba,a,pt		%xcc, fpdis_exit
+
 3:	mov		SECONDARY_CONTEXT, %g3
 	add		%g6, TI_FPREGS, %g1
 
@@ -197,8 +197,7 @@ fpdis_exit2:
 fp_other_bounce:
 	call		do_fpother
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		fp_other_bounce,.-fp_other_bounce
 
 	.align		32
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 3d61fcae7ee3..8ff57630a486 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -461,9 +461,8 @@ sun4v_chip_type:
 	subcc	%g3, 1, %g3
 	bne,pt	%xcc, 41b
 	add	%g1, 1, %g1
-	mov	SUN4V_CHIP_SPARC64X, %g4
 	ba,pt	%xcc, 5f
-	nop
+	 mov	SUN4V_CHIP_SPARC64X, %g4
 
 49:
 	mov	SUN4V_CHIP_UNKNOWN, %g4
@@ -548,8 +547,7 @@ sun4u_init:
 	stxa		%g0, [%g7] ASI_DMMU
 	membar	#Sync
 
-	ba,pt		%xcc, sun4u_continue
-	 nop
+	ba,a,pt		%xcc, sun4u_continue
 
 sun4v_init:
 	/* Set ctx 0 */
@@ -560,14 +558,12 @@ sun4v_init:
 	mov		SECONDARY_CONTEXT, %g7
 	stxa		%g0, [%g7] ASI_MMU
 	membar		#Sync
-	ba,pt		%xcc, niagara_tlb_fixup
-	 nop
+	ba,a,pt		%xcc, niagara_tlb_fixup
 
 sun4u_continue:
 	BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
 
-	ba,pt	%xcc, spitfire_tlb_fixup
-	 nop
+	ba,a,pt	%xcc, spitfire_tlb_fixup
 
 niagara_tlb_fixup:
 	mov	3, %g2		/* Set TLB type to hypervisor. */
@@ -639,8 +635,7 @@ niagara_patch:
 	call	hypervisor_patch_cachetlbops
 	 nop
 
-	ba,pt	%xcc, tlb_fixup_done
-	 nop
+	ba,a,pt	%xcc, tlb_fixup_done
 
 cheetah_tlb_fixup:
 	mov	2, %g2		/* Set TLB type to cheetah+. */
@@ -659,8 +654,7 @@ cheetah_tlb_fixup:
 	call	cheetah_patch_cachetlbops
 	 nop
 
-	ba,pt	%xcc, tlb_fixup_done
-	 nop
+	ba,a,pt	%xcc, tlb_fixup_done
 
 spitfire_tlb_fixup:
 	/* Set TLB type to spitfire. */
@@ -782,8 +776,7 @@ setup_trap_table:
 	call	%o1
 	 add	%sp, (2047 + 128), %o0
 
-	ba,pt	%xcc, 2f
-	 nop
+	ba,a,pt	%xcc, 2f
 
 1:	sethi	%hi(sparc64_ttable_tl0), %o0
 	set	prom_set_trap_table_name, %g2
@@ -822,8 +815,7 @@ setup_trap_table:
 
 	BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
 
-	ba,pt	%xcc, 2f
-	 nop
+	ba,a,pt	%xcc, 2f
 
 	/* Disable STICK_INT interrupts. */
 1:
diff --git a/arch/sparc/kernel/misctrap.S b/arch/sparc/kernel/misctrap.S
index 753b4f031bfb..34b4933900bf 100644
--- a/arch/sparc/kernel/misctrap.S
+++ b/arch/sparc/kernel/misctrap.S
@@ -18,8 +18,7 @@ __do_privact:
 109:	or		%g7, %lo(109b), %g7
 	call		do_privact
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__do_privact,.-__do_privact
 
 	.type		do_mna,#function
@@ -46,8 +45,7 @@ do_mna:
 	mov		%l5, %o2
 	call		mem_address_unaligned
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_mna,.-do_mna
 
 	.type		do_lddfmna,#function
@@ -65,8 +63,7 @@ do_lddfmna:
 	mov		%l5, %o2
 	call		handle_lddfmna
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_lddfmna,.-do_lddfmna
 
 	.type		do_stdfmna,#function
@@ -84,8 +81,7 @@ do_stdfmna:
 	mov		%l5, %o2
 	call		handle_stdfmna
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_stdfmna,.-do_stdfmna
 
 	.type		breakpoint_trap,#function
diff --git a/arch/sparc/kernel/spiterrs.S b/arch/sparc/kernel/spiterrs.S
index c357e40ffd01..4a73009f66a5 100644
--- a/arch/sparc/kernel/spiterrs.S
+++ b/arch/sparc/kernel/spiterrs.S
@@ -85,8 +85,7 @@ __spitfire_cee_trap_continue:
 	ba,pt		%xcc, etraptl1
 	 rd		%pc, %g7
 
-	ba,pt		%xcc, 2f
-	 nop
+	ba,a,pt		%xcc, 2f
 
 1:	ba,pt		%xcc, etrap_irq
 	 rd		%pc, %g7
@@ -100,8 +99,7 @@ __spitfire_cee_trap_continue:
 	mov		%l5, %o2
 	call		spitfire_access_error
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_access_error,.-__spitfire_access_error
 
 	/* This is the trap handler entry point for ECC correctable
@@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1:
 	mov		%l5, %o2
 	call		spitfire_data_access_exception_tl1
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
 
 	.type		__spitfire_data_access_exception,#function
@@ -200,8 +197,7 @@ __spitfire_data_access_exception:
 	mov		%l5, %o2
 	call		spitfire_data_access_exception
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_data_access_exception,.-__spitfire_data_access_exception
 
 	.type		__spitfire_insn_access_exception_tl1,#function
@@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1:
 	mov		%l5, %o2
 	call		spitfire_insn_access_exception_tl1
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
 
 	.type		__spitfire_insn_access_exception,#function
@@ -240,6 +235,5 @@ __spitfire_insn_access_exception:
 	mov		%l5, %o2
 	call		spitfire_insn_access_exception
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_insn_access_exception,.-__spitfire_insn_access_exception
diff --git a/arch/sparc/kernel/utrap.S b/arch/sparc/kernel/utrap.S
index b7f0f3f3a909..c731e8023d3e 100644
--- a/arch/sparc/kernel/utrap.S
+++ b/arch/sparc/kernel/utrap.S
@@ -11,8 +11,7 @@ utrap_trap:		/* %g3=handler,%g4=level */
 	mov		%l4, %o1
         call		bad_trap
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 
 invoke_utrap:
 	sllx		%g3, 3, %g3
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 09243057cb0b..7028b4dab903 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -33,6 +33,10 @@ ENTRY(_start)
 jiffies = jiffies_64;
 #endif
 
+#ifdef CONFIG_SPARC64
+ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large")
+#endif
+
 SECTIONS
 {
 #ifdef CONFIG_SPARC64
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S
index 1e67ce958369..855019a8590e 100644
--- a/arch/sparc/kernel/winfixup.S
+++ b/arch/sparc/kernel/winfixup.S
@@ -32,8 +32,7 @@ fill_fixup:
 	 rd	%pc, %g7
 	call	do_sparc64_fault
 	 add	%sp, PTREGS_OFF, %o0
-	ba,pt	%xcc, rtrap
-	 nop
+	ba,a,pt	%xcc, rtrap
 
 	/* Be very careful about usage of the trap globals here.
 	 * You cannot touch %g5 as that has the fault information.
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 06/88] sparc64: Fix sparc64_set_context stack handling.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (4 preceding siblings ...)
  2016-07-14  8:14 ` [PATCH 3.12 05/88] sparc64: Fix bootup regressions on some Kconfig combinations Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 07/88] sparc/PCI: Fix for panic while enabling SR-IOV Jiri Slaby
                   ` (83 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, David S. Miller, Jiri Slaby

From: "David S. Miller" <davem@davemloft.net>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 397d1533b6cce0ccb5379542e2e6d079f6936c46 ]

Like a signal return, we should use synchronize_user_stack() rather
than flush_user_windows().

Reported-by: Ilya Malakhov <ilmalakhovthefirst@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/kernel/signal_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 35923e8abd82..90f08055b7d2 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -49,7 +49,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
 	unsigned char fenab;
 	int err;
 
-	flush_user_windows();
+	synchronize_user_stack();
 	if (get_thread_wsaved()					||
 	    (((unsigned long)ucp) & (sizeof(unsigned long)-1))	||
 	    (!__access_ok(ucp, sizeof(*ucp))))
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 07/88] sparc/PCI: Fix for panic while enabling SR-IOV
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (5 preceding siblings ...)
  2016-07-14  8:14 ` [PATCH 3.12 06/88] sparc64: Fix sparc64_set_context stack handling Jiri Slaby
@ 2016-07-14  8:14 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 08/88] sparc64: Take ctx_alloc_lock properly in hugetlb_setup() Jiri Slaby
                   ` (82 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:14 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Babu Moger, Sowmini Varadhan, David S . Miller, Jiri Slaby

From: Babu Moger <babu.moger@oracle.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit d0c31e02005764dae0aab130a57e9794d06b824d ]

We noticed this panic while enabling SR-IOV in sparc.

mlx4_core: Mellanox ConnectX core driver v2.2-1 (Jan  1 2015)
mlx4_core: Initializing 0007:01:00.0
mlx4_core 0007:01:00.0: Enabling SR-IOV with 5 VFs
mlx4_core: Initializing 0007:01:00.1
Unable to handle kernel NULL pointer dereference
insmod(10010): Oops [#1]
CPU: 391 PID: 10010 Comm: insmod Not tainted
		4.1.12-32.el6uek.kdump2.sparc64 #1
TPC: <dma_supported+0x20/0x80>
I7: <__mlx4_init_one+0x324/0x500 [mlx4_core]>
Call Trace:
 [00000000104c5ea4] __mlx4_init_one+0x324/0x500 [mlx4_core]
 [00000000104c613c] mlx4_init_one+0xbc/0x120 [mlx4_core]
 [0000000000725f14] local_pci_probe+0x34/0xa0
 [0000000000726028] pci_call_probe+0xa8/0xe0
 [0000000000726310] pci_device_probe+0x50/0x80
 [000000000079f700] really_probe+0x140/0x420
 [000000000079fa24] driver_probe_device+0x44/0xa0
 [000000000079fb5c] __device_attach+0x3c/0x60
 [000000000079d85c] bus_for_each_drv+0x5c/0xa0
 [000000000079f588] device_attach+0x88/0xc0
 [000000000071acd0] pci_bus_add_device+0x30/0x80
 [0000000000736090] virtfn_add.clone.1+0x210/0x360
 [00000000007364a4] sriov_enable+0x2c4/0x520
 [000000000073672c] pci_enable_sriov+0x2c/0x40
 [00000000104c2d58] mlx4_enable_sriov+0xf8/0x180 [mlx4_core]
 [00000000104c49ac] mlx4_load_one+0x42c/0xd40 [mlx4_core]
Disabling lock debugging due to kernel taint
Caller[00000000104c5ea4]: __mlx4_init_one+0x324/0x500 [mlx4_core]
Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core]
Caller[0000000000725f14]: local_pci_probe+0x34/0xa0
Caller[0000000000726028]: pci_call_probe+0xa8/0xe0
Caller[0000000000726310]: pci_device_probe+0x50/0x80
Caller[000000000079f700]: really_probe+0x140/0x420
Caller[000000000079fa24]: driver_probe_device+0x44/0xa0
Caller[000000000079fb5c]: __device_attach+0x3c/0x60
Caller[000000000079d85c]: bus_for_each_drv+0x5c/0xa0
Caller[000000000079f588]: device_attach+0x88/0xc0
Caller[000000000071acd0]: pci_bus_add_device+0x30/0x80
Caller[0000000000736090]: virtfn_add.clone.1+0x210/0x360
Caller[00000000007364a4]: sriov_enable+0x2c4/0x520
Caller[000000000073672c]: pci_enable_sriov+0x2c/0x40
Caller[00000000104c2d58]: mlx4_enable_sriov+0xf8/0x180 [mlx4_core]
Caller[00000000104c49ac]: mlx4_load_one+0x42c/0xd40 [mlx4_core]
Caller[00000000104c5f90]: __mlx4_init_one+0x410/0x500 [mlx4_core]
Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core]
Caller[0000000000725f14]: local_pci_probe+0x34/0xa0
Caller[0000000000726028]: pci_call_probe+0xa8/0xe0
Caller[0000000000726310]: pci_device_probe+0x50/0x80
Caller[000000000079f700]: really_probe+0x140/0x420
Caller[000000000079fa24]: driver_probe_device+0x44/0xa0
Caller[000000000079fb08]: __driver_attach+0x88/0xa0
Caller[000000000079d90c]: bus_for_each_dev+0x6c/0xa0
Caller[000000000079f29c]: driver_attach+0x1c/0x40
Caller[000000000079e35c]: bus_add_driver+0x17c/0x220
Caller[00000000007a02d4]: driver_register+0x74/0x120
Caller[00000000007263fc]: __pci_register_driver+0x3c/0x60
Caller[00000000104f62bc]: mlx4_init+0x60/0xcc [mlx4_core]
Kernel panic - not syncing: Fatal exception
Press Stop-A (L1-A) to return to the boot prom
---[ end Kernel panic - not syncing: Fatal exception

Details:
Here is the call sequence
virtfn_add->__mlx4_init_one->dma_set_mask->dma_supported

The panic happened at line 760(file arch/sparc/kernel/iommu.c)

758 int dma_supported(struct device *dev, u64 device_mask)
759 {
760         struct iommu *iommu = dev->archdata.iommu;
761         u64 dma_addr_mask = iommu->dma_addr_mask;
762
763         if (device_mask >= (1UL << 32UL))
764                 return 0;
765
766         if ((device_mask & dma_addr_mask) == dma_addr_mask)
767                 return 1;
768
769 #ifdef CONFIG_PCI
770         if (dev_is_pci(dev))
771		return pci64_dma_supported(to_pci_dev(dev), device_mask);
772 #endif
773
774         return 0;
775 }
776 EXPORT_SYMBOL(dma_supported);

Same panic happened with Intel ixgbe driver also.

SR-IOV code looks for arch specific data while enabling
VFs. When VF device is added, driver probe function makes set
of calls to initialize the pci device. Because the VF device is
added different way than the normal PF device(which happens via
of_create_pci_dev for sparc), some of the arch specific initialization
does not happen for VF device.  That causes panic when archdata is
accessed.

To fix this, I have used already defined weak function
pcibios_setup_device to copy archdata from PF to VF.
Also verified the fix.

Signed-off-by: Babu Moger <babu.moger@oracle.com>
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Reviewed-by: Ethan Zhao <ethan.zhao@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/kernel/pci.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index cb021453de2a..80afbebfbf81 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -930,6 +930,23 @@ void pcibios_set_master(struct pci_dev *dev)
 	/* No special bus mastering setup handling */
 }
 
+#ifdef CONFIG_PCI_IOV
+int pcibios_add_device(struct pci_dev *dev)
+{
+	struct pci_dev *pdev;
+
+	/* Add sriov arch specific initialization here.
+	 * Copy dev_archdata from PF to VF
+	 */
+	if (dev->is_virtfn) {
+		pdev = dev->physfn;
+		memcpy(&dev->dev.archdata, &pdev->dev.archdata,
+		       sizeof(struct dev_archdata));
+	}
+	return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+
 static int __init pcibios_init(void)
 {
 	pci_dfl_cache_line_size = 64 >> 2;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 08/88] sparc64: Take ctx_alloc_lock properly in hugetlb_setup().
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (6 preceding siblings ...)
  2016-07-14  8:14 ` [PATCH 3.12 07/88] sparc/PCI: Fix for panic while enabling SR-IOV Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 09/88] sparc: Harden signal return frame checks Jiri Slaby
                   ` (81 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, David S. Miller, Jiri Slaby

From: "David S. Miller" <davem@davemloft.net>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 9ea46abe22550e3366ff7cee2f8391b35b12f730 ]

On cheetahplus chips we take the ctx_alloc_lock in order to
modify the TLB lookup parameters for the indexed TLBs, which
are stored in the context register.

This is called with interrupts disabled, however ctx_alloc_lock
is an IRQ safe lock, therefore we must take acquire/release it
properly with spin_{lock,unlock}_irq().

Reported-by: Meelis Roos <mroos@linux.ee>
Tested-by: Meelis Roos <mroos@linux.ee>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/mm/init_64.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 4438e94822a2..9633e0706d6e 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2673,9 +2673,10 @@ void hugetlb_setup(struct pt_regs *regs)
 	 * the Data-TLB for huge pages.
 	 */
 	if (tlb_type == cheetah_plus) {
+		bool need_context_reload = false;
 		unsigned long ctx;
 
-		spin_lock(&ctx_alloc_lock);
+		spin_lock_irq(&ctx_alloc_lock);
 		ctx = mm->context.sparc64_ctx_val;
 		ctx &= ~CTX_PGSZ_MASK;
 		ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
@@ -2694,9 +2695,12 @@ void hugetlb_setup(struct pt_regs *regs)
 			 * also executing in this address space.
 			 */
 			mm->context.sparc64_ctx_val = ctx;
-			on_each_cpu(context_reload, mm, 0);
+			need_context_reload = true;
 		}
-		spin_unlock(&ctx_alloc_lock);
+		spin_unlock_irq(&ctx_alloc_lock);
+
+		if (need_context_reload)
+			on_each_cpu(context_reload, mm, 0);
 	}
 }
 #endif
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 09/88] sparc: Harden signal return frame checks.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (7 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 08/88] sparc64: Take ctx_alloc_lock properly in hugetlb_setup() Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 10/88] sparc64: Fix return from trap window fill crashes Jiri Slaby
                   ` (80 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, David S. Miller, Jiri Slaby

From: "David S. Miller" <davem@davemloft.net>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit d11c2a0de2824395656cf8ed15811580c9dd38aa ]

All signal frames must be at least 16-byte aligned, because that is
the alignment we explicitly create when we build signal return stack
frames.

All stack pointers must be at least 8-byte aligned.

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/kernel/signal32.c   | 46 +++++++++++++++++++++++++++---------------
 arch/sparc/kernel/signal_32.c  | 41 +++++++++++++++++++++++--------------
 arch/sparc/kernel/signal_64.c  | 31 ++++++++++++++++++----------
 arch/sparc/kernel/sigutil_32.c |  9 ++++++++-
 arch/sparc/kernel/sigutil_64.c | 10 +++++++--
 5 files changed, 92 insertions(+), 45 deletions(-)

diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index b524f91dd0e5..d45b112908c1 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -137,12 +137,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 	return 0;
 }
 
+/* Checks if the fp is valid.  We always build signal frames which are
+ * 16-byte aligned, therefore we can always enforce that the restore
+ * frame has that property as well.
+ */
+static bool invalid_frame_pointer(void __user *fp, int fplen)
+{
+	if ((((unsigned long) fp) & 15) ||
+	    ((unsigned long)fp) > 0x100000000ULL - fplen)
+		return true;
+	return false;
+}
+
 void do_sigreturn32(struct pt_regs *regs)
 {
 	struct signal_frame32 __user *sf;
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
-	unsigned int psr;
+	unsigned int psr, ufp;
 	unsigned pc, npc;
 	sigset_t set;
 	unsigned seta[_COMPAT_NSIG_WORDS];
@@ -157,11 +169,16 @@ void do_sigreturn32(struct pt_regs *regs)
 	sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 3))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
+		goto segv;
+
+	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
 		goto segv;
 
-	if (get_user(pc, &sf->info.si_regs.pc) ||
+	if (__get_user(pc, &sf->info.si_regs.pc) ||
 	    __get_user(npc, &sf->info.si_regs.npc))
 		goto segv;
 
@@ -230,7 +247,7 @@ segv:
 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 {
 	struct rt_signal_frame32 __user *sf;
-	unsigned int psr, pc, npc;
+	unsigned int psr, pc, npc, ufp;
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
 	sigset_t set;
@@ -245,11 +262,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 	sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 3))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
 		goto segv;
 
-	if (get_user(pc, &sf->regs.pc) || 
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
+		goto segv;
+
+	if (__get_user(pc, &sf->regs.pc) || 
 	    __get_user(npc, &sf->regs.npc))
 		goto segv;
 
@@ -315,14 +337,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp, int fplen)
-{
-	if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
-		return 1;
-	return 0;
-}
-
 static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 7d5d8e1f8415..e751dbc527e2 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -59,10 +59,22 @@ struct rt_signal_frame {
 #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
 
+/* Checks if the fp is valid.  We always build signal frames which are
+ * 16-byte aligned, therefore we can always enforce that the restore
+ * frame has that property as well.
+ */
+static inline bool invalid_frame_pointer(void __user *fp, int fplen)
+{
+	if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
+		return true;
+
+	return false;
+}
+
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
+	unsigned long up_psr, pc, npc, ufp;
 	struct signal_frame __user *sf;
-	unsigned long up_psr, pc, npc;
 	sigset_t set;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
@@ -76,10 +88,13 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
 	sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
+	if (!invalid_frame_pointer(sf, sizeof(*sf)))
+		goto segv_and_exit;
+
+	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
 		goto segv_and_exit;
 
-	if (((unsigned long) sf) & 3)
+	if (ufp & 0x7)
 		goto segv_and_exit;
 
 	err = __get_user(pc,  &sf->info.si_regs.pc);
@@ -126,7 +141,7 @@ segv_and_exit:
 asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_signal_frame __user *sf;
-	unsigned int psr, pc, npc;
+	unsigned int psr, pc, npc, ufp;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
 	sigset_t set;
@@ -134,8 +149,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
 
 	synchronize_user_stack();
 	sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 0x03))
+	if (!invalid_frame_pointer(sf, sizeof(*sf)))
+		goto segv;
+
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
 		goto segv;
 
 	err = __get_user(pc, &sf->regs.pc);
@@ -177,15 +197,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static inline int invalid_frame_pointer(void __user *fp, int fplen)
-{
-	if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
-		return 1;
-
-	return 0;
-}
-
 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp = regs->u_regs[UREG_FP];
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 90f08055b7d2..5a2e50bcc3b8 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -226,6 +226,17 @@ do_sigsegv:
 	force_sig(SIGSEGV, current);
 }
 
+/* Checks if the fp is valid.  We always build rt signal frames which
+ * are 16-byte aligned, therefore we can always enforce that the
+ * restore frame has that property as well.
+ */
+static bool invalid_frame_pointer(void __user *fp)
+{
+	if (((unsigned long) fp) & 15)
+		return true;
+	return false;
+}
+
 struct rt_signal_frame {
 	struct sparc_stackf	ss;
 	siginfo_t		info;
@@ -238,8 +249,8 @@ struct rt_signal_frame {
 
 void do_rt_sigreturn(struct pt_regs *regs)
 {
+	unsigned long tpc, tnpc, tstate, ufp;
 	struct rt_signal_frame __user *sf;
-	unsigned long tpc, tnpc, tstate;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
 	sigset_t set;
@@ -253,10 +264,16 @@ void do_rt_sigreturn(struct pt_regs *regs)
 		(regs->u_regs [UREG_FP] + STACK_BIAS);
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (((unsigned long) sf) & 3)
+	if (invalid_frame_pointer(sf))
+		goto segv;
+
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
 		goto segv;
 
-	err = get_user(tpc, &sf->regs.tpc);
+	if ((ufp + STACK_BIAS) & 0x7)
+		goto segv;
+
+	err = __get_user(tpc, &sf->regs.tpc);
 	err |= __get_user(tnpc, &sf->regs.tnpc);
 	if (test_thread_flag(TIF_32BIT)) {
 		tpc &= 0xffffffff;
@@ -300,14 +317,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp)
-{
-	if (((unsigned long) fp) & 15)
-		return 1;
-	return 0;
-}
-
 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
index 0f6eebe71e6c..e5fe8cef9a69 100644
--- a/arch/sparc/kernel/sigutil_32.c
+++ b/arch/sparc/kernel/sigutil_32.c
@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 {
 	int err;
+
+	if (((unsigned long) fpu) & 3)
+		return -EFAULT;
+
 #ifdef CONFIG_SMP
 	if (test_tsk_thread_flag(current, TIF_USEDFPU))
 		regs->psr &= ~PSR_EF;
@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
 	struct thread_info *t = current_thread_info();
 	int i, wsaved, err;
 
-	__get_user(wsaved, &rp->wsaved);
+	if (((unsigned long) rp) & 3)
+		return -EFAULT;
+
+	get_user(wsaved, &rp->wsaved);
 	if (wsaved > NSWINS)
 		return -EFAULT;
 
diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
index 387834a9c56a..36aadcbeac69 100644
--- a/arch/sparc/kernel/sigutil_64.c
+++ b/arch/sparc/kernel/sigutil_64.c
@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 	unsigned long fprs;
 	int err;
 
-	err = __get_user(fprs, &fpu->si_fprs);
+	if (((unsigned long) fpu) & 7)
+		return -EFAULT;
+
+	err = get_user(fprs, &fpu->si_fprs);
 	fprs_write(0);
 	regs->tstate &= ~TSTATE_PEF;
 	if (fprs & FPRS_DL)
@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
 	struct thread_info *t = current_thread_info();
 	int i, wsaved, err;
 
-	__get_user(wsaved, &rp->wsaved);
+	if (((unsigned long) rp) & 7)
+		return -EFAULT;
+
+	get_user(wsaved, &rp->wsaved);
 	if (wsaved > NSWINS)
 		return -EFAULT;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 10/88] sparc64: Fix return from trap window fill crashes.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (8 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 09/88] sparc: Harden signal return frame checks Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 11/88] perf/x86: Honor the architectural performance monitoring version Jiri Slaby
                   ` (79 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, David S. Miller, Jiri Slaby

From: "David S. Miller" <davem@davemloft.net>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 7cafc0b8bf130f038b0ec2dcdd6a9de6dc59b65a ]

We must handle data access exception as well as memory address unaligned
exceptions from return from trap window fill faults, not just normal
TLB misses.

Otherwise we can get an OOPS that looks like this:

ld-linux.so.2(36808): Kernel bad sw trap 5 [#1]
CPU: 1 PID: 36808 Comm: ld-linux.so.2 Not tainted 4.6.0 #34
task: fff8000303be5c60 ti: fff8000301344000 task.ti: fff8000301344000
TSTATE: 0000004410001601 TPC: 0000000000a1a784 TNPC: 0000000000a1a788 Y: 00000002    Not tainted
TPC: <do_sparc64_fault+0x5c4/0x700>
g0: fff8000024fc8248 g1: 0000000000db04dc g2: 0000000000000000 g3: 0000000000000001
g4: fff8000303be5c60 g5: fff800030e672000 g6: fff8000301344000 g7: 0000000000000001
o0: 0000000000b95ee8 o1: 000000000000012b o2: 0000000000000000 o3: 0000000200b9b358
o4: 0000000000000000 o5: fff8000301344040 sp: fff80003013475c1 ret_pc: 0000000000a1a77c
RPC: <do_sparc64_fault+0x5bc/0x700>
l0: 00000000000007ff l1: 0000000000000000 l2: 000000000000005f l3: 0000000000000000
l4: fff8000301347e98 l5: fff8000024ff3060 l6: 0000000000000000 l7: 0000000000000000
i0: fff8000301347f60 i1: 0000000000102400 i2: 0000000000000000 i3: 0000000000000000
i4: 0000000000000000 i5: 0000000000000000 i6: fff80003013476a1 i7: 0000000000404d4c
I7: <user_rtt_fill_fixup+0x6c/0x7c>
Call Trace:
 [0000000000404d4c] user_rtt_fill_fixup+0x6c/0x7c

The window trap handlers are slightly clever, the trap table entries for them are
composed of two pieces of code.  First comes the code that actually performs
the window fill or spill trap handling, and then there are three instructions at
the end which are for exception processing.

The userland register window fill handler is:

	add	%sp, STACK_BIAS + 0x00, %g1;		\
	ldxa	[%g1 + %g0] ASI, %l0;			\
	mov	0x08, %g2;				\
	mov	0x10, %g3;				\
	ldxa	[%g1 + %g2] ASI, %l1;			\
	mov	0x18, %g5;				\
	ldxa	[%g1 + %g3] ASI, %l2;			\
	ldxa	[%g1 + %g5] ASI, %l3;			\
	add	%g1, 0x20, %g1;				\
	ldxa	[%g1 + %g0] ASI, %l4;			\
	ldxa	[%g1 + %g2] ASI, %l5;			\
	ldxa	[%g1 + %g3] ASI, %l6;			\
	ldxa	[%g1 + %g5] ASI, %l7;			\
	add	%g1, 0x20, %g1;				\
	ldxa	[%g1 + %g0] ASI, %i0;			\
	ldxa	[%g1 + %g2] ASI, %i1;			\
	ldxa	[%g1 + %g3] ASI, %i2;			\
	ldxa	[%g1 + %g5] ASI, %i3;			\
	add	%g1, 0x20, %g1;				\
	ldxa	[%g1 + %g0] ASI, %i4;			\
	ldxa	[%g1 + %g2] ASI, %i5;			\
	ldxa	[%g1 + %g3] ASI, %i6;			\
	ldxa	[%g1 + %g5] ASI, %i7;			\
	restored;					\
	retry; nop; nop; nop; nop;			\
	b,a,pt	%xcc, fill_fixup_dax;			\
	b,a,pt	%xcc, fill_fixup_mna;			\
	b,a,pt	%xcc, fill_fixup;

And the way this works is that if any of those memory accesses
generate an exception, the exception handler can revector to one of
those final three branch instructions depending upon which kind of
exception the memory access took.  In this way, the fault handler
doesn't have to know if it was a spill or a fill that it's handling
the fault for.  It just always branches to the last instruction in
the parent trap's handler.

For example, for a regular fault, the code goes:

winfix_trampoline:
	rdpr	%tpc, %g3
	or	%g3, 0x7c, %g3
	wrpr	%g3, %tnpc
	done

All window trap handlers are 0x80 aligned, so if we "or" 0x7c into the
trap time program counter, we'll get that final instruction in the
trap handler.

On return from trap, we have to pull the register window in but we do
this by hand instead of just executing a "restore" instruction for
several reasons.  The largest being that from Niagara and onward we
simply don't have enough levels in the trap stack to fully resolve all
possible exception cases of a window fault when we are already at
trap level 1 (which we enter to get ready to return from the original
trap).

This is executed inline via the FILL_*_RTRAP handlers.  rtrap_64.S's
code branches directly to these to do the window fill by hand if
necessary.  Now if you look at them, we'll see at the end:

	    ba,a,pt    %xcc, user_rtt_fill_fixup;
	    ba,a,pt    %xcc, user_rtt_fill_fixup;
	    ba,a,pt    %xcc, user_rtt_fill_fixup;

And oops, all three cases are handled like a fault.

This doesn't work because each of these trap types (data access
exception, memory address unaligned, and faults) store their auxiliary
info in different registers to pass on to the C handler which does the
real work.

So in the case where the stack was unaligned, the unaligned trap
handler sets up the arg registers one way, and then we branched to
the fault handler which expects them setup another way.

So the FAULT_TYPE_* value ends up basically being garbage, and
randomly would generate the backtrace seen above.

Reported-by: Nick Alcock <nix@esperi.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/sparc/include/asm/head_64.h |  4 ++
 arch/sparc/include/asm/ttable.h  |  8 ++--
 arch/sparc/kernel/Makefile       |  1 +
 arch/sparc/kernel/rtrap_64.S     | 57 ++++-------------------
 arch/sparc/kernel/urtt_fill.S    | 98 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 116 insertions(+), 52 deletions(-)
 create mode 100644 arch/sparc/kernel/urtt_fill.S

diff --git a/arch/sparc/include/asm/head_64.h b/arch/sparc/include/asm/head_64.h
index 10e9dabc4c41..f0700cfeedd7 100644
--- a/arch/sparc/include/asm/head_64.h
+++ b/arch/sparc/include/asm/head_64.h
@@ -15,6 +15,10 @@
 
 #define	PTREGS_OFF	(STACK_BIAS + STACKFRAME_SZ)
 
+#define	RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
+#define	RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
+#define RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
+
 #define __CHEETAH_ID	0x003e0014
 #define __JALAPENO_ID	0x003e0016
 #define __SERRANO_ID	0x003e0022
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
index 71b5a67522ab..781b9f1dbdc2 100644
--- a/arch/sparc/include/asm/ttable.h
+++ b/arch/sparc/include/asm/ttable.h
@@ -589,8 +589,8 @@ user_rtt_fill_64bit:					\
 	 restored;					\
 	nop; nop; nop; nop; nop; nop;			\
 	nop; nop; nop; nop; nop;			\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;
 
 
@@ -652,8 +652,8 @@ user_rtt_fill_32bit:					\
 	 restored;					\
 	nop; nop; nop; nop; nop;			\
 	nop; nop; nop;					\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;
 
 
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index d15cc1794b0e..a0977a201114 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
 CFLAGS_REMOVE_pcr.o := -pg
 endif
 
+obj-$(CONFIG_SPARC64)   += urtt_fill.o
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index afa2a9e3d0a0..5c0b0254580d 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -14,10 +14,6 @@
 #include <asm/visasm.h>
 #include <asm/processor.h>
 
-#define		RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
-#define		RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
-#define		RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
-
 		.text
 		.align			32
 __handle_preemption:
@@ -230,52 +226,17 @@ rt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
 		 wrpr			%g1, %cwp
 		ba,a,pt			%xcc, user_rtt_fill_64bit
 
-user_rtt_fill_fixup:
-		rdpr	%cwp, %g1
-		add	%g1, 1, %g1
-		wrpr	%g1, 0x0, %cwp
-
-		rdpr	%wstate, %g2
-		sll	%g2, 3, %g2
-		wrpr	%g2, 0x0, %wstate
-
-		/* We know %canrestore and %otherwin are both zero.  */
-
-		sethi	%hi(sparc64_kern_pri_context), %g2
-		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
-		mov	PRIMARY_CONTEXT, %g1
-
-661:		stxa	%g2, [%g1] ASI_DMMU
-		.section .sun4v_1insn_patch, "ax"
-		.word	661b
-		stxa	%g2, [%g1] ASI_MMU
-		.previous
-
-		sethi	%hi(KERNBASE), %g1
-		flush	%g1
+user_rtt_fill_fixup_dax:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 mov	1, %g3
 
-		or	%g4, FAULT_CODE_WINFIXUP, %g4
-		stb	%g4, [%g6 + TI_FAULT_CODE]
-		stx	%g5, [%g6 + TI_FAULT_ADDR]
+user_rtt_fill_fixup_mna:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 mov	2, %g3
 
-		mov	%g6, %l1
-		wrpr	%g0, 0x0, %tl
-
-661:		nop
-		.section		.sun4v_1insn_patch, "ax"
-		.word			661b
-		SET_GL(0)
-		.previous
-
-		wrpr	%g0, RTRAP_PSTATE, %pstate
-
-		mov	%l1, %g6
-		ldx	[%g6 + TI_TASK], %g4
-		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
-		call	do_sparc64_fault
-		 add	%sp, PTREGS_OFF, %o0
-		ba,pt	%xcc, rtrap
-		 nop
+user_rtt_fill_fixup:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 clr	%g3
 
 user_rtt_pre_restore:
 		add			%g1, 1, %g1
diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S
new file mode 100644
index 000000000000..5604a2b051d4
--- /dev/null
+++ b/arch/sparc/kernel/urtt_fill.S
@@ -0,0 +1,98 @@
+#include <asm/thread_info.h>
+#include <asm/trap_block.h>
+#include <asm/spitfire.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+
+		.text
+		.align	8
+		.globl	user_rtt_fill_fixup_common
+user_rtt_fill_fixup_common:
+		rdpr	%cwp, %g1
+		add	%g1, 1, %g1
+		wrpr	%g1, 0x0, %cwp
+
+		rdpr	%wstate, %g2
+		sll	%g2, 3, %g2
+		wrpr	%g2, 0x0, %wstate
+
+		/* We know %canrestore and %otherwin are both zero.  */
+
+		sethi	%hi(sparc64_kern_pri_context), %g2
+		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
+		mov	PRIMARY_CONTEXT, %g1
+
+661:		stxa	%g2, [%g1] ASI_DMMU
+		.section .sun4v_1insn_patch, "ax"
+		.word	661b
+		stxa	%g2, [%g1] ASI_MMU
+		.previous
+
+		sethi	%hi(KERNBASE), %g1
+		flush	%g1
+
+		mov	%g4, %l4
+		mov	%g5, %l5
+		brnz,pn	%g3, 1f
+		 mov	%g3, %l3
+
+		or	%g4, FAULT_CODE_WINFIXUP, %g4
+		stb	%g4, [%g6 + TI_FAULT_CODE]
+		stx	%g5, [%g6 + TI_FAULT_ADDR]
+1:
+		mov	%g6, %l1
+		wrpr	%g0, 0x0, %tl
+
+661:		nop
+		.section		.sun4v_1insn_patch, "ax"
+		.word			661b
+		SET_GL(0)
+		.previous
+
+		wrpr	%g0, RTRAP_PSTATE, %pstate
+
+		mov	%l1, %g6
+		ldx	[%g6 + TI_TASK], %g4
+		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
+
+		brnz,pn	%l3, 1f
+		 nop
+
+		call	do_sparc64_fault
+		 add	%sp, PTREGS_OFF, %o0
+		ba,pt	%xcc, rtrap
+		 nop
+
+1:		cmp	%g3, 2
+		bne,pn	%xcc, 2f
+		 nop
+
+		sethi	%hi(tlb_type), %g1
+		lduw	[%g1 + %lo(tlb_type)], %g1
+		cmp	%g1, 3
+		bne,pt	%icc, 1f
+		 add	%sp, PTREGS_OFF, %o0
+		mov	%l4, %o2
+		call	sun4v_do_mna
+		 mov	%l5, %o1
+		ba,a,pt	%xcc, rtrap
+1:		mov	%l4, %o1
+		mov	%l5, %o2
+		call	mem_address_unaligned
+		 nop
+		ba,a,pt	%xcc, rtrap
+
+2:		sethi	%hi(tlb_type), %g1
+		mov	%l4, %o1
+		lduw	[%g1 + %lo(tlb_type)], %g1
+		mov	%l5, %o2
+		cmp	%g1, 3
+		bne,pt	%icc, 1f
+		 add	%sp, PTREGS_OFF, %o0
+		call	sun4v_data_access_exception
+		 nop
+		ba,a,pt	%xcc, rtrap
+
+1:		call	spitfire_data_access_exception
+		 nop
+		ba,a,pt	%xcc, rtrap
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 11/88] perf/x86: Honor the architectural performance monitoring version
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (9 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 10/88] sparc64: Fix return from trap window fill crashes Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 12/88] perf/x86: Fix undefined shift on 32-bit kernels Jiri Slaby
                   ` (78 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Palik, Imre, Peter Zijlstra, Andrew Morton,
	Andy Lutomirski, Anthony Liguori, Arnaldo Carvalho de Melo,
	Borislav Petkov, Brian Gerst, Denys Vlasenko, H . Peter Anvin,
	Linus Torvalds, Oleg Nesterov, Paul Mackerras, Thomas Gleixner,
	Ingo Molnar, Kevin Christopher, Jiri Slaby

From: "Palik, Imre" <imrep@amazon.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 2c33645d366d13b969d936b68b9f4875b1fdddea upstream.

Architectural performance monitoring, version 1, doesn't support fixed counters.

Currently, even if a hypervisor advertises support for architectural
performance monitoring version 1, perf may still try to use the fixed
counters, as the constraints are set up based on the CPU model.

This patch ensures that perf honors the architectural performance monitoring
version returned by CPUID, and it only uses the fixed counters for version 2
and above.

(Some of the ideas in this patch came from Peter Zijlstra.)

Signed-off-by: Imre Palik <imrep@amazon.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Anthony Liguori <aliguori@amazon.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1433767609-1039-1-git-send-email-imrep.amz@gmail.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kevin Christopher <kevinc@vmware.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kernel/cpu/perf_event_intel.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 0c8fc76b2d2c..491d6813ea3f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2538,13 +2538,13 @@ __init int intel_pmu_init(void)
 		 * counter, so do not extend mask to generic counters
 		 */
 		for_each_event_constraint(c, x86_pmu.event_constraints) {
-			if (c->cmask != FIXED_EVENT_FLAGS
-			    || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
-				continue;
+			if (c->cmask == FIXED_EVENT_FLAGS
+			    && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) {
+				c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
 			}
-
-			c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
-			c->weight += x86_pmu.num_counters;
+			c->idxmsk64 &=
+				~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
+			c->weight = hweight64(c->idxmsk64);
 		}
 	}
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 12/88] perf/x86: Fix undefined shift on 32-bit kernels
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (10 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 11/88] perf/x86: Honor the architectural performance monitoring version Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 13/88] netlink: Fix dump skb leak/double free Jiri Slaby
                   ` (77 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Andrey Ryabinin, Peter Zijlstra,
	Alexander Shishkin, Arnaldo Carvalho de Melo, H . Peter Anvin,
	Imre Palik, Jiri Olsa, Linus Torvalds, Stephane Eranian,
	Thomas Gleixner, Vince Weaver, Ingo Molnar, Kevin Christopher,
	Jiri Slaby

From: Andrey Ryabinin <aryabinin@virtuozzo.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 6d6f2833bfbf296101f9f085e10488aef2601ba5 upstream.

Jim reported:

	UBSAN: Undefined behaviour in arch/x86/events/intel/core.c:3708:12
	shift exponent 35 is too large for 32-bit type 'long unsigned int'

The use of 'unsigned long' type obviously is not correct here, make it
'unsigned long long' instead.

Reported-by: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Imre Palik <imrep@amazon.de>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Fixes: 2c33645d366d ("perf/x86: Honor the architectural performance monitoring version")
Link: http://lkml.kernel.org/r/1462974711-10037-1-git-send-email-aryabinin@virtuozzo.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kevin Christopher <kevinc@vmware.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kernel/cpu/perf_event_intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 491d6813ea3f..04e7df068f0e 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2543,7 +2543,7 @@ __init int intel_pmu_init(void)
 				c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
 			}
 			c->idxmsk64 &=
-				~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
+				~(~0ULL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
 			c->weight = hweight64(c->idxmsk64);
 		}
 	}
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 13/88] netlink: Fix dump skb leak/double free
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (11 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 12/88] perf/x86: Fix undefined shift on 32-bit kernels Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 14/88] udp: prevent skbs lingering in tunnel socket queues Jiri Slaby
                   ` (76 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Herbert Xu, David S . Miller, Jiri Slaby

From: Herbert Xu <herbert@gondor.apana.org.au>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 92964c79b357efd980812c4de5c1fd2ec8bb5520 ]

When we free cb->skb after a dump, we do it after releasing the
lock.  This means that a new dump could have started in the time
being and we'll end up freeing their skb instead of ours.

This patch saves the skb and module before we unlock so we free
the right memory.

Fixes: 16b304f3404f ("netlink: Eliminate kmalloc in netlink dump operation.")
Reported-by: Baozeng Ding <sploving1@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/netlink/af_netlink.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 10805856dfba..bb04abe72d76 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2658,6 +2658,7 @@ static int netlink_dump(struct sock *sk)
 	struct netlink_callback *cb;
 	struct sk_buff *skb = NULL;
 	struct nlmsghdr *nlh;
+	struct module *module;
 	int len, err = -ENOBUFS;
 	int alloc_size;
 
@@ -2707,9 +2708,11 @@ static int netlink_dump(struct sock *sk)
 		cb->done(cb);
 
 	nlk->cb_running = false;
+	module = cb->module;
+	skb = cb->skb;
 	mutex_unlock(nlk->cb_mutex);
-	module_put(cb->module);
-	consume_skb(cb->skb);
+	module_put(module);
+	consume_skb(skb);
 	return 0;
 
 errout_skb:
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 14/88] udp: prevent skbs lingering in tunnel socket queues
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (12 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 13/88] netlink: Fix dump skb leak/double free Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 15/88] tcp: record TLP and ER timer stats in v6 stats Jiri Slaby
                   ` (75 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Hannes Frederic Sowa, David S . Miller, Jiri Slaby

From: Hannes Frederic Sowa <hannes@stressinduktion.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit e5aed006be918af163eb397e45aa5ea6cefd5e01 ]

In case we find a socket with encapsulation enabled we should call
the encap_recv function even if just a udp header without payload is
available. The callbacks are responsible for correctly verifying and
dropping the packets.

Also, in case the header validation fails for geneve and vxlan we
shouldn't put the skb back into the socket queue, no one will pick
them up there.  Instead we can simply discard them in the respective
encap_recv functions.

[js] 3.12 does not have geneve yet.

Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/vxlan.c | 8 ++------
 net/ipv4/udp.c      | 2 +-
 net/ipv6/udp.c      | 2 +-
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index c8e333306c4c..73790abf0c2a 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1037,7 +1037,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
 	/* Need Vxlan and inner Ethernet header to be present */
 	if (!pskb_may_pull(skb, VXLAN_HLEN))
-		goto error;
+		goto drop;
 
 	/* Return packets with reserved bits set */
 	vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
@@ -1045,7 +1045,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 	    (vxh->vx_vni & htonl(0xff))) {
 		netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
 			   ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
-		goto error;
+		goto drop;
 	}
 
 	if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
@@ -1073,10 +1073,6 @@ drop:
 	/* Consume bad packet */
 	kfree_skb(skb);
 	return 0;
-
-error:
-	/* Return non vxlan pkt */
-	return 1;
 }
 
 static void vxlan_rcv(struct vxlan_sock *vs,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f904b644a40c..a5d71c65ea30 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1469,7 +1469,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 		/* if we're overly short, let UDP handle it */
 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
-		if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
+		if (encap_rcv != NULL) {
 			int ret;
 
 			ret = encap_rcv(sk, skb);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 26e1648ca228..b9188e157227 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -607,7 +607,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 		/* if we're overly short, let UDP handle it */
 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
-		if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
+		if (encap_rcv != NULL) {
 			int ret;
 
 			ret = encap_rcv(sk, skb);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 15/88] tcp: record TLP and ER timer stats in v6 stats
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (13 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 14/88] udp: prevent skbs lingering in tunnel socket queues Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 16/88] ipv6: Skip XFRM lookup if dst_entry in socket cache is valid Jiri Slaby
                   ` (74 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Yuchung Cheng, Neal Cardwell, David S . Miller, Jiri Slaby

From: Yuchung Cheng <ycheng@google.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit ce3cf4ec0305919fc69a972f6c2b2efd35d36abc ]

The v6 tcp stats scan do not provide TLP and ER timer information
correctly like the v4 version . This patch fixes that.

Fixes: 6ba8a3b19e76 ("tcp: Tail loss probe (TLP)")
Fixes: eed530b6c676 ("tcp: early retransmit")
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv6/tcp_ipv6.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7138ee87e07c..5ed4579f8212 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1776,7 +1776,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
 	destp = ntohs(inet->inet_dport);
 	srcp  = ntohs(inet->inet_sport);
 
-	if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
+	if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
+	    icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
+	    icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
 		timer_active	= 1;
 		timer_expires	= icsk->icsk_timeout;
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 16/88] ipv6: Skip XFRM lookup if dst_entry in socket cache is valid
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (14 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 15/88] tcp: record TLP and ER timer stats in v6 stats Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 17/88] macintosh/therm_windtunnel: Export I2C module alias information Jiri Slaby
                   ` (73 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Jakub Sitnicki, David S . Miller, Jiri Slaby

From: Jakub Sitnicki <jkbs@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 00bc0ef5880dc7b82f9c320dead4afaad48e47be ]

At present we perform an xfrm_lookup() for each UDPv6 message we
send. The lookup involves querying the flow cache (flow_cache_lookup)
and, in case of a cache miss, creating an XFRM bundle.

If we miss the flow cache, we can end up creating a new bundle and
deriving the path MTU (xfrm_init_pmtu) from on an already transformed
dst_entry, which we pass from the socket cache (sk->sk_dst_cache) down
to xfrm_lookup(). This can happen only if we're caching the dst_entry
in the socket, that is when we're using a connected UDP socket.

To put it another way, the path MTU shrinks each time we miss the flow
cache, which later on leads to incorrectly fragmented payload. It can
be observed with ESPv6 in transport mode:

  1) Set up a transformation and lower the MTU to trigger fragmentation
    # ip xfrm policy add dir out src ::1 dst ::1 \
      tmpl src ::1 dst ::1 proto esp spi 1
    # ip xfrm state add src ::1 dst ::1 \
      proto esp spi 1 enc 'aes' 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
    # ip link set dev lo mtu 1500

  2) Monitor the packet flow and set up an UDP sink
    # tcpdump -ni lo -ttt &
    # socat udp6-listen:12345,fork /dev/null &

  3) Send a datagram that needs fragmentation with a connected socket
    # perl -e 'print "@" x 1470 | socat - udp6:[::1]:12345
    2016/06/07 18:52:52 socat[724] E read(3, 0x555bb3d5ba00, 8192): Protocol error
    00:00:00.000000 IP6 ::1 > ::1: frag (0|1448) ESP(spi=0x00000001,seq=0x2), length 1448
    00:00:00.000014 IP6 ::1 > ::1: frag (1448|32)
    00:00:00.000050 IP6 ::1 > ::1: ESP(spi=0x00000001,seq=0x3), length 1272
    (^ ICMPv6 Parameter Problem)
    00:00:00.000022 IP6 ::1 > ::1: ESP(spi=0x00000001,seq=0x5), length 136

  4) Compare it to a non-connected socket
    # perl -e 'print "@" x 1500' | socat - udp6-sendto:[::1]:12345
    00:00:40.535488 IP6 ::1 > ::1: frag (0|1448) ESP(spi=0x00000001,seq=0x6), length 1448
    00:00:00.000010 IP6 ::1 > ::1: frag (1448|64)

What happens in step (3) is:

  1) when connecting the socket in __ip6_datagram_connect(), we
     perform an XFRM lookup, miss the flow cache, create an XFRM
     bundle, and cache the destination,

  2) afterwards, when sending the datagram, we perform an XFRM lookup,
     again, miss the flow cache (due to mismatch of flowi6_iif and
     flowi6_oif, which is an issue of its own), and recreate an XFRM
     bundle based on the cached (and already transformed) destination.

To prevent the recreation of an XFRM bundle, avoid an XFRM lookup
altogether whenever we already have a destination entry cached in the
socket. This prevents the path MTU shrinkage and brings us on par with
UDPv4.

The fix also benefits connected PINGv6 sockets, another user of
ip6_sk_dst_lookup_flow(), who also suffer messages being transformed
twice.

Joint work with Hannes Frederic Sowa.

Reported-by: Jan Tluka <jtluka@redhat.com>
Signed-off-by: Jakub Sitnicki <jkbs@redhat.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv6/ip6_output.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 8b144bf50189..f5f86850a305 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1018,19 +1018,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
 					 bool can_sleep)
 {
 	struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
-	int err;
 
 	dst = ip6_sk_dst_check(sk, dst, fl6);
+	if (!dst)
+		dst = ip6_dst_lookup_flow(sk, fl6, final_dst, can_sleep);
 
-	err = ip6_dst_lookup_tail(sk, &dst, fl6);
-	if (err)
-		return ERR_PTR(err);
-	if (final_dst)
-		fl6->daddr = *final_dst;
-	if (can_sleep)
-		fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
-
-	return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
+	return dst;
 }
 EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 17/88] macintosh/therm_windtunnel: Export I2C module alias information
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (15 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 16/88] ipv6: Skip XFRM lookup if dst_entry in socket cache is valid Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 18/88] drivers: macintosh: rack-meter: limit idle ticks to total ticks Jiri Slaby
                   ` (72 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Javier Martinez Canillas, Michael Ellerman,
	Oliver Neukum, Jiri Slaby

From: Javier Martinez Canillas <javier@osg.samsung.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit cb0eefcc3271ea1d370476dd29685918b99c5a9f upstream.

The I2C core always reports the MODALIAS uevent as "i2c:<client name"
regardless if the driver was matched using the I2C id_table or the
of_match_table. So the driver needs to export the I2C table and this
be built into the module or udev won't have the necessary information
to auto load the correct module when the device is added.

Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/macintosh/therm_windtunnel.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 3b4a157714b1..b40ed32379ec 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -408,6 +408,7 @@ static const struct i2c_device_id therm_windtunnel_id[] = {
 	{ "therm_adm1030", adm1030 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id);
 
 static int
 do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 18/88] drivers: macintosh: rack-meter: limit idle ticks to total ticks
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (16 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 17/88] macintosh/therm_windtunnel: Export I2C module alias information Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 19/88] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS Jiri Slaby
                   ` (71 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Aaro Koskinen, Michael Ellerman, Oliver Neukum, Jiri Slaby

From: Aaro Koskinen <aaro.koskinen@iki.fi>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit c796d1d97c3035cf54d4d5a9e75abd094db80e76 upstream.

Limit idle ticks to total ticks. This prevents the annoying rackmeter
leds fully ON / OFF blinking state that happens on fully idling
G5 Xserve systems.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/macintosh/rack-meter.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
index cad0e19b47a2..0b569da3c467 100644
--- a/drivers/macintosh/rack-meter.c
+++ b/drivers/macintosh/rack-meter.c
@@ -225,6 +225,7 @@ static void rackmeter_do_timer(struct work_struct *work)
 
 	total_idle_ticks = get_cpu_idle_time(cpu);
 	idle_ticks = (unsigned int) (total_idle_ticks - rcpu->prev_idle);
+	idle_ticks = min(idle_ticks, total_ticks);
 	rcpu->prev_idle = total_idle_ticks;
 
 	/* We do a very dumb calculation to update the LEDs for now,
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 19/88] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (17 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 18/88] drivers: macintosh: rack-meter: limit idle ticks to total ticks Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 20/88] ARM: fix PTRACE_SETVFPREGS on SMP systems Jiri Slaby
                   ` (70 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Paolo Bonzini, Radim Krčmář, Jiri Slaby

From: Paolo Bonzini <pbonzini@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d14bdb553f9196169f003058ae1cdabe514470e6 upstream.

MOV to DR6 or DR7 causes a #GP if an attempt is made to write a 1 to
any of bits 63:32.  However, this is not detected at KVM_SET_DEBUGREGS
time, and the next KVM_RUN oopses:

   general protection fault: 0000 [#1] SMP
   CPU: 2 PID: 14987 Comm: a.out Not tainted 4.4.9-300.fc23.x86_64 #1
   Hardware name: LENOVO 2325F51/2325F51, BIOS G2ET32WW (1.12 ) 05/30/2012
   [...]
   Call Trace:
    [<ffffffffa072c93d>] kvm_arch_vcpu_ioctl_run+0x141d/0x14e0 [kvm]
    [<ffffffffa071405d>] kvm_vcpu_ioctl+0x33d/0x620 [kvm]
    [<ffffffff81241648>] do_vfs_ioctl+0x298/0x480
    [<ffffffff812418a9>] SyS_ioctl+0x79/0x90
    [<ffffffff817a0f2e>] entry_SYSCALL_64_fastpath+0x12/0x71
   Code: 55 83 ff 07 48 89 e5 77 27 89 ff ff 24 fd 90 87 80 81 0f 23 fe 5d c3 0f 23 c6 5d c3 0f 23 ce 5d c3 0f 23 d6 5d c3 0f 23 de 5d c3 <0f> 23 f6 5d c3 0f 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
   RIP  [<ffffffff810639eb>] native_set_debugreg+0x2b/0x40
    RSP <ffff88005836bd50>

Testcase (beautified/reduced from syzkaller output):

    #include <unistd.h>
    #include <sys/syscall.h>
    #include <string.h>
    #include <stdint.h>
    #include <linux/kvm.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>

    long r[8];

    int main()
    {
        struct kvm_debugregs dr = { 0 };

        r[2] = open("/dev/kvm", O_RDONLY);
        r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
        r[4] = ioctl(r[3], KVM_CREATE_VCPU, 7);

        memcpy(&dr,
               "\x5d\x6a\x6b\xe8\x57\x3b\x4b\x7e\xcf\x0d\xa1\x72"
               "\xa3\x4a\x29\x0c\xfc\x6d\x44\x00\xa7\x52\xc7\xd8"
               "\x00\xdb\x89\x9d\x78\xb5\x54\x6b\x6b\x13\x1c\xe9"
               "\x5e\xd3\x0e\x40\x6f\xb4\x66\xf7\x5b\xe3\x36\xcb",
               48);
        r[7] = ioctl(r[4], KVM_SET_DEBUGREGS, &dr);
        r[6] = ioctl(r[4], KVM_RUN, 0);
    }

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kvm/x86.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e0c859e1999a..06b37a671b12 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3009,6 +3009,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
 	if (dbgregs->flags)
 		return -EINVAL;
 
+	if (dbgregs->dr6 & ~0xffffffffull)
+		return -EINVAL;
+	if (dbgregs->dr7 & ~0xffffffffull)
+		return -EINVAL;
+
 	memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
 	vcpu->arch.dr6 = dbgregs->dr6;
 	vcpu->arch.dr7 = dbgregs->dr7;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 20/88] ARM: fix PTRACE_SETVFPREGS on SMP systems
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (18 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 19/88] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 21/88] powerpc: Fix definition of SIAR and SDAR registers Jiri Slaby
                   ` (69 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Russell King, Jiri Slaby

From: Russell King <rmk+kernel@armlinux.org.uk>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e2dfb4b880146bfd4b6aa8e138c0205407cebbaf upstream.

PTRACE_SETVFPREGS fails to properly mark the VFP register set to be
reloaded, because it undoes one of the effects of vfp_flush_hwstate().

Specifically vfp_flush_hwstate() sets thread->vfpstate.hard.cpu to
an invalid CPU number, but vfp_set() overwrites this with the original
CPU number, thereby rendering the hardware state as apparently "valid",
even though the software state is more recent.

Fix this by reverting the previous change.

Fixes: 8130b9d7b9d8 ("ARM: 7308/1: vfp: flush thread hwstate before copying ptrace registers")
Acked-by: Will Deacon <will.deacon@arm.com>
Tested-by: Simon Marchi <simon.marchi@ericsson.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/arm/kernel/ptrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 0dd3b79b15c3..ec33df500f86 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
 	if (ret)
 		return ret;
 
-	vfp_flush_hwstate(thread);
 	thread->vfpstate.hard = new_vfp;
+	vfp_flush_hwstate(thread);
 
 	return 0;
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 21/88] powerpc: Fix definition of SIAR and SDAR registers
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (19 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 20/88] ARM: fix PTRACE_SETVFPREGS on SMP systems Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 22/88] powerpc: Use privileged SPR number for MMCR2 Jiri Slaby
                   ` (68 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Thomas Huth, Michael Ellerman, Jiri Slaby

From: Thomas Huth <thuth@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d23fac2b27d94aeb7b65536a50d32bfdc21fe01e upstream.

The SIAR and SDAR registers are available twice, one time as SPRs
780 / 781 (unprivileged, but read-only), and one time as the SPRs
796 / 797 (privileged, but read and write). The Linux kernel code
currently uses the unprivileged  SPRs - while this is OK for reading,
writing to that register of course does not work.
Since the KVM code tries to write to this register, too (see the mtspr
in book3s_hv_rmhandlers.S), the contents of this register sometimes get
lost for the guests, e.g. during migration of a VM.
To fix this issue, simply switch to the privileged SPR numbers instead.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/include/asm/reg.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 3ce6b7b5ca19..ad261d56ae39 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -681,13 +681,13 @@
 #define SPRN_PMC6	792
 #define SPRN_PMC7	793
 #define SPRN_PMC8	794
-#define SPRN_SIAR	780
-#define SPRN_SDAR	781
 #define SPRN_SIER	784
 #define   SIER_SIPR		0x2000000	/* Sampled MSR_PR */
 #define   SIER_SIHV		0x1000000	/* Sampled MSR_HV */
 #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
 #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
+#define SPRN_SIAR	796
+#define SPRN_SDAR	797
 
 /* When EBB is enabled, some of MMCR0/MMCR2/SIER are user accessible */
 #define MMCR0_USER_MASK	(MMCR0_FC | MMCR0_PMXE | MMCR0_PMAO)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 22/88] powerpc: Use privileged SPR number for MMCR2
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (20 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 21/88] powerpc: Fix definition of SIAR and SDAR registers Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 23/88] parisc: Fix pagefault crash in unaligned __get_user() call Jiri Slaby
                   ` (67 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Thomas Huth, Michael Ellerman, Jiri Slaby

From: Thomas Huth <thuth@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8dd75ccb571f3c92c48014b3dabd3d51a115ab41 upstream.

We are already using the privileged versions of MMCR0, MMCR1
and MMCRA in the kernel, so for MMCR2, we should better use
the privileged versions, too, to be consistent.

Fixes: 240686c13687 ("powerpc: Initialise PMU related regs on Power8")
Suggested-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/include/asm/reg.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index ad261d56ae39..53762dbf547c 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -647,7 +647,7 @@
 #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
 #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
 #define SPRN_MMCR1	798
-#define SPRN_MMCR2	769
+#define SPRN_MMCR2	785
 #define SPRN_MMCRA	0x312
 #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
 #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 23/88] parisc: Fix pagefault crash in unaligned __get_user() call
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (21 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 22/88] powerpc: Use privileged SPR number for MMCR2 Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 24/88] ecryptfs: forbid opening files without mmap handler Jiri Slaby
                   ` (66 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Helge Deller, Jiri Slaby

From: Helge Deller <deller@gmx.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8b78f260887df532da529f225c49195d18fef36b upstream.

One of the debian buildd servers had this crash in the syslog without
any other information:

 Unaligned handler failed, ret = -2
 clock_adjtime (pid 22578): Unaligned data reference (code 28)
 CPU: 1 PID: 22578 Comm: clock_adjtime Tainted: G  E  4.5.0-2-parisc64-smp #1 Debian 4.5.4-1
 task: 000000007d9960f8 ti: 00000001bde7c000 task.ti: 00000001bde7c000

      YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
 PSW: 00001000000001001111100000001111 Tainted: G            E
 r00-03  000000ff0804f80f 00000001bde7c2b0 00000000402d2be8 00000001bde7c2b0
 r04-07  00000000409e1fd0 00000000fa6f7fff 00000001bde7c148 00000000fa6f7fff
 r08-11  0000000000000000 00000000ffffffff 00000000fac9bb7b 000000000002b4d4
 r12-15  000000000015241c 000000000015242c 000000000000002d 00000000fac9bb7b
 r16-19  0000000000028800 0000000000000001 0000000000000070 00000001bde7c218
 r20-23  0000000000000000 00000001bde7c210 0000000000000002 0000000000000000
 r24-27  0000000000000000 0000000000000000 00000001bde7c148 00000000409e1fd0
 r28-31  0000000000000001 00000001bde7c320 00000001bde7c350 00000001bde7c218
 sr00-03  0000000001200000 0000000001200000 0000000000000000 0000000001200000
 sr04-07  0000000000000000 0000000000000000 0000000000000000 0000000000000000

 IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000402d2e84 00000000402d2e88
  IIR: 0ca0d089    ISR: 0000000001200000  IOR: 00000000fa6f7fff
  CPU:        1   CR30: 00000001bde7c000 CR31: ffffffffffffffff
  ORIG_R28: 00000002369fe628
  IAOQ[0]: compat_get_timex+0x2dc/0x3c0
  IAOQ[1]: compat_get_timex+0x2e0/0x3c0
  RP(r2): compat_get_timex+0x40/0x3c0
 Backtrace:
  [<00000000402d4608>] compat_SyS_clock_adjtime+0x40/0xc0
  [<0000000040205024>] syscall_exit+0x0/0x14

This means the userspace program clock_adjtime called the clock_adjtime()
syscall and then crashed inside the compat_get_timex() function.
Syscalls should never crash programs, but instead return EFAULT.

The IIR register contains the executed instruction, which disassebles
into "ldw 0(sr3,r5),r9".
This load-word instruction is part of __get_user() which tried to read the word
at %r5/IOR (0xfa6f7fff). This means the unaligned handler jumped in.  The
unaligned handler is able to emulate all ldw instructions, but it fails if it
fails to read the source e.g. because of page fault.

The following program reproduces the problem:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>

int main(void) {
        /* allocate 8k */
        char *ptr = mmap(NULL, 2*4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
        /* free second half (upper 4k) and make it invalid. */
        munmap(ptr+4096, 4096);
        /* syscall where first int is unaligned and clobbers into invalid memory region */
        /* syscall should return EFAULT */
        return syscall(__NR_clock_adjtime, 0, ptr+4095);
}

To fix this issue we simply need to check if the faulting instruction address
is in the exception fixup table when the unaligned handler failed. If it
is, call the fixup routine instead of crashing.

While looking at the unaligned handler I found another issue as well: The
target register should not be modified if the handler was unsuccessful.

Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/parisc/kernel/unaligned.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index d7c0acb35ec2..8d49614d600d 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
 		break;
 	}
 
-	if (modify && R1(regs->iir))
+	if (ret == 0 && modify && R1(regs->iir))
 		regs->gr[R1(regs->iir)] = newbase;
 
 
@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)
 
 	if (ret)
 	{
+		/*
+		 * The unaligned handler failed.
+		 * If we were called by __get_user() or __put_user() jump
+		 * to it's exception fixup handler instead of crashing.
+		 */
+		if (!user_mode(regs) && fixup_exception(regs))
+			return;
+
 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
 		die_if_kernel("Unaligned data reference", regs, 28);
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 24/88] ecryptfs: forbid opening files without mmap handler
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (22 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 23/88] parisc: Fix pagefault crash in unaligned __get_user() call Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
       [not found]   ` <20160716192134.72132405@desktop.jensen.local>
  2016-07-14  8:15 ` [PATCH 3.12 25/88] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Jiri Slaby
                   ` (65 subsequent siblings)
  89 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Jann Horn, Linus Torvalds, Jiri Slaby

From: Jann Horn <jannh@google.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 2f36db71009304b3f0b95afacd8eba1f9f046b87 upstream.

This prevents users from triggering a stack overflow through a recursive
invocation of pagefault handling that involves mapping procfs files into
virtual memory.

Signed-off-by: Jann Horn <jannh@google.com>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 fs/ecryptfs/kthread.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index f1ea610362c6..9b661a4ccee7 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mount.h>
+#include <linux/file.h>
 #include "ecryptfs_kernel.h"
 
 struct ecryptfs_open_req {
@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
 	flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
 	(*lower_file) = dentry_open(&req.path, flags, cred);
 	if (!IS_ERR(*lower_file))
-		goto out;
+		goto have_file;
 	if ((flags & O_ACCMODE) == O_RDONLY) {
 		rc = PTR_ERR((*lower_file));
 		goto out;
@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct file **lower_file,
 	mutex_unlock(&ecryptfs_kthread_ctl.mux);
 	wake_up(&ecryptfs_kthread_ctl.wait);
 	wait_for_completion(&req.done);
-	if (IS_ERR(*lower_file))
+	if (IS_ERR(*lower_file)) {
 		rc = PTR_ERR(*lower_file);
+		goto out;
+	}
+have_file:
+	if ((*lower_file)->f_op->mmap == NULL) {
+		fput(*lower_file);
+		*lower_file = NULL;
+		rc = -EMEDIUMTYPE;
+	}
 out:
 	return rc;
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 25/88] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (23 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 24/88] ecryptfs: forbid opening files without mmap handler Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 26/88] fix d_walk()/non-delayed __d_free() race Jiri Slaby
                   ` (64 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Prasun Maiti, Ujjal Roy, Johannes Berg, Jiri Slaby

From: Prasun Maiti <prasunmaiti87@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.

iwpriv app uses iw_point structure to send data to Kernel. The iw_point
structure holds a pointer. For compatibility Kernel converts the pointer
as required for WEXT IOCTLs (SIOCIWFIRST to SIOCIWLAST). Some drivers
may use iw_handler_def.private_args to populate iwpriv commands instead
of iw_handler_def.private. For those case, the IOCTLs from
SIOCIWFIRSTPRIV to SIOCIWLASTPRIV will follow the path ndo_do_ioctl().
Accordingly when the filled up iw_point structure comes from 32 bit
iwpriv to 64 bit Kernel, Kernel will not convert the pointer and sends
it to driver. So, the driver may get the invalid data.

The pointer conversion for the IOCTLs (SIOCIWFIRSTPRIV to
SIOCIWLASTPRIV), which follow the path ndo_do_ioctl(), is mandatory.
This patch adds pointer conversion from 32 bit to 64 bit and vice versa,
if the ioctl comes from 32 bit iwpriv to 64 bit Kernel.

Signed-off-by: Prasun Maiti <prasunmaiti87@gmail.com>
Signed-off-by: Ujjal Roy <royujjal@gmail.com>
Tested-by: Dibyajyoti Ghosh <dibyajyotig@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/wireless/wext-core.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 87dd619fb2e9..1c9a505b7019 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -954,8 +954,29 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
 			return private(dev, iwr, cmd, info, handler);
 	}
 	/* Old driver API : call driver ioctl handler */
-	if (dev->netdev_ops->ndo_do_ioctl)
-		return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
+	if (dev->netdev_ops->ndo_do_ioctl) {
+#ifdef CONFIG_COMPAT
+		if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+			int ret = 0;
+			struct iwreq iwr_lcl;
+			struct compat_iw_point *iwp_compat = (void *) &iwr->u.data;
+
+			memcpy(&iwr_lcl, iwr, sizeof(struct iwreq));
+			iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer);
+			iwr_lcl.u.data.length = iwp_compat->length;
+			iwr_lcl.u.data.flags = iwp_compat->flags;
+
+			ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd);
+
+			iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer);
+			iwp_compat->length = iwr_lcl.u.data.length;
+			iwp_compat->flags = iwr_lcl.u.data.flags;
+
+			return ret;
+		} else
+#endif
+			return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
+	}
 	return -EOPNOTSUPP;
 }
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 26/88] fix d_walk()/non-delayed __d_free() race
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (24 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 25/88] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 27/88] netfilter: x_tables: don't move to non-existent next rule Jiri Slaby
                   ` (63 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Al Viro, Jiri Slaby

From: Al Viro <viro@zeniv.linux.org.uk>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 3d56c25e3bb0726a5c5e16fc2d9e38f8ed763085 upstream.

Ascend-to-parent logics in d_walk() depends on all encountered child
dentries not getting freed without an RCU delay.  Unfortunately, in
quite a few cases it is not true, with hard-to-hit oopsable race as
the result.

Fortunately, the fix is simiple; right now the rule is "if it ever
been hashed, freeing must be delayed" and changing it to "if it
ever had a parent, freeing must be delayed" closes that hole and
covers all cases the old rule used to cover.  Moreover, pipes and
sockets remain _not_ covered, so we do not introduce RCU delay in
the cases which are the reason for having that delay conditional
in the first place.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 fs/dcache.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index 40bf046884b1..9befdcea22fa 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1529,7 +1529,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
 	struct dentry *dentry = __d_alloc(parent->d_sb, name);
 	if (!dentry)
 		return NULL;
-
+	dentry->d_flags |= DCACHE_RCUACCESS;
 	spin_lock(&parent->d_lock);
 	/*
 	 * don't need child lock because it is not subject
@@ -2319,7 +2319,6 @@ static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
 {
 	BUG_ON(!d_unhashed(entry));
 	hlist_bl_lock(b);
-	entry->d_flags |= DCACHE_RCUACCESS;
 	hlist_bl_add_head_rcu(&entry->d_hash, b);
 	hlist_bl_unlock(b);
 }
@@ -2503,6 +2502,7 @@ static void __d_move(struct dentry * dentry, struct dentry * target)
 
 	/* ... and switch the parents */
 	if (IS_ROOT(dentry)) {
+		dentry->d_flags |= DCACHE_RCUACCESS;
 		dentry->d_parent = target->d_parent;
 		target->d_parent = target;
 		INIT_LIST_HEAD(&target->d_child);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 27/88] netfilter: x_tables: don't move to non-existent next rule
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (25 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 26/88] fix d_walk()/non-delayed __d_free() race Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps Jiri Slaby
                   ` (62 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit f24e230d257af1ad7476c6e81a8dc3127a74204e upstream.

Ben Hawkes says:

 In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it
 is possible for a user-supplied ipt_entry structure to have a large
 next_offset field. This field is not bounds checked prior to writing a
 counter value at the supplied offset.

Base chains enforce absolute verdict.

User defined chains are supposed to end with an unconditional return,
xtables userspace adds them automatically.

But if such return is missing we will move to non-existent next rule.

Reported-by: Ben Hawkes <hawkes@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/netfilter/arp_tables.c | 8 +++++---
 net/ipv4/netfilter/ip_tables.c  | 4 ++++
 net/ipv6/netfilter/ip6_tables.c | 4 ++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 456fc6efe05d..7460b7bef3ab 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -430,6 +430,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 				size = e->next_offset;
 				e = (struct arpt_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -452,6 +454,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
 				e = (struct arpt_entry *)
 					(entry0 + newpos);
@@ -675,10 +679,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
 		}
 	}
 
-	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
-		duprintf("Looping hook\n");
+	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
 		return -ELOOP;
-	}
 
 	/* Finally, each sanity check must pass */
 	i = 0;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a5bd3c8eee84..8fc22eed9603 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -511,6 +511,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
 				size = e->next_offset;
 				e = (struct ipt_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -532,6 +534,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
 				e = (struct ipt_entry *)
 					(entry0 + newpos);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index fb8a146abed8..63f7876c4f29 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -521,6 +521,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
 				size = e->next_offset;
 				e = (struct ip6t_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -542,6 +544,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
 				e = (struct ip6t_entry *)
 					(entry0 + newpos);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (26 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 27/88] netfilter: x_tables: don't move to non-existent next rule Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-21  6:36   ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 29/88] netfilter: x_tables: add and use xt_check_entry_offsets Jiri Slaby
                   ` (61 subsequent siblings)
  89 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 36472341017529e2b12573093cc0f68719300997 upstream.

When we see a jump also check that the offset gets us to beginning of
a rule (an ipt_entry).

The extra overhead is negible, even with absurd cases.

300k custom rules, 300k jumps to 'next' user chain:
[ plus one jump from INPUT to first userchain ]:

Before:
real    0m24.874s
user    0m7.532s
sys     0m16.076s

After:
real    0m27.464s
user    0m7.436s
sys     0m18.840s

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/netfilter/arp_tables.c | 17 +++++++++++++++++
 net/ipv4/netfilter/ip_tables.c  | 17 +++++++++++++++++
 net/ipv6/netfilter/ip6_tables.c | 17 +++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7460b7bef3ab..473ec559ce7b 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -358,6 +358,19 @@ static inline bool unconditional(const struct arpt_entry *e)
 	       memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
 }
 
+static bool find_jump_target(const struct xt_table_info *t,
+			     const void *entry0,
+			     const struct arpt_entry *target)
+{
+	struct arpt_entry *iter;
+
+	xt_entry_foreach(iter, entry0, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
+}
+
 /* Figures out from what hook each rule can be called: returns 0 if
  * there are loops.  Puts hook bitmask in comefrom.
  */
@@ -451,6 +464,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct arpt_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, entry0, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 8fc22eed9603..dba9d8070d07 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -434,6 +434,19 @@ ipt_do_table(struct sk_buff *skb,
 #endif
 }
 
+static bool find_jump_target(const struct xt_table_info *t,
+			     const void *entry0,
+			     const struct ipt_entry *target)
+{
+	struct ipt_entry *iter;
+
+	xt_entry_foreach(iter, entry0, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
+}
+
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -531,6 +544,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct ipt_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, entry0, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 63f7876c4f29..97a8d2525c26 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -444,6 +444,19 @@ ip6t_do_table(struct sk_buff *skb,
 #endif
 }
 
+static bool find_jump_target(const struct xt_table_info *t,
+			     const void *entry0,
+			     const struct ip6t_entry *target)
+{
+	struct ip6t_entry *iter;
+
+	xt_entry_foreach(iter, entry0, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
+}
+
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -541,6 +554,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct ip6t_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, entry0, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 29/88] netfilter: x_tables: add and use xt_check_entry_offsets
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (27 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 30/88] netfilter: x_tables: kill check_entry helper Jiri Slaby
                   ` (60 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7d35812c3214afa5b37a675113555259cfd67b98 upstream.

Currently arp/ip and ip6tables each implement a short helper to check that
the target offset is large enough to hold one xt_entry_target struct and
that t->u.target_size fits within the current rule.

Unfortunately these checks are not sufficient.

To avoid adding new tests to all of ip/ip6/arptables move the current
checks into a helper, then extend this helper in followup patches.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/netfilter/x_tables.h |  4 ++++
 net/ipv4/netfilter/arp_tables.c    | 11 +----------
 net/ipv4/netfilter/ip_tables.c     | 12 +-----------
 net/ipv6/netfilter/ip6_tables.c    | 12 +-----------
 net/netfilter/x_tables.c           | 34 ++++++++++++++++++++++++++++++++++
 5 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index dd49566315c6..20ced1191c50 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -239,6 +239,10 @@ extern void xt_unregister_match(struct xt_match *target);
 extern int xt_register_matches(struct xt_match *match, unsigned int n);
 extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
 
+int xt_check_entry_offsets(const void *base,
+			   unsigned int target_offset,
+			   unsigned int next_offset);
+
 extern int xt_check_match(struct xt_mtchk_param *,
 			  unsigned int size, u_int8_t proto, bool inv_proto);
 extern int xt_check_target(struct xt_tgchk_param *,
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 473ec559ce7b..7232b8301ea9 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -488,19 +488,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 
 static inline int check_entry(const struct arpt_entry *e)
 {
-	const struct xt_entry_target *t;
-
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
-		return -EINVAL;
-
-	t = arpt_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
+	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 }
 
 static inline int check_target(struct arpt_entry *e, const char *name)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index dba9d8070d07..ce2ba7365434 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -582,20 +582,10 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
 static int
 check_entry(const struct ipt_entry *e)
 {
-	const struct xt_entry_target *t;
-
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	if (e->target_offset + sizeof(struct xt_entry_target) >
-	    e->next_offset)
-		return -EINVAL;
-
-	t = ipt_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
+	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 }
 
 static int
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 97a8d2525c26..ac061d40f920 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -592,20 +592,10 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
 static int
 check_entry(const struct ip6t_entry *e)
 {
-	const struct xt_entry_target *t;
-
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	if (e->target_offset + sizeof(struct xt_entry_target) >
-	    e->next_offset)
-		return -EINVAL;
-
-	t = ip6t_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
+	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 }
 
 static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8b03028cca69..55b1e0ccb0e2 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -560,6 +560,40 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
 EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
 #endif /* CONFIG_COMPAT */
 
+/**
+ * xt_check_entry_offsets - validate arp/ip/ip6t_entry
+ *
+ * @base: pointer to arp/ip/ip6t_entry
+ * @target_offset: the arp/ip/ip6_t->target_offset
+ * @next_offset: the arp/ip/ip6_t->next_offset
+ *
+ * validates that target_offset and next_offset are sane.
+ *
+ * The arp/ip/ip6t_entry structure @base must have passed following tests:
+ * - it must point to a valid memory location
+ * - base to base + next_offset must be accessible, i.e. not exceed allocated
+ *   length.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int xt_check_entry_offsets(const void *base,
+			   unsigned int target_offset,
+			   unsigned int next_offset)
+{
+	const struct xt_entry_target *t;
+	const char *e = base;
+
+	if (target_offset + sizeof(*t) > next_offset)
+		return -EINVAL;
+
+	t = (void *)(e + target_offset);
+	if (target_offset + t->u.target_size > next_offset)
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(xt_check_entry_offsets);
+
 int xt_check_target(struct xt_tgchk_param *par,
 		    unsigned int size, u_int8_t proto, bool inv_proto)
 {
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 30/88] netfilter: x_tables: kill check_entry helper
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (28 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 29/88] netfilter: x_tables: add and use xt_check_entry_offsets Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 31/88] netfilter: x_tables: assert minimum target size Jiri Slaby
                   ` (59 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit aa412ba225dd3bc36d404c28cdc3d674850d80d0 upstream.

Once we add more sanity testing to xt_check_entry_offsets it
becomes relvant if we're expecting a 32bit 'config_compat' blob
or a normal one.

Since we already have a lot of similar-named functions (check_entry,
compat_check_entry, find_and_check_entry, etc.) and the current
incarnation is short just fold its contents into the callers.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/netfilter/arp_tables.c | 19 ++++++++-----------
 net/ipv4/netfilter/ip_tables.c  | 20 ++++++++------------
 net/ipv6/netfilter/ip6_tables.c | 20 ++++++++------------
 3 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7232b8301ea9..99b28387ef6f 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -486,14 +486,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 	return 1;
 }
 
-static inline int check_entry(const struct arpt_entry *e)
-{
-	if (!arp_checkentry(&e->arp))
-		return -EINVAL;
-
-	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
 static inline int check_target(struct arpt_entry *e, const char *name)
 {
 	struct xt_entry_target *t = arpt_get_target(e);
@@ -583,7 +575,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 		return -EINVAL;
 	}
 
-	err = check_entry(e);
+	if (!arp_checkentry(&e->arp))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (err)
 		return err;
 
@@ -1242,8 +1237,10 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct arpt_entry *)e);
+	if (!arp_checkentry(&e->arp))
+		return -EINVAL;
+
+	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ce2ba7365434..f5fe7e66610b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -580,15 +580,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
 }
 
 static int
-check_entry(const struct ipt_entry *e)
-{
-	if (!ip_checkentry(&e->ip))
-		return -EINVAL;
-
-	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
-static int
 check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
 {
 	const struct ipt_ip *ip = par->entryinfo;
@@ -744,7 +735,10 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 		return -EINVAL;
 	}
 
-	err = check_entry(e);
+	if (!ip_checkentry(&e->ip))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (err)
 		return err;
 
@@ -1508,8 +1502,10 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct ipt_entry *)e);
+	if (!ip_checkentry(&e->ip))
+		return -EINVAL;
+
+	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ac061d40f920..e9ee3feba843 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -589,15 +589,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
 	module_put(par.match->me);
 }
 
-static int
-check_entry(const struct ip6t_entry *e)
-{
-	if (!ip6_checkentry(&e->ipv6))
-		return -EINVAL;
-
-	return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
 static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
 {
 	const struct ip6t_ip6 *ipv6 = par->entryinfo;
@@ -755,7 +746,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 		return -EINVAL;
 	}
 
-	err = check_entry(e);
+	if (!ip6_checkentry(&e->ipv6))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (err)
 		return err;
 
@@ -1520,8 +1514,10 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct ip6t_entry *)e);
+	if (!ip6_checkentry(&e->ipv6))
+		return -EINVAL;
+
+	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 31/88] netfilter: x_tables: assert minimum target size
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (29 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 30/88] netfilter: x_tables: kill check_entry helper Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 32/88] netfilter: x_tables: add compat version of xt_check_entry_offsets Jiri Slaby
                   ` (58 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit a08e4e190b866579896c09af59b3bdca821da2cd upstream.

The target size includes the size of the xt_entry_target struct.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/netfilter/x_tables.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 55b1e0ccb0e2..cc34bb38c814 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -587,6 +587,9 @@ int xt_check_entry_offsets(const void *base,
 		return -EINVAL;
 
 	t = (void *)(e + target_offset);
+	if (t->u.target_size < sizeof(*t))
+		return -EINVAL;
+
 	if (target_offset + t->u.target_size > next_offset)
 		return -EINVAL;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 32/88] netfilter: x_tables: add compat version of xt_check_entry_offsets
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (30 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 31/88] netfilter: x_tables: assert minimum target size Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 33/88] netfilter: x_tables: check standard target size too Jiri Slaby
                   ` (57 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit fc1221b3a163d1386d1052184202d5dc50d302d1 upstream.

32bit rulesets have different layout and alignment requirements, so once
more integrity checks get added to xt_check_entry_offsets it will reject
well-formed 32bit rulesets.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/netfilter/x_tables.h |  3 +++
 net/ipv4/netfilter/arp_tables.c    |  3 ++-
 net/ipv4/netfilter/ip_tables.c     |  3 ++-
 net/ipv6/netfilter/ip6_tables.c    |  3 ++-
 net/netfilter/x_tables.c           | 22 ++++++++++++++++++++++
 5 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 20ced1191c50..958a5132e46b 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -437,6 +437,9 @@ extern void xt_compat_target_from_user(struct xt_entry_target *t,
 				       void **dstptr, unsigned int *size);
 extern int xt_compat_target_to_user(const struct xt_entry_target *t,
 				    void __user **dstptr, unsigned int *size);
+int xt_compat_check_entry_offsets(const void *base,
+				  unsigned int target_offset,
+				  unsigned int next_offset);
 
 #endif /* CONFIG_COMPAT */
 #endif /* _X_TABLES_H */
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 99b28387ef6f..788ddb05dd3d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1240,7 +1240,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	ret = xt_compat_check_entry_offsets(e, e->target_offset,
+					    e->next_offset);
 	if (ret)
 		return ret;
 
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index f5fe7e66610b..65325bd2180f 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1505,7 +1505,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	ret = xt_compat_check_entry_offsets(e,
+					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index e9ee3feba843..c54cfa235a1d 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1517,7 +1517,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	ret = xt_compat_check_entry_offsets(e,
+					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index cc34bb38c814..eeb4edc750cd 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -558,6 +558,27 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
+
+int xt_compat_check_entry_offsets(const void *base,
+				  unsigned int target_offset,
+				  unsigned int next_offset)
+{
+	const struct compat_xt_entry_target *t;
+	const char *e = base;
+
+	if (target_offset + sizeof(*t) > next_offset)
+		return -EINVAL;
+
+	t = (void *)(e + target_offset);
+	if (t->u.target_size < sizeof(*t))
+		return -EINVAL;
+
+	if (target_offset + t->u.target_size > next_offset)
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(xt_compat_check_entry_offsets);
 #endif /* CONFIG_COMPAT */
 
 /**
@@ -568,6 +589,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
  * @next_offset: the arp/ip/ip6_t->next_offset
  *
  * validates that target_offset and next_offset are sane.
+ * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
  *
  * The arp/ip/ip6t_entry structure @base must have passed following tests:
  * - it must point to a valid memory location
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 33/88] netfilter: x_tables: check standard target size too
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (31 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 32/88] netfilter: x_tables: add compat version of xt_check_entry_offsets Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 34/88] netfilter: x_tables: check for bogus target offset Jiri Slaby
                   ` (56 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7ed2abddd20cf8f6bd27f65bd218f26fa5bf7f44 upstream.

We have targets and standard targets -- the latter carries a verdict.

The ip/ip6tables validation functions will access t->verdict for the
standard targets to fetch the jump offset or verdict for chainloop
detection, but this happens before the targets get checked/validated.

Thus we also need to check for verdict presence here, else t->verdict
can point right after a blob.

Spotted with UBSAN while testing malformed blobs.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/netfilter/x_tables.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index eeb4edc750cd..37f7eda8ad19 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -559,6 +559,13 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
 
+/* non-compat version may have padding after verdict */
+struct compat_xt_standard_target {
+	struct compat_xt_entry_target t;
+	compat_uint_t verdict;
+};
+
+/* see xt_check_entry_offsets */
 int xt_compat_check_entry_offsets(const void *base,
 				  unsigned int target_offset,
 				  unsigned int next_offset)
@@ -576,6 +583,10 @@ int xt_compat_check_entry_offsets(const void *base,
 	if (target_offset + t->u.target_size > next_offset)
 		return -EINVAL;
 
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+	    target_offset + sizeof(struct compat_xt_standard_target) != next_offset)
+		return -EINVAL;
+
 	return 0;
 }
 EXPORT_SYMBOL(xt_compat_check_entry_offsets);
@@ -615,6 +626,10 @@ int xt_check_entry_offsets(const void *base,
 	if (target_offset + t->u.target_size > next_offset)
 		return -EINVAL;
 
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+	    target_offset + sizeof(struct xt_standard_target) != next_offset)
+		return -EINVAL;
+
 	return 0;
 }
 EXPORT_SYMBOL(xt_check_entry_offsets);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 34/88] netfilter: x_tables: check for bogus target offset
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (32 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 33/88] netfilter: x_tables: check standard target size too Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 35/88] netfilter: x_tables: validate all offsets and sizes in a rule Jiri Slaby
                   ` (55 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit ce683e5f9d045e5d67d1312a42b359cb2ab2a13c upstream.

We're currently asserting that targetoff + targetsize <= nextoff.

Extend it to also check that targetoff is >= sizeof(xt_entry).
Since this is generic code, add an argument pointing to the start of the
match/target, we can then derive the base structure size from the delta.

We also need the e->elems pointer in a followup change to validate matches.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/netfilter/x_tables.h |  4 ++--
 net/ipv4/netfilter/arp_tables.c    |  5 +++--
 net/ipv4/netfilter/ip_tables.c     |  5 +++--
 net/ipv6/netfilter/ip6_tables.c    |  5 +++--
 net/netfilter/x_tables.c           | 17 +++++++++++++++--
 5 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 958a5132e46b..ef93201a7c0e 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -239,7 +239,7 @@ extern void xt_unregister_match(struct xt_match *target);
 extern int xt_register_matches(struct xt_match *match, unsigned int n);
 extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
 
-int xt_check_entry_offsets(const void *base,
+int xt_check_entry_offsets(const void *base, const char *elems,
 			   unsigned int target_offset,
 			   unsigned int next_offset);
 
@@ -437,7 +437,7 @@ extern void xt_compat_target_from_user(struct xt_entry_target *t,
 				       void **dstptr, unsigned int *size);
 extern int xt_compat_target_to_user(const struct xt_entry_target *t,
 				    void __user **dstptr, unsigned int *size);
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
 				  unsigned int target_offset,
 				  unsigned int next_offset);
 
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 788ddb05dd3d..37550a103f88 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -578,7 +578,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1240,7 +1241,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e, e->target_offset,
+	ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
 					    e->next_offset);
 	if (ret)
 		return ret;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 65325bd2180f..cd8a5186a6a6 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -738,7 +738,8 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1505,7 +1506,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e,
+	ret = xt_compat_check_entry_offsets(e, e->elems,
 					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index c54cfa235a1d..60c71ad180f0 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -749,7 +749,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1517,7 +1518,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e,
+	ret = xt_compat_check_entry_offsets(e, e->elems,
 					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 37f7eda8ad19..ea147468df9c 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -565,14 +565,17 @@ struct compat_xt_standard_target {
 	compat_uint_t verdict;
 };
 
-/* see xt_check_entry_offsets */
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
 				  unsigned int target_offset,
 				  unsigned int next_offset)
 {
+	long size_of_base_struct = elems - (const char *)base;
 	const struct compat_xt_entry_target *t;
 	const char *e = base;
 
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
 	if (target_offset + sizeof(*t) > next_offset)
 		return -EINVAL;
 
@@ -596,12 +599,16 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
  * xt_check_entry_offsets - validate arp/ip/ip6t_entry
  *
  * @base: pointer to arp/ip/ip6t_entry
+ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
  * @target_offset: the arp/ip/ip6_t->target_offset
  * @next_offset: the arp/ip/ip6_t->next_offset
  *
  * validates that target_offset and next_offset are sane.
  * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
  *
+ * This function does not validate the targets or matches themselves, it
+ * only tests that all the offsets and sizes are correct.
+ *
  * The arp/ip/ip6t_entry structure @base must have passed following tests:
  * - it must point to a valid memory location
  * - base to base + next_offset must be accessible, i.e. not exceed allocated
@@ -610,12 +617,18 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
  * Return: 0 on success, negative errno on failure.
  */
 int xt_check_entry_offsets(const void *base,
+			   const char *elems,
 			   unsigned int target_offset,
 			   unsigned int next_offset)
 {
+	long size_of_base_struct = elems - (const char *)base;
 	const struct xt_entry_target *t;
 	const char *e = base;
 
+	/* target start is within the ip/ip6/arpt_entry struct */
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
 	if (target_offset + sizeof(*t) > next_offset)
 		return -EINVAL;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 35/88] netfilter: x_tables: validate all offsets and sizes in a rule
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (33 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 34/88] netfilter: x_tables: check for bogus target offset Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 36/88] netfilter: x_tables: don't reject valid target size on some architectures Jiri Slaby
                   ` (54 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 13631bfc604161a9d69cd68991dff8603edd66f9 upstream.

Validate that all matches (if any) add up to the beginning of
the target and that each match covers at least the base structure size.

The compat path should be able to safely re-use the function
as the structures only differ in alignment; added a
BUILD_BUG_ON just in case we have an arch that adds padding as well.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/netfilter/x_tables.c | 81 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index ea147468df9c..c4826337866b 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -435,6 +435,47 @@ int xt_check_match(struct xt_mtchk_param *par,
 }
 EXPORT_SYMBOL_GPL(xt_check_match);
 
+/** xt_check_entry_match - check that matches end before start of target
+ *
+ * @match: beginning of xt_entry_match
+ * @target: beginning of this rules target (alleged end of matches)
+ * @alignment: alignment requirement of match structures
+ *
+ * Validates that all matches add up to the beginning of the target,
+ * and that each match covers at least the base structure size.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+static int xt_check_entry_match(const char *match, const char *target,
+				const size_t alignment)
+{
+	const struct xt_entry_match *pos;
+	int length = target - match;
+
+	if (length == 0) /* no matches */
+		return 0;
+
+	pos = (struct xt_entry_match *)match;
+	do {
+		if ((unsigned long)pos % alignment)
+			return -EINVAL;
+
+		if (length < (int)sizeof(struct xt_entry_match))
+			return -EINVAL;
+
+		if (pos->u.match_size < sizeof(struct xt_entry_match))
+			return -EINVAL;
+
+		if (pos->u.match_size > length)
+			return -EINVAL;
+
+		length -= pos->u.match_size;
+		pos = ((void *)((char *)(pos) + (pos)->u.match_size));
+	} while (length > 0);
+
+	return 0;
+}
+
 #ifdef CONFIG_COMPAT
 int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
 {
@@ -590,7 +631,14 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
 	    target_offset + sizeof(struct compat_xt_standard_target) != next_offset)
 		return -EINVAL;
 
-	return 0;
+	/* compat_xt_entry match has less strict aligment requirements,
+	 * otherwise they are identical.  In case of padding differences
+	 * we need to add compat version of xt_check_entry_match.
+	 */
+	BUILD_BUG_ON(sizeof(struct compat_xt_entry_match) != sizeof(struct xt_entry_match));
+
+	return xt_check_entry_match(elems, base + target_offset,
+				    __alignof__(struct compat_xt_entry_match));
 }
 EXPORT_SYMBOL(xt_compat_check_entry_offsets);
 #endif /* CONFIG_COMPAT */
@@ -603,17 +651,39 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
  * @target_offset: the arp/ip/ip6_t->target_offset
  * @next_offset: the arp/ip/ip6_t->next_offset
  *
- * validates that target_offset and next_offset are sane.
- * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
+ * validates that target_offset and next_offset are sane and that all
+ * match sizes (if any) align with the target offset.
  *
  * This function does not validate the targets or matches themselves, it
- * only tests that all the offsets and sizes are correct.
+ * only tests that all the offsets and sizes are correct, that all
+ * match structures are aligned, and that the last structure ends where
+ * the target structure begins.
+ *
+ * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
  *
  * The arp/ip/ip6t_entry structure @base must have passed following tests:
  * - it must point to a valid memory location
  * - base to base + next_offset must be accessible, i.e. not exceed allocated
  *   length.
  *
+ * A well-formed entry looks like this:
+ *
+ * ip(6)t_entry   match [mtdata]  match [mtdata] target [tgdata] ip(6)t_entry
+ * e->elems[]-----'                              |               |
+ *                matchsize                      |               |
+ *                                matchsize      |               |
+ *                                               |               |
+ * target_offset---------------------------------'               |
+ * next_offset---------------------------------------------------'
+ *
+ * elems[]: flexible array member at end of ip(6)/arpt_entry struct.
+ *          This is where matches (if any) and the target reside.
+ * target_offset: beginning of target.
+ * next_offset: start of the next rule; also: size of this rule.
+ * Since targets have a minimum size, target_offset + minlen <= next_offset.
+ *
+ * Every match stores its size, sum of sizes must not exceed target_offset.
+ *
  * Return: 0 on success, negative errno on failure.
  */
 int xt_check_entry_offsets(const void *base,
@@ -643,7 +713,8 @@ int xt_check_entry_offsets(const void *base,
 	    target_offset + sizeof(struct xt_standard_target) != next_offset)
 		return -EINVAL;
 
-	return 0;
+	return xt_check_entry_match(elems, base + target_offset,
+				    __alignof__(struct xt_entry_match));
 }
 EXPORT_SYMBOL(xt_check_entry_offsets);
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 36/88] netfilter: x_tables: don't reject valid target size on some architectures
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (34 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 35/88] netfilter: x_tables: validate all offsets and sizes in a rule Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 37/88] netfilter: arp_tables: simplify translate_compat_table args Jiri Slaby
                   ` (53 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7b7eba0f3515fca3296b8881d583f7c1042f5226 upstream.

Quoting John Stultz:
  In updating a 32bit arm device from 4.6 to Linus' current HEAD, I
  noticed I was having some trouble with networking, and realized that
  /proc/net/ip_tables_names was suddenly empty.
  Digging through the registration process, it seems we're catching on the:

   if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
       target_offset + sizeof(struct xt_standard_target) != next_offset)
         return -EINVAL;

  Where next_offset seems to be 4 bytes larger then the
  offset + standard_target struct size.

next_offset needs to be aligned via XT_ALIGN (so we can access all members
of ip(6)t_entry struct).

This problem didn't show up on i686 as it only needs 4-byte alignment for
u64, but iptables userspace on other 32bit arches does insert extra padding.

Reported-by: John Stultz <john.stultz@linaro.org>
Tested-by: John Stultz <john.stultz@linaro.org>
Fixes: 7ed2abddd20cf ("netfilter: x_tables: check standard target size too")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/netfilter/x_tables.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index c4826337866b..6ac9fb4f42fc 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -628,7 +628,7 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
 		return -EINVAL;
 
 	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
-	    target_offset + sizeof(struct compat_xt_standard_target) != next_offset)
+	    COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
 		return -EINVAL;
 
 	/* compat_xt_entry match has less strict aligment requirements,
@@ -710,7 +710,7 @@ int xt_check_entry_offsets(const void *base,
 		return -EINVAL;
 
 	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
-	    target_offset + sizeof(struct xt_standard_target) != next_offset)
+	    XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
 		return -EINVAL;
 
 	return xt_check_entry_match(elems, base + target_offset,
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 37/88] netfilter: arp_tables: simplify translate_compat_table args
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (35 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 36/88] netfilter: x_tables: don't reject valid target size on some architectures Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 38/88] netfilter: ip_tables: " Jiri Slaby
                   ` (52 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8dddd32756f6fe8e4e82a63361119b7e2384e02f upstream.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/netfilter/arp_tables.c | 82 ++++++++++++++++++-----------------------
 1 file changed, 36 insertions(+), 46 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 37550a103f88..cf6aa304a4f5 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1200,6 +1200,18 @@ static int do_add_counters(struct net *net, const void __user *user,
 }
 
 #ifdef CONFIG_COMPAT
+struct compat_arpt_replace {
+	char				name[XT_TABLE_MAXNAMELEN];
+	u32				valid_hooks;
+	u32				num_entries;
+	u32				size;
+	u32				hook_entry[NF_ARP_NUMHOOKS];
+	u32				underflow[NF_ARP_NUMHOOKS];
+	u32				num_counters;
+	compat_uptr_t			counters;
+	struct compat_arpt_entry	entries[0];
+};
+
 static inline void compat_release_entry(struct compat_arpt_entry *e)
 {
 	struct xt_entry_target *t;
@@ -1215,8 +1227,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 				  const unsigned char *base,
 				  const unsigned char *limit,
 				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned int *underflows)
 {
 	struct xt_entry_target *t;
 	struct xt_target *target;
@@ -1287,7 +1298,7 @@ out:
 
 static int
 compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
@@ -1320,14 +1331,9 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
 	return ret;
 }
 
-static int translate_compat_table(const char *name,
-				  unsigned int valid_hooks,
-				  struct xt_table_info **pinfo,
+static int translate_compat_table(struct xt_table_info **pinfo,
 				  void **pentry0,
-				  unsigned int total_size,
-				  unsigned int number,
-				  unsigned int *hook_entries,
-				  unsigned int *underflows)
+				  const struct compat_arpt_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
@@ -1339,8 +1345,8 @@ static int translate_compat_table(const char *name,
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	/* Init all hooks to impossible value. */
 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
@@ -1351,40 +1357,39 @@ static int translate_compat_table(const char *name,
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(NFPROTO_ARP);
-	xt_compat_init_offsets(NFPROTO_ARP, number);
+	xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size,
+							compatr->hook_entry,
+							compatr->underflow);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
 	/* Check hooks all assigned */
 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
+		if (!(compatr->valid_hooks & (1 << i)))
 			continue;
 		if (info->hook_entry[i] == 0xFFFFFFFF) {
 			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
+				 i, info->hook_entry[i]);
 			goto out_unlock;
 		}
 		if (info->underflow[i] == 0xFFFFFFFF) {
 			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
+				 i, info->underflow[i]);
 			goto out_unlock;
 		}
 	}
@@ -1394,17 +1399,17 @@ static int translate_compat_table(const char *name,
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = info->hook_entry[i];
 		newinfo->underflow[i] = info->underflow[i];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
+						  newinfo, entry1);
 		if (ret != 0)
 			break;
 	}
@@ -1414,12 +1419,12 @@ static int translate_compat_table(const char *name,
 		goto free_newinfo;
 
 	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
 		goto free_newinfo;
 
 	i = 0;
 	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = check_target(iter1, name);
+		ret = check_target(iter1, compatr->name);
 		if (ret != 0)
 			break;
 		++i;
@@ -1464,7 +1469,7 @@ static int translate_compat_table(const char *name,
 free_newinfo:
 	xt_free_table_info(newinfo);
 out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
@@ -1476,18 +1481,6 @@ out_unlock:
 	goto out;
 }
 
-struct compat_arpt_replace {
-	char				name[XT_TABLE_MAXNAMELEN];
-	u32				valid_hooks;
-	u32				num_entries;
-	u32				size;
-	u32				hook_entry[NF_ARP_NUMHOOKS];
-	u32				underflow[NF_ARP_NUMHOOKS];
-	u32				num_counters;
-	compat_uptr_t			counters;
-	struct compat_arpt_entry	entries[0];
-};
-
 static int compat_do_replace(struct net *net, void __user *user,
 			     unsigned int len)
 {
@@ -1518,10 +1511,7 @@ static int compat_do_replace(struct net *net, void __user *user,
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 38/88] netfilter: ip_tables: simplify translate_compat_table args
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (36 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 37/88] netfilter: arp_tables: simplify translate_compat_table args Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 39/88] netfilter: ip6_tables: " Jiri Slaby
                   ` (51 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7d3f843eed29222254c9feab481f55175a1afcc9 upstream.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/netfilter/ip_tables.c | 61 +++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index cd8a5186a6a6..a7d5f29e6c1c 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1440,7 +1440,6 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
 
 static int
 compat_find_calc_match(struct xt_entry_match *m,
-		       const char *name,
 		       const struct ipt_ip *ip,
 		       unsigned int hookmask,
 		       int *size)
@@ -1478,8 +1477,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 				  const unsigned char *base,
 				  const unsigned char *limit,
 				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned int *underflows)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
@@ -1515,8 +1513,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
 	xt_ematch_foreach(ematch, e) {
-		ret = compat_find_calc_match(ematch, name,
-					     &e->ip, e->comefrom, &off);
+		ret = compat_find_calc_match(ematch, &e->ip, e->comefrom,
+					     &off);
 		if (ret != 0)
 			goto release_matches;
 		++j;
@@ -1565,7 +1563,7 @@ release_matches:
 
 static int
 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
@@ -1641,14 +1639,9 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
 
 static int
 translate_compat_table(struct net *net,
-		       const char *name,
-		       unsigned int valid_hooks,
 		       struct xt_table_info **pinfo,
 		       void **pentry0,
-		       unsigned int total_size,
-		       unsigned int number,
-		       unsigned int *hook_entries,
-		       unsigned int *underflows)
+		       const struct compat_ipt_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
@@ -1660,8 +1653,8 @@ translate_compat_table(struct net *net,
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	/* Init all hooks to impossible value. */
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
@@ -1672,40 +1665,39 @@ translate_compat_table(struct net *net,
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET);
-	xt_compat_init_offsets(AF_INET, number);
+	xt_compat_init_offsets(AF_INET, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size,
+							compatr->hook_entry,
+							compatr->underflow);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
 	/* Check hooks all assigned */
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
+		if (!(compatr->valid_hooks & (1 << i)))
 			continue;
 		if (info->hook_entry[i] == 0xFFFFFFFF) {
 			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
+				 i, info->hook_entry[i]);
 			goto out_unlock;
 		}
 		if (info->underflow[i] == 0xFFFFFFFF) {
 			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
+				 i, info->underflow[i]);
 			goto out_unlock;
 		}
 	}
@@ -1715,17 +1707,17 @@ translate_compat_table(struct net *net,
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	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];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
+						  newinfo, entry1);
 		if (ret != 0)
 			break;
 	}
@@ -1735,12 +1727,12 @@ translate_compat_table(struct net *net,
 		goto free_newinfo;
 
 	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
 		goto free_newinfo;
 
 	i = 0;
 	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, name);
+		ret = compat_check_entry(iter1, net, compatr->name);
 		if (ret != 0)
 			break;
 		++i;
@@ -1785,7 +1777,7 @@ translate_compat_table(struct net *net,
 free_newinfo:
 	xt_free_table_info(newinfo);
 out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
@@ -1828,10 +1820,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 39/88] netfilter: ip6_tables: simplify translate_compat_table args
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (37 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 38/88] netfilter: ip_tables: " Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 40/88] netfilter: x_tables: xt_compat_match_from_user doesn't need a retval Jiri Slaby
                   ` (50 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 329a0807124f12fe1c8032f95d8a8eb47047fb0e upstream.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv6/netfilter/ip6_tables.c | 61 +++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 60c71ad180f0..a8e605de16dd 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1452,7 +1452,6 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
 
 static int
 compat_find_calc_match(struct xt_entry_match *m,
-		       const char *name,
 		       const struct ip6t_ip6 *ipv6,
 		       unsigned int hookmask,
 		       int *size)
@@ -1490,8 +1489,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 				  const unsigned char *base,
 				  const unsigned char *limit,
 				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned int *underflows)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
@@ -1527,8 +1525,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
 	xt_ematch_foreach(ematch, e) {
-		ret = compat_find_calc_match(ematch, name,
-					     &e->ipv6, e->comefrom, &off);
+		ret = compat_find_calc_match(ematch, &e->ipv6, e->comefrom,
+					     &off);
 		if (ret != 0)
 			goto release_matches;
 		++j;
@@ -1577,7 +1575,7 @@ release_matches:
 
 static int
 compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
@@ -1651,14 +1649,9 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,
 
 static int
 translate_compat_table(struct net *net,
-		       const char *name,
-		       unsigned int valid_hooks,
 		       struct xt_table_info **pinfo,
 		       void **pentry0,
-		       unsigned int total_size,
-		       unsigned int number,
-		       unsigned int *hook_entries,
-		       unsigned int *underflows)
+		       const struct compat_ip6t_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
@@ -1670,8 +1663,8 @@ translate_compat_table(struct net *net,
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	/* Init all hooks to impossible value. */
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
@@ -1682,40 +1675,39 @@ translate_compat_table(struct net *net,
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET6);
-	xt_compat_init_offsets(AF_INET6, number);
+	xt_compat_init_offsets(AF_INET6, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size,
+							compatr->hook_entry,
+							compatr->underflow);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
 	/* Check hooks all assigned */
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
+		if (!(compatr->valid_hooks & (1 << i)))
 			continue;
 		if (info->hook_entry[i] == 0xFFFFFFFF) {
 			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
+				 i, info->hook_entry[i]);
 			goto out_unlock;
 		}
 		if (info->underflow[i] == 0xFFFFFFFF) {
 			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
+				 i, info->underflow[i]);
 			goto out_unlock;
 		}
 	}
@@ -1725,17 +1717,17 @@ translate_compat_table(struct net *net,
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	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];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
+						  newinfo, entry1);
 		if (ret != 0)
 			break;
 	}
@@ -1745,12 +1737,12 @@ translate_compat_table(struct net *net,
 		goto free_newinfo;
 
 	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
 		goto free_newinfo;
 
 	i = 0;
 	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, name);
+		ret = compat_check_entry(iter1, net, compatr->name);
 		if (ret != 0)
 			break;
 		++i;
@@ -1795,7 +1787,7 @@ translate_compat_table(struct net *net,
 free_newinfo:
 	xt_free_table_info(newinfo);
 out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
@@ -1838,10 +1830,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 40/88] netfilter: x_tables: xt_compat_match_from_user doesn't need a retval
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (38 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 39/88] netfilter: ip6_tables: " Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 41/88] netfilter: ensure number of counters is >0 in do_replace() Jiri Slaby
                   ` (49 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 0188346f21e6546498c2a0f84888797ad4063fc5 upstream.

Always returned 0.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/netfilter/x_tables.h |  2 +-
 net/ipv4/netfilter/arp_tables.c    | 17 +++++------------
 net/ipv4/netfilter/ip_tables.c     | 26 +++++++++-----------------
 net/ipv6/netfilter/ip6_tables.c    | 27 +++++++++------------------
 net/netfilter/x_tables.c           |  5 ++---
 5 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index ef93201a7c0e..fb4ea1578552 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -427,7 +427,7 @@ extern void xt_compat_init_offsets(u_int8_t af, unsigned int number);
 extern int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
 
 extern int xt_compat_match_offset(const struct xt_match *match);
-extern int xt_compat_match_from_user(struct xt_entry_match *m,
+extern void xt_compat_match_from_user(struct xt_entry_match *m,
 				     void **dstptr, unsigned int *size);
 extern int xt_compat_match_to_user(const struct xt_entry_match *m,
 				   void __user **dstptr, unsigned int *size);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index cf6aa304a4f5..819a5d2b618f 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1296,7 +1296,7 @@ out:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
 			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
@@ -1305,9 +1305,8 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
 	struct xt_target *target;
 	struct arpt_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct arpt_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct arpt_entry));
@@ -1328,7 +1327,6 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
 }
 
 static int translate_compat_table(struct xt_table_info **pinfo,
@@ -1407,16 +1405,11 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
 	size = compatr->size;
-	xt_entry_foreach(iter0, entry0, compatr->size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
 	xt_compat_flush_offsets(NFPROTO_ARP);
 	xt_compat_unlock(NFPROTO_ARP);
-	if (ret)
-		goto free_newinfo;
 
 	ret = -ELOOP;
 	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a7d5f29e6c1c..b296da45a7bd 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1561,7 +1561,7 @@ release_matches:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
@@ -1570,10 +1570,9 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 	struct xt_target *target;
 	struct ipt_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 	struct xt_entry_match *ematch;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct ipt_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct ipt_entry));
@@ -1582,11 +1581,9 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 	*dstptr += sizeof(struct ipt_entry);
 	*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
 
-	xt_ematch_foreach(ematch, e) {
-		ret = xt_compat_match_from_user(ematch, dstptr, size);
-		if (ret != 0)
-			return ret;
-	}
+	xt_ematch_foreach(ematch, e)
+		xt_compat_match_from_user(ematch, dstptr, size);
+
 	de->target_offset = e->target_offset - (origsize - *size);
 	t = compat_ipt_get_target(e);
 	target = t->u.kernel.target;
@@ -1599,7 +1596,6 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
 }
 
 static int
@@ -1715,16 +1711,12 @@ translate_compat_table(struct net *net,
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
 	size = compatr->size;
-	xt_entry_foreach(iter0, entry0, compatr->size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
+
 	xt_compat_flush_offsets(AF_INET);
 	xt_compat_unlock(AF_INET);
-	if (ret)
-		goto free_newinfo;
 
 	ret = -ELOOP;
 	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index a8e605de16dd..2b345f642978 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1573,7 +1573,7 @@ release_matches:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
@@ -1581,10 +1581,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 	struct xt_entry_target *t;
 	struct ip6t_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 	struct xt_entry_match *ematch;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct ip6t_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct ip6t_entry));
@@ -1593,11 +1592,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 	*dstptr += sizeof(struct ip6t_entry);
 	*size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
 
-	xt_ematch_foreach(ematch, e) {
-		ret = xt_compat_match_from_user(ematch, dstptr, size);
-		if (ret != 0)
-			return ret;
-	}
+	xt_ematch_foreach(ematch, e)
+		xt_compat_match_from_user(ematch, dstptr, size);
+
 	de->target_offset = e->target_offset - (origsize - *size);
 	t = compat_ip6t_get_target(e);
 	xt_compat_target_from_user(t, dstptr, size);
@@ -1609,7 +1606,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
 }
 
 static int compat_check_entry(struct ip6t_entry *e, struct net *net,
@@ -1724,17 +1720,12 @@ translate_compat_table(struct net *net,
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
-	size = compatr->size;
-	xt_entry_foreach(iter0, entry0, compatr->size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
+
 	xt_compat_flush_offsets(AF_INET6);
 	xt_compat_unlock(AF_INET6);
-	if (ret)
-		goto free_newinfo;
 
 	ret = -ELOOP;
 	if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 6ac9fb4f42fc..9cf3039deac2 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -545,8 +545,8 @@ int xt_compat_match_offset(const struct xt_match *match)
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_offset);
 
-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-			      unsigned int *size)
+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+			       unsigned int *size)
 {
 	const struct xt_match *match = m->u.kernel.match;
 	struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -568,7 +568,6 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 
 	*size += off;
 	*dstptr += msize;
-	return 0;
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 41/88] netfilter: ensure number of counters is >0 in do_replace()
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (39 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 40/88] netfilter: x_tables: xt_compat_match_from_user doesn't need a retval Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table Jiri Slaby
                   ` (48 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Dave Jones, Pablo Neira Ayuso, Jiri Slaby

From: Dave Jones <davej@codemonkey.org.uk>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 1086bbe97a074844188c6c988fa0b1a98c3ccbb9 upstream.

After improving setsockopt() coverage in trinity, I started triggering
vmalloc failures pretty reliably from this code path:

warn_alloc_failed+0xe9/0x140
__vmalloc_node_range+0x1be/0x270
vzalloc+0x4b/0x50
__do_replace+0x52/0x260 [ip_tables]
do_ipt_set_ctl+0x15d/0x1d0 [ip_tables]
nf_setsockopt+0x65/0x90
ip_setsockopt+0x61/0xa0
raw_setsockopt+0x16/0x60
sock_common_setsockopt+0x14/0x20
SyS_setsockopt+0x71/0xd0

It turns out we don't validate that the num_counters field in the
struct we pass in from userspace is initialized.

The same problem also exists in ebtables, arptables, ipv6, and the
compat variants.

Signed-off-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bridge/netfilter/ebtables.c | 4 ++++
 net/ipv4/netfilter/arp_tables.c | 6 ++++++
 net/ipv4/netfilter/ip_tables.c  | 6 ++++++
 net/ipv6/netfilter/ip6_tables.c | 6 ++++++
 4 files changed, 22 insertions(+)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index b166fc2ec4b9..fbfa24b19127 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1105,6 +1105,8 @@ static int do_replace(struct net *net, const void __user *user,
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
 
 	tmp.name[sizeof(tmp.name) - 1] = 0;
 
@@ -2150,6 +2152,8 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
 
 	memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
 
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 819a5d2b618f..020b0e97c206 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1077,6 +1077,9 @@ static int do_replace(struct net *net, const void __user *user,
 	/* overflow check */
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
@@ -1491,6 +1494,9 @@ static int compat_do_replace(struct net *net, void __user *user,
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index b296da45a7bd..a207d2befc75 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1263,6 +1263,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
 	/* overflow check */
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
@@ -1798,6 +1801,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 2b345f642978..b87f35b6c742 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1273,6 +1273,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
 	/* overflow check */
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
@@ -1807,6 +1810,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
 		return -ENOMEM;
+	if (tmp.num_counters == 0)
+		return -EINVAL;
+
 	tmp.name[sizeof(tmp.name)-1] = 0;
 
 	newinfo = xt_alloc_table_info(tmp.size);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (40 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 41/88] netfilter: ensure number of counters is >0 in do_replace() Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-19  7:13   ` Michal Kubecek
  2016-07-14  8:15 ` [PATCH 3.12 43/88] Revert "netfilter: ensure number of counters is >0 in do_replace()" Jiri Slaby
                   ` (47 subsequent siblings)
  89 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

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: Jiri Slaby <jslaby@suse.cz>
---
 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 020b0e97c206..b7f3b31a3cc3 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1223,19 +1223,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 ||
@@ -1280,17 +1278,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:
@@ -1340,7 +1327,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;
 
@@ -1349,12 +1336,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);
@@ -1363,9 +1344,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;
@@ -1378,23 +1357,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)
@@ -1411,51 +1373,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;
@@ -1464,17 +1400,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 a207d2befc75..19878c0ba0fc 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1478,16 +1478,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 ||
@@ -1540,17 +1538,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:
@@ -1593,6 +1580,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;
@@ -1602,41 +1590,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,
@@ -1646,7 +1599,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;
 
@@ -1655,12 +1608,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);
@@ -1669,9 +1616,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;
@@ -1684,23 +1629,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)
@@ -1708,8 +1636,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;
@@ -1718,51 +1646,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;
@@ -1771,17 +1677,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 b87f35b6c742..59a8cc791966 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1490,16 +1490,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 ||
@@ -1552,17 +1550,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:
@@ -1611,41 +1598,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,
@@ -1656,7 +1608,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;
 
@@ -1665,12 +1617,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);
@@ -1679,9 +1625,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;
@@ -1694,23 +1638,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)
@@ -1718,60 +1645,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;
@@ -1780,17 +1680,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 9cf3039deac2..da11978eff5d 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.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 43/88] Revert "netfilter: ensure number of counters is >0 in do_replace()"
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (41 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 44/88] netfilter: x_tables: introduce and use xt_copy_counters_from_user Jiri Slaby
                   ` (46 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Bernhard Thaler, Pablo Neira Ayuso, Jiri Slaby

From: Bernhard Thaler <bernhard.thaler@wvnet.at>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d26e2c9ffa385dd1b646f43c1397ba12af9ed431 upstream.

This partially reverts commit 1086bbe97a07 ("netfilter: ensure number of
counters is >0 in do_replace()") in net/bridge/netfilter/ebtables.c.

Setting rules with ebtables does not work any more with 1086bbe97a07 place.

There is an error message and no rules set in the end.

e.g.

~# ebtables -t nat -A POSTROUTING --src 12:34:56:78:9a:bc -j DROP
Unable to update the kernel. Two possible causes:
1. Multiple ebtables programs were executing simultaneously. The ebtables
   userspace tool doesn't by default support multiple ebtables programs
running

Reverting the ebtables part of 1086bbe97a07 makes this work again.

Signed-off-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bridge/netfilter/ebtables.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index fbfa24b19127..b166fc2ec4b9 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1105,8 +1105,6 @@ static int do_replace(struct net *net, const void __user *user,
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
 		return -ENOMEM;
-	if (tmp.num_counters == 0)
-		return -EINVAL;
 
 	tmp.name[sizeof(tmp.name) - 1] = 0;
 
@@ -2152,8 +2150,6 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
 		return -ENOMEM;
 	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
 		return -ENOMEM;
-	if (tmp.num_counters == 0)
-		return -EINVAL;
 
 	memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 44/88] netfilter: x_tables: introduce and use xt_copy_counters_from_user
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (42 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 43/88] Revert "netfilter: ensure number of counters is >0 in do_replace()" Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 45/88] crypto: ux500 - memmove the right size Jiri Slaby
                   ` (45 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso, Jiri Slaby

From: Florian Westphal <fw@strlen.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d7591f0c41ce3e67600a982bab6989ef0f07b3ce upstream

The three variants use same copy&pasted code, condense this into a
helper and use that.

Make sure info.name is 0-terminated.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/netfilter/x_tables.h |  3 ++
 net/ipv4/netfilter/arp_tables.c    | 48 +++----------------------
 net/ipv4/netfilter/ip_tables.c     | 48 +++----------------------
 net/ipv6/netfilter/ip6_tables.c    | 49 +++----------------------
 net/netfilter/x_tables.c           | 74 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 92 insertions(+), 130 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index fb4ea1578552..1d24aa71f773 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -248,6 +248,9 @@ extern int xt_check_match(struct xt_mtchk_param *,
 extern int xt_check_target(struct xt_tgchk_param *,
 			   unsigned int size, u_int8_t proto, bool inv_proto);
 
+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
+				 struct xt_counters_info *info, bool compat);
+
 extern struct xt_table *xt_register_table(struct net *net,
 					  const struct xt_table *table,
 					  struct xt_table_info *bootstrap,
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b7f3b31a3cc3..3f58cf8e2fd2 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1120,56 +1120,18 @@ static int do_add_counters(struct net *net, const void __user *user,
 	unsigned int i, curcpu;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	const char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	void *loc_cpu_entry;
 	struct arpt_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
 
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
-
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
-
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
 
-	t = xt_find_table_lock(net, NFPROTO_ARP, name);
+	t = xt_find_table_lock(net, NFPROTO_ARP, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1177,7 +1139,7 @@ static int do_add_counters(struct net *net, const void __user *user,
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 19878c0ba0fc..9363a37729a8 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1307,56 +1307,18 @@ do_add_counters(struct net *net, const void __user *user,
 	unsigned int i, curcpu;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	const char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	void *loc_cpu_entry;
 	struct ipt_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
 
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
-
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
-
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
 
-	t = xt_find_table_lock(net, AF_INET, name);
+	t = xt_find_table_lock(net, AF_INET, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1364,7 +1326,7 @@ do_add_counters(struct net *net, const void __user *user,
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 59a8cc791966..a7d644e62a3e 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1317,56 +1317,17 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
 	unsigned int i, curcpu;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	const void *loc_cpu_entry;
 	struct ip6t_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
-
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
-
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
-
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
 
-	t = xt_find_table_lock(net, AF_INET6, name);
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
+	t = xt_find_table_lock(net, AF_INET6, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1375,7 +1336,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index da11978eff5d..51c141b09dba 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -771,6 +771,80 @@ int xt_check_target(struct xt_tgchk_param *par,
 }
 EXPORT_SYMBOL_GPL(xt_check_target);
 
+/**
+ * xt_copy_counters_from_user - copy counters and metadata from userspace
+ *
+ * @user: src pointer to userspace memory
+ * @len: alleged size of userspace memory
+ * @info: where to store the xt_counters_info metadata
+ * @compat: true if we setsockopt call is done by 32bit task on 64bit kernel
+ *
+ * Copies counter meta data from @user and stores it in @info.
+ *
+ * vmallocs memory to hold the counters, then copies the counter data
+ * from @user to the new memory and returns a pointer to it.
+ *
+ * If @compat is true, @info gets converted automatically to the 64bit
+ * representation.
+ *
+ * The metadata associated with the counters is stored in @info.
+ *
+ * Return: returns pointer that caller has to test via IS_ERR().
+ * If IS_ERR is false, caller has to vfree the pointer.
+ */
+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
+				 struct xt_counters_info *info, bool compat)
+{
+	void *mem;
+	u64 size;
+
+#ifdef CONFIG_COMPAT
+	if (compat) {
+		/* structures only differ in size due to alignment */
+		struct compat_xt_counters_info compat_tmp;
+
+		if (len <= sizeof(compat_tmp))
+			return ERR_PTR(-EINVAL);
+
+		len -= sizeof(compat_tmp);
+		if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
+			return ERR_PTR(-EFAULT);
+
+		strlcpy(info->name, compat_tmp.name, sizeof(info->name));
+		info->num_counters = compat_tmp.num_counters;
+		user += sizeof(compat_tmp);
+	} else
+#endif
+	{
+		if (len <= sizeof(*info))
+			return ERR_PTR(-EINVAL);
+
+		len -= sizeof(*info);
+		if (copy_from_user(info, user, sizeof(*info)) != 0)
+			return ERR_PTR(-EFAULT);
+
+		info->name[sizeof(info->name) - 1] = '\0';
+		user += sizeof(*info);
+	}
+
+	size = sizeof(struct xt_counters);
+	size *= info->num_counters;
+
+	if (size != (u64)len)
+		return ERR_PTR(-EINVAL);
+
+	mem = vmalloc(len);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+
+	if (copy_from_user(mem, user, len) == 0)
+		return mem;
+
+	vfree(mem);
+	return ERR_PTR(-EFAULT);
+}
+EXPORT_SYMBOL_GPL(xt_copy_counters_from_user);
+
 #ifdef CONFIG_COMPAT
 int xt_compat_target_offset(const struct xt_target *target)
 {
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 45/88] crypto: ux500 - memmove the right size
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (43 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 44/88] netfilter: x_tables: introduce and use xt_copy_counters_from_user Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 46/88] sit: correct IP protocol used in ipip6_err Jiri Slaby
                   ` (44 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Linus Walleij, Joakim Bech, Herbert Xu, Jiri Slaby

From: Linus Walleij <linus.walleij@linaro.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 19ced623db2fe91604d69f7d86b03144c5107739 upstream.

The hash buffer is really HASH_BLOCK_SIZE bytes, someone
must have thought that memmove takes n*u32 words by mistake.
Tests work as good/bad as before after this patch.

Cc: Joakim Bech <joakim.bech@linaro.org>
Reported-by: David Binderman <linuxdev.baldrick@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/crypto/ux500/hash/hash_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
index 8e5e0187506f..3ff21c3e9ab2 100644
--- a/drivers/crypto/ux500/hash/hash_core.c
+++ b/drivers/crypto/ux500/hash/hash_core.c
@@ -797,7 +797,7 @@ static int hash_process_data(struct hash_device_data *device_data,
 						&device_data->state);
 				memmove(req_ctx->state.buffer,
 					device_data->state.buffer,
-					HASH_BLOCK_SIZE / sizeof(u32));
+					HASH_BLOCK_SIZE);
 				if (ret) {
 					dev_err(device_data->dev,
 						"%s: hash_resume_state() failed!\n",
@@ -848,7 +848,7 @@ static int hash_process_data(struct hash_device_data *device_data,
 
 			memmove(device_data->state.buffer,
 				req_ctx->state.buffer,
-				HASH_BLOCK_SIZE / sizeof(u32));
+				HASH_BLOCK_SIZE);
 			if (ret) {
 				dev_err(device_data->dev, "%s: hash_save_state() failed!\n",
 					__func__);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 46/88] sit: correct IP protocol used in ipip6_err
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (44 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 45/88] crypto: ux500 - memmove the right size Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 47/88] ipmr/ip6mr: Initialize the last assert time of mfc entries Jiri Slaby
                   ` (43 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Simon Horman, David S . Miller, Jiri Slaby

From: Simon Horman <simon.horman@netronome.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit d5d8760b78d0cfafe292f965f599988138b06a70 ]

Since 32b8a8e59c9c ("sit: add IPv4 over IPv4 support")
ipip6_err() may be called for packets whose IP protocol is
IPPROTO_IPIP as well as those whose IP protocol is IPPROTO_IPV6.

In the case of IPPROTO_IPIP packets the correct protocol value is not
passed to ipv4_update_pmtu() or ipv4_redirect().

This patch resolves this problem by using the IP protocol of the packet
rather than a hard-coded value. This appears to be consistent
with the usage of the protocol of a packet by icmp_socket_deliver()
the caller of ipip6_err().

I was able to exercise the redirect case by using a setup where an ICMP
redirect was received for the destination of the encapsulated packet.
However, it appears that although incorrect the protocol field is not used
in this case and thus no problem manifests.  On inspection it does not
appear that a problem will manifest in the fragmentation needed/update pmtu
case either.

In short I believe this is a cosmetic fix. None the less, the use of
IPPROTO_IPV6 seems wrong and confusing.

Reviewed-by: Dinan Gunawardena <dinan.gunawardena@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv6/sit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index eb1fe0759752..a883776bcec8 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -529,13 +529,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
 
 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
-				 t->parms.link, 0, IPPROTO_IPV6, 0);
+				 t->parms.link, 0, iph->protocol, 0);
 		err = 0;
 		goto out;
 	}
 	if (type == ICMP_REDIRECT) {
 		ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
-			      IPPROTO_IPV6, 0);
+			      iph->protocol, 0);
 		err = 0;
 		goto out;
 	}
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 47/88] ipmr/ip6mr: Initialize the last assert time of mfc entries.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (45 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 46/88] sit: correct IP protocol used in ipip6_err Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15   ` Jiri Slaby
                   ` (42 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Tom Goff, David S . Miller, Jiri Slaby

From: Tom Goff <thomas.goff@ll.mit.edu>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 70a0dec45174c976c64b4c8c1d0898581f759948 ]

This fixes wrong-interface signaling on 32-bit platforms for entries
created when jiffies > 2^31 + MFC_ASSERT_THRESH.

Signed-off-by: Tom Goff <thomas.goff@ll.mit.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/ipv4/ipmr.c  | 4 +++-
 net/ipv6/ip6mr.c | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 2f8de5f9c032..dccda72bac62 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -881,8 +881,10 @@ static struct mfc_cache *ipmr_cache_alloc(void)
 {
 	struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
 
-	if (c)
+	if (c) {
+		c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
 		c->mfc_un.res.minvif = MAXVIFS;
+	}
 	return c;
 }
 
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8b61288e5746..86d30e60242a 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1076,6 +1076,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
 	struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
 	if (c == NULL)
 		return NULL;
+	c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
 	c->mfc_un.res.minvif = MAXMIFS;
 	return c;
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 48/88] net: alx: Work around the DMA RX overflow issue
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
@ 2016-07-14  8:15   ` Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 02/88] MIPS: Fix 64k page support for 32 bit kernels Jiri Slaby
                     ` (88 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Feng Tang, Jiri Slaby

From: Feng Tang <feng.tang@intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 881d0327db37ad917a367c77aff1afa1ee41e0a9 ]

Note: This is a verified backported patch for stable 4.4 kernel, and it
could also be applied to 4.3/4.2/4.1/3.18/3.16

There is a problem with alx devices, that the network link will be
lost in 1-5 minutes after the device is up.

>From debugging without datasheet, we found the error always
happen when the DMA RX address is set to 0x....fc0, which is very
likely to be a HW/silicon problem.

This patch will apply rx skb with 64 bytes longer space, and if the
allocated skb has a 0x...fc0 address, it will use skb_resever(skb, 64)
to advance the address, so that the RX overflow can be avoided.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=70761
Signed-off-by: Feng Tang <feng.tang@intel.com>
Suggested-by: Eric Dumazet <edumazet@google.com>
Tested-by: Ole Lukoie <olelukoie@mail.ru>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/ethernet/atheros/alx/main.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 754ac8ef2484..4736df41f062 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -86,9 +86,14 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
 	while (!cur_buf->skb && next != rxq->read_idx) {
 		struct alx_rfd *rfd = &rxq->rfd[cur];
 
-		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
+		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size + 64, gfp);
 		if (!skb)
 			break;
+
+		/* Workround for the HW RX DMA overflow issue */
+		if (((unsigned long)skb->data & 0xfff) == 0xfc0)
+			skb_reserve(skb, 64);
+
 		dma = dma_map_single(&alx->hw.pdev->dev,
 				     skb->data, alx->rxbuf_size,
 				     DMA_FROM_DEVICE);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 48/88] net: alx: Work around the DMA RX overflow issue
@ 2016-07-14  8:15   ` Jiri Slaby
  0 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Feng Tang, Jiri Slaby

From: Feng Tang <feng.tang@intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 881d0327db37ad917a367c77aff1afa1ee41e0a9 ]

Note: This is a verified backported patch for stable 4.4 kernel, and it
could also be applied to 4.3/4.2/4.1/3.18/3.16

There is a problem with alx devices, that the network link will be
lost in 1-5 minutes after the device is up.

>>From debugging without datasheet, we found the error always
happen when the DMA RX address is set to 0x....fc0, which is very
likely to be a HW/silicon problem.

This patch will apply rx skb with 64 bytes longer space, and if the
allocated skb has a 0x...fc0 address, it will use skb_resever(skb, 64)
to advance the address, so that the RX overflow can be avoided.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=70761
Signed-off-by: Feng Tang <feng.tang@intel.com>
Suggested-by: Eric Dumazet <edumazet@google.com>
Tested-by: Ole Lukoie <olelukoie@mail.ru>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/ethernet/atheros/alx/main.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 754ac8ef2484..4736df41f062 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -86,9 +86,14 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
 	while (!cur_buf->skb && next != rxq->read_idx) {
 		struct alx_rfd *rfd = &rxq->rfd[cur];
 
-		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
+		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size + 64, gfp);
 		if (!skb)
 			break;
+
+		/* Workround for the HW RX DMA overflow issue */
+		if (((unsigned long)skb->data & 0xfff) == 0xfc0)
+			skb_reserve(skb, 64);
+
 		dma = dma_map_single(&alx->hw.pdev->dev,
 				     skb->data, alx->rxbuf_size,
 				     DMA_FROM_DEVICE);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 49/88] usb: quirks: Add no-lpm quirk for Acer C120 LED Projector
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (47 preceding siblings ...)
  2016-07-14  8:15   ` Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 50/88] usb: musb: Stop bulk endpoint while queue is rotated Jiri Slaby
                   ` (40 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Hans de Goede, Jiri Slaby

From: Hans de Goede <hdegoede@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 32cb0b37098f4beeff5ad9e325f11b42a6ede56c upstream.

The Acer C120 LED Projector is a USB-3 connected pico projector which
takes both its power and video data from USB-3.

In combination with some hubs this device does not play well with
lpm, so disable lpm for it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/core/quirks.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 9596d4f3e71a..ba39d978583c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -225,6 +225,9 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
 	/* Logitech Optical Mouse M90/M100 */
 	{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Acer C120 LED Projector */
+	{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
+
 	/* Blackmagic Design Intensity Shuttle */
 	{ USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 50/88] usb: musb: Stop bulk endpoint while queue is rotated
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (48 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 49/88] usb: quirks: Add no-lpm quirk for Acer C120 LED Projector Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 51/88] usb: musb: Ensure rx reinit occurs for shared_fifo endpoints Jiri Slaby
                   ` (39 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Andrew Goodbody, Bin Liu, Jiri Slaby

From: Andrew Goodbody <andrew.goodbody@cambrionix.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7b2c17f829545df27a910e8d82e133c21c9a8c9c upstream.

Ensure that the endpoint is stopped by clearing REQPKT before
clearing DATAERR_NAKTIMEOUT before rotating the queue on the
dedicated bulk endpoint.
This addresses an issue where a race could result in the endpoint
receiving data before it was reprogrammed resulting in a warning
about such data from musb_rx_reinit before it was thrown away.
The data thrown away was a valid packet that had been correctly
ACKed which meant the host and device got out of sync.

Signed-off-by: Andrew Goodbody <andrew.goodbody@cambrionix.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/musb/musb_host.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index d73cda3591aa..7a149719d495 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -951,9 +951,15 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep,
 	if (is_in) {
 		dma = is_dma_capable() ? ep->rx_channel : NULL;
 
-		/* clear nak timeout bit */
+		/*
+		 * Need to stop the transaction by clearing REQPKT first
+		 * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED
+		 * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2
+		 */
 		rx_csr = musb_readw(epio, MUSB_RXCSR);
 		rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+		rx_csr &= ~MUSB_RXCSR_H_REQPKT;
+		musb_writew(epio, MUSB_RXCSR, rx_csr);
 		rx_csr &= ~MUSB_RXCSR_DATAERROR;
 		musb_writew(epio, MUSB_RXCSR, rx_csr);
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 51/88] usb: musb: Ensure rx reinit occurs for shared_fifo endpoints
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (49 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 50/88] usb: musb: Stop bulk endpoint while queue is rotated Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 52/88] mac80211: mesh: flush mesh paths unconditionally Jiri Slaby
                   ` (38 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Andrew Goodbody, Bin Liu, Jiri Slaby

From: Andrew Goodbody <andrew.goodbody@cambrionix.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit f3eec0cf784e0d6c47822ca6b66df3d5812af7e6 upstream.

shared_fifo endpoints would only get a previous tx state cleared
out, the rx state was only cleared for non shared_fifo endpoints
Change this so that the rx state is cleared for all endpoints.
This addresses an issue that resulted in rx packets being dropped
silently.

Signed-off-by: Andrew Goodbody <andrew.goodbody@cambrionix.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/musb/musb_host.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 7a149719d495..7be2ad0a10f4 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -584,14 +584,13 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 		musb_writew(ep->regs, MUSB_TXCSR, 0);
 
 	/* scrub all previous state, clearing toggle */
-	} else {
-		csr = musb_readw(ep->regs, MUSB_RXCSR);
-		if (csr & MUSB_RXCSR_RXPKTRDY)
-			WARNING("rx%d, packet/%d ready?\n", ep->epnum,
-				musb_readw(ep->regs, MUSB_RXCOUNT));
-
-		musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
 	}
+	csr = musb_readw(ep->regs, MUSB_RXCSR);
+	if (csr & MUSB_RXCSR_RXPKTRDY)
+		WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+			musb_readw(ep->regs, MUSB_RXCOUNT));
+
+	musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 52/88] mac80211: mesh: flush mesh paths unconditionally
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (50 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 51/88] usb: musb: Ensure rx reinit occurs for shared_fifo endpoints Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 53/88] mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL Jiri Slaby
                   ` (37 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Bob Copeland, Johannes Berg, Jiri Slaby

From: Bob Copeland <me@bobcopeland.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit fe7a7c57629e8dcbc0e297363a9b2366d67a6dc5 upstream.

Currently, the mesh paths associated with a nexthop station are cleaned
up in the following code path:

    __sta_info_destroy_part1
    synchronize_net()
    __sta_info_destroy_part2
     -> cleanup_single_sta
       -> mesh_sta_cleanup
         -> mesh_plink_deactivate
           -> mesh_path_flush_by_nexthop

However, there are a couple of problems here:

1) the paths aren't flushed at all if the MPM is running in userspace
   (e.g. when using wpa_supplicant or authsae)

2) there is no synchronize_rcu between removing the path and readers
   accessing the nexthop, which means the following race is possible:

CPU0                            CPU1
~~~~                            ~~~~
                                sta_info_destroy_part1()
                                synchronize_net()
rcu_read_lock()
mesh_nexthop_resolve()
  mpath = mesh_path_lookup()
                                [...] -> mesh_path_flush_by_nexthop()
  sta = rcu_dereference(
    mpath->next_hop)
                                kfree(sta)
  access sta <-- CRASH

Fix both of these by unconditionally flushing paths before destroying
the sta, and by adding a synchronize_net() after path flush to ensure
no active readers can still dereference the sta.

Fixes this crash:

[  348.529295] BUG: unable to handle kernel paging request at 00020040
[  348.530014] IP: [<f929245d>] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211]
[  348.530014] *pde = 00000000
[  348.530014] Oops: 0000 [#1] PREEMPT
[  348.530014] Modules linked in: drbg ansi_cprng ctr ccm ppp_generic slhc ipt_MASQUERADE nf_nat_masquerade_ipv4 8021q ]
[  348.530014] CPU: 0 PID: 20597 Comm: wget Tainted: G           O 4.6.0-rc5-wt=V1 #1
[  348.530014] Hardware name: To Be Filled By O.E.M./To be filled by O.E.M., BIOS 080016  11/07/2014
[  348.530014] task: f64fa280 ti: f4f9c000 task.ti: f4f9c000
[  348.530014] EIP: 0060:[<f929245d>] EFLAGS: 00010246 CPU: 0
[  348.530014] EIP is at ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211]
[  348.530014] EAX: f4ce63e0 EBX: 00000088 ECX: f3788416 EDX: 00020008
[  348.530014] ESI: 00000000 EDI: 00000088 EBP: f6409a4c ESP: f6409a40
[  348.530014]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[  348.530014] CR0: 80050033 CR2: 00020040 CR3: 33190000 CR4: 00000690
[  348.530014] Stack:
[  348.530014]  00000000 f4ce63e0 f5f9bd80 f6409a64 f9291d80 0000ce67 f5d51e00 f4ce63e0
[  348.530014]  f3788416 f6409a80 f9291dc1 f4ce8320 f4ce63e0 f5d51e00 f4ce63e0 f4ce8320
[  348.530014]  f6409a98 f9277f6f 00000000 00000000 0000007c 00000000 f6409b2c f9278dd1
[  348.530014] Call Trace:
[  348.530014]  [<f9291d80>] mesh_nexthop_lookup+0xbb/0xc8 [mac80211]
[  348.530014]  [<f9291dc1>] mesh_nexthop_resolve+0x34/0xd8 [mac80211]
[  348.530014]  [<f9277f6f>] ieee80211_xmit+0x92/0xc1 [mac80211]
[  348.530014]  [<f9278dd1>] __ieee80211_subif_start_xmit+0x807/0x83c [mac80211]
[  348.530014]  [<c04df012>] ? sch_direct_xmit+0xd7/0x1b3
[  348.530014]  [<c022a8c6>] ? __local_bh_enable_ip+0x5d/0x7b
[  348.530014]  [<f956870c>] ? nf_nat_ipv4_out+0x4c/0xd0 [nf_nat_ipv4]
[  348.530014]  [<f957e036>] ? iptable_nat_ipv4_fn+0xf/0xf [iptable_nat]
[  348.530014]  [<c04c6f45>] ? netif_skb_features+0x14d/0x30a
[  348.530014]  [<f9278e10>] ieee80211_subif_start_xmit+0xa/0xe [mac80211]
[  348.530014]  [<c04c769c>] dev_hard_start_xmit+0x1f8/0x267
[  348.530014]  [<c04c7261>] ?  validate_xmit_skb.isra.120.part.121+0x10/0x253
[  348.530014]  [<c04defc6>] sch_direct_xmit+0x8b/0x1b3
[  348.530014]  [<c04c7a9c>] __dev_queue_xmit+0x2c8/0x513
[  348.530014]  [<c04c7cfb>] dev_queue_xmit+0xa/0xc
[  348.530014]  [<f91bfc7a>] batadv_send_skb_packet+0xd6/0xec [batman_adv]
[  348.530014]  [<f91bfdc4>] batadv_send_unicast_skb+0x15/0x4a [batman_adv]
[  348.530014]  [<f91b5938>] batadv_dat_send_data+0x27e/0x310 [batman_adv]
[  348.530014]  [<f91c30b5>] ? batadv_tt_global_hash_find.isra.11+0x8/0xa [batman_adv]
[  348.530014]  [<f91b63f3>] batadv_dat_snoop_outgoing_arp_request+0x208/0x23d [batman_adv]
[  348.530014]  [<f91c0cd9>] batadv_interface_tx+0x206/0x385 [batman_adv]
[  348.530014]  [<c04c769c>] dev_hard_start_xmit+0x1f8/0x267
[  348.530014]  [<c04c7261>] ?  validate_xmit_skb.isra.120.part.121+0x10/0x253
[  348.530014]  [<c04defc6>] sch_direct_xmit+0x8b/0x1b3
[  348.530014]  [<c04c7a9c>] __dev_queue_xmit+0x2c8/0x513
[  348.530014]  [<f80cbd2a>] ? igb_xmit_frame+0x57/0x72 [igb]
[  348.530014]  [<c04c7cfb>] dev_queue_xmit+0xa/0xc
[  348.530014]  [<f843a326>] br_dev_queue_push_xmit+0xeb/0xfb [bridge]
[  348.530014]  [<f843a35f>] br_forward_finish+0x29/0x74 [bridge]
[  348.530014]  [<f843a23b>] ? deliver_clone+0x3b/0x3b [bridge]
[  348.530014]  [<f843a714>] __br_forward+0x89/0xe7 [bridge]
[  348.530014]  [<f843a336>] ? br_dev_queue_push_xmit+0xfb/0xfb [bridge]
[  348.530014]  [<f843a234>] deliver_clone+0x34/0x3b [bridge]
[  348.530014]  [<f843a68b>] ? br_flood+0x95/0x95 [bridge]
[  348.530014]  [<f843a66d>] br_flood+0x77/0x95 [bridge]
[  348.530014]  [<f843a809>] br_flood_forward+0x13/0x1a [bridge]
[  348.530014]  [<f843a68b>] ? br_flood+0x95/0x95 [bridge]
[  348.530014]  [<f843b877>] br_handle_frame_finish+0x392/0x3db [bridge]
[  348.530014]  [<c04e9b2b>] ? nf_iterate+0x2b/0x6b
[  348.530014]  [<f843baa6>] br_handle_frame+0x1e6/0x240 [bridge]
[  348.530014]  [<f843b4e5>] ? br_handle_local_finish+0x6a/0x6a [bridge]
[  348.530014]  [<c04c4ba0>] __netif_receive_skb_core+0x43a/0x66b
[  348.530014]  [<f843b8c0>] ? br_handle_frame_finish+0x3db/0x3db [bridge]
[  348.530014]  [<c023cea4>] ? resched_curr+0x19/0x37
[  348.530014]  [<c0240707>] ? check_preempt_wakeup+0xbf/0xfe
[  348.530014]  [<c0255dec>] ? ktime_get_with_offset+0x5c/0xfc
[  348.530014]  [<c04c4fc1>] __netif_receive_skb+0x47/0x55
[  348.530014]  [<c04c57ba>] netif_receive_skb_internal+0x40/0x5a
[  348.530014]  [<c04c61ef>] napi_gro_receive+0x3a/0x94
[  348.530014]  [<f80ce8d5>] igb_poll+0x6fd/0x9ad [igb]
[  348.530014]  [<c0242bd8>] ? swake_up_locked+0x14/0x26
[  348.530014]  [<c04c5d29>] net_rx_action+0xde/0x250
[  348.530014]  [<c022a743>] __do_softirq+0x8a/0x163
[  348.530014]  [<c022a6b9>] ? __hrtimer_tasklet_trampoline+0x19/0x19
[  348.530014]  [<c021100f>] do_softirq_own_stack+0x26/0x2c
[  348.530014]  <IRQ>
[  348.530014]  [<c022a957>] irq_exit+0x31/0x6f
[  348.530014]  [<c0210eb2>] do_IRQ+0x8d/0xa0
[  348.530014]  [<c058152c>] common_interrupt+0x2c/0x40
[  348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005
[  348.530014] EIP: [<f929245d>] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] SS:ESP 0068:f6409a40
[  348.530014] CR2: 0000000000020040
[  348.530014] ---[ end trace 48556ac26779732e ]---
[  348.530014] Kernel panic - not syncing: Fatal exception in interrupt
[  348.530014] Kernel Offset: disabled

Reported-by: Fred Veldini <fred.veldini@gmail.com>
Tested-by: Fred Veldini <fred.veldini@gmail.com>
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/mac80211/mesh.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 707ac61d63e5..67559f7a7832 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -160,6 +160,10 @@ void mesh_sta_cleanup(struct sta_info *sta)
 		del_timer_sync(&sta->plink_timer);
 	}
 
+	/* make sure no readers can access nexthop sta from here on */
+	mesh_path_flush_by_nexthop(sta);
+	synchronize_net();
+
 	if (changed)
 		ieee80211_mbss_info_change_notify(sdata, changed);
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 53/88] mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (51 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 52/88] mac80211: mesh: flush mesh paths unconditionally Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 54/88] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs Jiri Slaby
                   ` (36 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Martin Willi, Johannes Berg, Jiri Slaby

From: Martin Willi <martin@strongswan.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 62397da50bb20a6b812c949ef465d7e69fe54bb6 upstream.

A wmediumd that does not send this attribute causes a NULL pointer
dereference, as the attribute is accessed even if it does not exist.

The attribute was required but never checked ever since userspace frame
forwarding has been introduced. The issue gets more problematic once we
allow wmediumd registration from user namespaces.

Fixes: 7882513bacb1 ("mac80211_hwsim driver support userspace frame tx/rx")
Signed-off-by: Martin Willi <martin@strongswan.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/wireless/mac80211_hwsim.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 38b8b7139ba3..38fa31d56ef9 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1932,6 +1932,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
 	if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
 	   !info->attrs[HWSIM_ATTR_FLAGS] ||
 	   !info->attrs[HWSIM_ATTR_COOKIE] ||
+	   !info->attrs[HWSIM_ATTR_SIGNAL] ||
 	   !info->attrs[HWSIM_ATTR_TX_INFO])
 		goto out;
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 54/88] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (52 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 53/88] mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 55/88] powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism Jiri Slaby
                   ` (35 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Jason Gunthorpe, Doug Ledford, Jiri Slaby

From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8c5122e45a10a9262f872b53f151a592e870f905 upstream.

When this code was reworked for IBoE support the order of assignments
for the sl_tclass_flowlabel got flipped around resulting in
TClass & FlowLabel being permanently set to 0 in the packet headers.

This breaks IB routers that rely on these headers, but only affects
kernel users - libmlx4 does this properly for user space.

Fixes: fa417f7b520e ("IB/mlx4: Add support for IBoE")
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/infiniband/hw/mlx4/ah.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index 890c23b3d714..f55d69500a5f 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -65,6 +65,7 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
 
 	ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
 	ah->av.ib.g_slid  = ah_attr->src_path_bits;
+	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
 	if (ah_attr->ah_flags & IB_AH_GRH) {
 		ah->av.ib.g_slid   |= 0x80;
 		ah->av.ib.gid_index = ah_attr->grh.sgid_index;
@@ -82,7 +83,6 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
 		       !(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
 			--ah->av.ib.stat_rate;
 	}
-	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
 
 	return &ah->ibah;
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 55/88] powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (53 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 54/88] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 56/88] powerpc/pseries: Fix PCI config address for DDW Jiri Slaby
                   ` (34 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Guilherme G. Piccoli, Michael Ellerman, Jiri Slaby

From: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8445a87f7092bc8336ea1305be9306f26b846d93 upstream.

Commit 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn")
changed the pci_dn struct by removing its EEH-related members.
As part of this clean-up, DDW mechanism was modified to read the device
configuration address from eeh_dev struct.

As a consequence, now if we disable EEH mechanism on kernel command-line
for example, the DDW mechanism will fail, generating a kernel oops by
dereferencing a NULL pointer (which turns to be the eeh_dev pointer).

This patch just changes the configuration address calculation on DDW
functions to a manual calculation based on pci_dn members instead of
using eeh_dev-based address.

No functional changes were made. This was tested on pSeries, both
in PHyp and qemu guest.

Fixes: 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn")
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/platforms/pseries/iommu.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 261c5095d5d3..88cbecbdbd6f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -861,7 +861,8 @@ machine_arch_initcall(pseries, find_existing_ddw_windows);
 static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 			struct ddw_query_response *query)
 {
-	struct eeh_dev *edev;
+	struct device_node *dn;
+	struct pci_dn *pdn;
 	u32 cfg_addr;
 	u64 buid;
 	int ret;
@@ -872,11 +873,10 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 	 * Retrieve them from the pci device, not the node with the
 	 * dma-window property
 	 */
-	edev = pci_dev_to_eeh_dev(dev);
-	cfg_addr = edev->config_addr;
-	if (edev->pe_config_addr)
-		cfg_addr = edev->pe_config_addr;
-	buid = edev->phb->buid;
+	dn = pci_device_to_OF_node(dev);
+	pdn = PCI_DN(dn);
+	buid = pdn->phb->buid;
+	cfg_addr = (pdn->busno << 8) | pdn->devfn;
 
 	ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
@@ -890,7 +890,8 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 			struct ddw_create_response *create, int page_shift,
 			int window_shift)
 {
-	struct eeh_dev *edev;
+	struct device_node *dn;
+	struct pci_dn *pdn;
 	u32 cfg_addr;
 	u64 buid;
 	int ret;
@@ -901,11 +902,10 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 	 * Retrieve them from the pci device, not the node with the
 	 * dma-window property
 	 */
-	edev = pci_dev_to_eeh_dev(dev);
-	cfg_addr = edev->config_addr;
-	if (edev->pe_config_addr)
-		cfg_addr = edev->pe_config_addr;
-	buid = edev->phb->buid;
+	dn = pci_device_to_OF_node(dev);
+	pdn = PCI_DN(dn);
+	buid = pdn->phb->buid;
+	cfg_addr = (pdn->busno << 8) | pdn->devfn;
 
 	do {
 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 56/88] powerpc/pseries: Fix PCI config address for DDW
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (54 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 55/88] powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 57/88] USB: EHCI: declare hostpc register as zero-length array Jiri Slaby
                   ` (33 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Gavin Shan, Michael Ellerman, Jiri Slaby

From: Gavin Shan <gwshan@linux.vnet.ibm.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8a934efe94347eee843aeea65bdec8077a79e259 upstream.

In commit 8445a87f7092 "powerpc/iommu: Remove the dependency on EEH
struct in DDW mechanism", the PE address was replaced with the PCI
config address in order to remove dependency on EEH. According to PAPR
spec, firmware (pHyp or QEMU) should accept "xxBBSSxx" format PCI config
address, not "xxxxBBSS" provided by the patch. Note that "BB" is PCI bus
number and "SS" is the combination of slot and function number.

This fixes the PCI address passed to DDW RTAS calls.

Fixes: 8445a87f7092 ("powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism")
Reported-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Tested-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/platforms/pseries/iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 88cbecbdbd6f..c06f9e75f8b1 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -876,7 +876,7 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 	dn = pci_device_to_OF_node(dev);
 	pdn = PCI_DN(dn);
 	buid = pdn->phb->buid;
-	cfg_addr = (pdn->busno << 8) | pdn->devfn;
+	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
 
 	ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
@@ -905,7 +905,7 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 	dn = pci_device_to_OF_node(dev);
 	pdn = PCI_DN(dn);
 	buid = pdn->phb->buid;
-	cfg_addr = (pdn->busno << 8) | pdn->devfn;
+	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
 
 	do {
 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 57/88] USB: EHCI: declare hostpc register as zero-length array
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (55 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 56/88] powerpc/pseries: Fix PCI config address for DDW Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 58/88] x86, build: copy ldlinux.c32 to image.iso Jiri Slaby
                   ` (32 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Alan Stern, Jiri Slaby

From: Alan Stern <stern@rowland.harvard.edu>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7e8b3dfef16375dbfeb1f36a83eb9f27117c51fd upstream.

The HOSTPC extension registers found in some EHCI implementations form
a variable-length array, with one element for each port.  Therefore
the hostpc field in struct ehci_regs should be declared as a
zero-length array, not a single-element array.

This fixes a problem reported by UBSAN.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Wilfried Klaebe <linux-kernel@lebenslange-mailadresse.de>
Tested-by: Wilfried Klaebe <linux-kernel@lebenslange-mailadresse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/usb/ehci_def.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h
index daec99af5d54..1c88b177cb9c 100644
--- a/include/linux/usb/ehci_def.h
+++ b/include/linux/usb/ehci_def.h
@@ -178,11 +178,11 @@ struct ehci_regs {
  * PORTSCx
  */
 	/* HOSTPC: offset 0x84 */
-	u32		hostpc[1];	/* HOSTPC extension */
+	u32		hostpc[0];	/* HOSTPC extension */
 #define HOSTPC_PHCD	(1<<22)		/* Phy clock disable */
 #define HOSTPC_PSPD	(3<<25)		/* Port speed detection */
 
-	u32		reserved5[16];
+	u32		reserved5[17];
 
 	/* USBMODE_EX: offset 0xc8 */
 	u32		usbmode_ex;	/* USB Device mode extension */
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 58/88] x86, build: copy ldlinux.c32 to image.iso
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (56 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 57/88] USB: EHCI: declare hostpc register as zero-length array Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 59/88] kprobes/x86: Clear TF bit in fault on single-stepping Jiri Slaby
                   ` (31 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, H. Peter Anvin, Jiri Slaby

From: "H. Peter Anvin" <hpa@zytor.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 9c77679cadb118c0aa99e6f88533d91765a131ba upstream.

For newer versions of Syslinux, we need ldlinux.c32 in addition to
isolinux.bin to reside on the boot disk, so if the latter is found,
copy it, too, to the isoimage tree.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/boot/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 6cf0111783d3..368f3582c93e 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -168,6 +168,9 @@ isoimage: $(obj)/bzImage
 	for i in lib lib64 share end ; do \
 		if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
 			cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
+			if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
+				cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
+			fi ; \
 			break ; \
 		fi ; \
 		if [ $$i = end ] ; then exit 1 ; fi ; \
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 59/88] kprobes/x86: Clear TF bit in fault on single-stepping
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (57 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 58/88] x86, build: copy ldlinux.c32 to image.iso Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 60/88] x86/amd_nb: Fix boot crash on non-AMD systems Jiri Slaby
                   ` (30 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Masami Hiramatsu, Alexander Shishkin,
	Andy Lutomirski, Arnaldo Carvalho de Melo, Borislav Petkov,
	Brian Gerst, Denys Vlasenko, H . Peter Anvin, Jiri Olsa,
	Linus Torvalds, Peter Zijlstra, Stephane Eranian,
	Thomas Gleixner, Vince Weaver, systemtap, Ingo Molnar,
	Jiri Slaby

From: Masami Hiramatsu <mhiramat@kernel.org>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit dcfc47248d3f7d28df6f531e6426b933de94370d upstream.

Fix kprobe_fault_handler() to clear the TF (trap flag) bit of
the flags register in the case of a fault fixup on single-stepping.

If we put a kprobe on the instruction which caused a
page fault (e.g. actual mov instructions in copy_user_*),
that fault happens on the single-stepping buffer. In this
case, kprobes resets running instance so that the CPU can
retry execution on the original ip address.

However, current code forgets to reset the TF bit. Since this
fault happens with TF bit set for enabling single-stepping,
when it retries, it causes a debug exception and kprobes
can not handle it because it already reset itself.

On the most of x86-64 platform, it can be easily reproduced
by using kprobe tracer. E.g.

  # cd /sys/kernel/debug/tracing
  # echo p copy_user_enhanced_fast_string+5 > kprobe_events
  # echo 1 > events/kprobes/enable

And you'll see a kernel panic on do_debug(), since the debug
trap is not handled by kprobes.

To fix this problem, we just need to clear the TF bit when
resetting running kprobe.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: systemtap@sourceware.org
Link: http://lkml.kernel.org/r/20160611140648.25885.37482.stgit@devbox
[ Updated the comments. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kernel/kprobes/core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 490fee15fea5..6cd32acb376f 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -911,7 +911,19 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 		 * normal page fault.
 		 */
 		regs->ip = (unsigned long)cur->addr;
+		/*
+		 * Trap flag (TF) has been set here because this fault
+		 * happened where the single stepping will be done.
+		 * So clear it by resetting the current kprobe:
+		 */
+		regs->flags &= ~X86_EFLAGS_TF;
+
+		/*
+		 * If the TF flag was set before the kprobe hit,
+		 * don't touch it:
+		 */
 		regs->flags |= kcb->kprobe_old_flags;
+
 		if (kcb->kprobe_status == KPROBE_REENTER)
 			restore_previous_kprobe(kcb);
 		else
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 60/88] x86/amd_nb: Fix boot crash on non-AMD systems
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (58 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 59/88] kprobes/x86: Clear TF bit in fault on single-stepping Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 61/88] make nfs_atomic_open() call d_drop() on all ->open_context() errors Jiri Slaby
                   ` (29 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Borislav Petkov, Linus Torvalds, Peter Zijlstra,
	Thomas Gleixner, Ingo Molnar, Jiri Slaby

From: Borislav Petkov <bp@suse.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 1ead852dd88779eda12cb09cc894a03d9abfe1ec upstream.

Fix boot crash that triggers if this driver is built into a kernel and
run on non-AMD systems.

AMD northbridges users call amd_cache_northbridges() and it returns
a negative value to signal that we weren't able to cache/detect any
northbridges on the system.

At least, it should do so as all its callers expect it to do so. But it
does return a negative value only when kmalloc() fails.

Fix it to return -ENODEV if there are no NBs cached as otherwise, amd_nb
users like amd64_edac, for example, which relies on it to know whether
it should load or not, gets loaded on systems like Intel Xeons where it
shouldn't.

Reported-and-tested-by: Tony Battersby <tonyb@cybernetics.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1466097230-5333-2-git-send-email-bp@alien8.de
Link: https://lkml.kernel.org/r/5761BEB0.9000807@cybernetics.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kernel/amd_nb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 6523534671b6..29957e8e2fc5 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -69,8 +69,8 @@ int amd_cache_northbridges(void)
 	while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
 		i++;
 
-	if (i == 0)
-		return 0;
+	if (!i)
+		return -ENODEV;
 
 	nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
 	if (!nb)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 61/88] make nfs_atomic_open() call d_drop() on all ->open_context() errors.
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (59 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 60/88] x86/amd_nb: Fix boot crash on non-AMD systems Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 62/88] NFS: Fix another OPEN_DOWNGRADE bug Jiri Slaby
                   ` (28 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Al Viro, Al Viro, Trond Myklebust, Anna Schumaker,
	Jiri Slaby

From: Al Viro <viro@ZenIV.linux.org.uk>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d20cb71dbf3487f24549ede1a8e2d67579b4632e upstream.

In "NFSv4: Move dentry instantiation into the NFSv4-specific atomic open code"
unconditional d_drop() after the ->open_context() had been removed.  It had
been correct for success cases (there ->open_context() itself had been doing
dcache manipulations), but not for error ones.  Only one of those (ENOENT)
got a compensatory d_drop() added in that commit, but in fact it should've
been done for all errors.  As it is, the case of O_CREAT non-exclusive open
on a hashed negative dentry racing with e.g. symlink creation from another
client ended up with ->open_context() getting an error and proceeding to
call nfs_lookup().  On a hashed dentry, which would've instantly triggered
BUG_ON() in d_materialise_unique() (or, these days, its equivalent in
d_splice_alias()).

Tested-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 fs/nfs/dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index cf6ede69a2e2..b9670301d7d3 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1483,9 +1483,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
 		err = PTR_ERR(inode);
 		trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
 		put_nfs_open_context(ctx);
+		d_drop(dentry);
 		switch (err) {
 		case -ENOENT:
-			d_drop(dentry);
 			d_add(dentry, NULL);
 			break;
 		case -EISDIR:
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 62/88] NFS: Fix another OPEN_DOWNGRADE bug
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (60 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 61/88] make nfs_atomic_open() call d_drop() on all ->open_context() errors Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 63/88] ARM: 8578/1: mm: ensure pmd_present only checks the valid bit Jiri Slaby
                   ` (27 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Trond Myklebust, Anna Schumaker, Jiri Slaby

From: Trond Myklebust <trond.myklebust@primarydata.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e547f2628327fec6afd2e03b46f113f614cca05b upstream.

Olga Kornievskaia reports that the following test fails to trigger
an OPEN_DOWNGRADE on the wire, and only triggers the final CLOSE.

	fd0 = open(foo, RDRW)   -- should be open on the wire for "both"
	fd1 = open(foo, RDONLY)  -- should be open on the wire for "read"
	close(fd0) -- should trigger an open_downgrade
	read(fd1)
	close(fd1)

The issue is that we're missing a check for whether or not the current
state transitioned from an O_RDWR state as opposed to having transitioned
from a combination of O_RDONLY and O_WRONLY.

Reported-by: Olga Kornievskaia <aglo@umich.edu>
Fixes: cd9288ffaea4 ("NFSv4: Fix another bug in the close/open_downgrade code")
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 fs/nfs/nfs4proc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ae85a71e5045..a94ec130003b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2569,12 +2569,11 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
 			call_close |= is_wronly;
 		else if (is_wronly)
 			calldata->arg.fmode |= FMODE_WRITE;
+		if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE))
+			call_close |= is_rdwr;
 	} else if (is_rdwr)
 		calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
 
-	if (calldata->arg.fmode == 0)
-		call_close |= is_rdwr;
-
 	if (!nfs4_valid_open_stateid(state))
 		call_close = 0;
 	spin_unlock(&state->owner->so_lock);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 63/88] ARM: 8578/1: mm: ensure pmd_present only checks the valid bit
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (61 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 62/88] NFS: Fix another OPEN_DOWNGRADE bug Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 64/88] mm: Export migrate_page_move_mapping and migrate_page_copy Jiri Slaby
                   ` (26 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Will Deacon, Russell King, Steve Capper,
	Catalin Marinas, Russell King, Jiri Slaby

From: Will Deacon <will.deacon@arm.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 624531886987f0f1b5d01fb598034d039198e090 upstream.

In a subsequent patch, pmd_mknotpresent will clear the valid bit of the
pmd entry, resulting in a not-present entry from the hardware's
perspective. Unfortunately, pmd_present simply checks for a non-zero pmd
value and will therefore continue to return true even after a
pmd_mknotpresent operation. Since pmd_mknotpresent is only used for
managing huge entries, this is only an issue for the 3-level case.

This patch fixes the 3-level pmd_present implementation to take into
account the valid bit. For bisectability, the change is made before the
fix to pmd_mknotpresent.

[catalin.marinas@arm.com: comment update regarding pmd_mknotpresent patch]

Fixes: 8d9625070073 ("ARM: mm: Transparent huge page support for LPAE systems.")
Cc: Russell King <linux@armlinux.org.uk>
Cc: Steve Capper <Steve.Capper@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/arm/include/asm/pgtable-2level.h | 1 +
 arch/arm/include/asm/pgtable-3level.h | 1 +
 arch/arm/include/asm/pgtable.h        | 1 -
 3 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index c98c9c89b95c..3f1b3a4150b6 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -162,6 +162,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 }
 
 #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
+#define pmd_present(pmd)	(pmd_val(pmd))
 
 #define copy_pmd(pmdpd,pmdps)		\
 	do {				\
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 6a171d0afc12..8afa39f81477 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -209,6 +209,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 						: !!(pmd_val(pmd) & (val)))
 #define pmd_isclear(pmd, val)	(!(pmd_val(pmd) & (val)))
 
+#define pmd_present(pmd)	(pmd_isset((pmd), L_PMD_SECT_VALID))
 #define pmd_young(pmd)		(pmd_isset((pmd), PMD_SECT_AF))
 
 #define __HAVE_ARCH_PMD_WRITE
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index a348bfd34f66..5bdf9864fb00 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
-#define pmd_present(pmd)	(pmd_val(pmd))
 
 static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 {
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 64/88] mm: Export migrate_page_move_mapping and migrate_page_copy
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (62 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 63/88] ARM: 8578/1: mm: ensure pmd_present only checks the valid bit Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 65/88] UBIFS: Implement ->migratepage() Jiri Slaby
                   ` (25 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Richard Weinberger, Jiri Slaby

From: Richard Weinberger <richard@nod.at>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 1118dce773d84f39ebd51a9fe7261f9169cb056e upstream.

Export these symbols such that UBIFS can implement
->migratepage.

Signed-off-by: Richard Weinberger <richard@nod.at>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 mm/migrate.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/migrate.c b/mm/migrate.c
index 0c14c0e1bdd6..71a2533ca8f5 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -399,6 +399,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
 
 	return MIGRATEPAGE_SUCCESS;
 }
+EXPORT_SYMBOL(migrate_page_move_mapping);
 
 /*
  * The expected number of remaining references is the same as that
@@ -549,6 +550,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
 	if (PageWriteback(newpage))
 		end_page_writeback(newpage);
 }
+EXPORT_SYMBOL(migrate_page_copy);
 
 /************************************************************
  *                    Migration functions
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 65/88] UBIFS: Implement ->migratepage()
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (63 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 64/88] mm: Export migrate_page_move_mapping and migrate_page_copy Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 66/88] scsi: remove scsi_end_request Jiri Slaby
                   ` (24 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Kirill A. Shutemov, Richard Weinberger, Jiri Slaby

From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 4ac1c17b2044a1b4b2fbed74451947e905fc2992 upstream.

During page migrations UBIFS might get confused
and the following assert triggers:
[  213.480000] UBIFS assert failed in ubifs_set_page_dirty at 1451 (pid 436)
[  213.490000] CPU: 0 PID: 436 Comm: drm-stress-test Not tainted 4.4.4-00176-geaa802524636-dirty #1008
[  213.490000] Hardware name: Allwinner sun4i/sun5i Families
[  213.490000] [<c0015e70>] (unwind_backtrace) from [<c0012cdc>] (show_stack+0x10/0x14)
[  213.490000] [<c0012cdc>] (show_stack) from [<c02ad834>] (dump_stack+0x8c/0xa0)
[  213.490000] [<c02ad834>] (dump_stack) from [<c0236ee8>] (ubifs_set_page_dirty+0x44/0x50)
[  213.490000] [<c0236ee8>] (ubifs_set_page_dirty) from [<c00fa0bc>] (try_to_unmap_one+0x10c/0x3a8)
[  213.490000] [<c00fa0bc>] (try_to_unmap_one) from [<c00fadb4>] (rmap_walk+0xb4/0x290)
[  213.490000] [<c00fadb4>] (rmap_walk) from [<c00fb1bc>] (try_to_unmap+0x64/0x80)
[  213.490000] [<c00fb1bc>] (try_to_unmap) from [<c010dc28>] (migrate_pages+0x328/0x7a0)
[  213.490000] [<c010dc28>] (migrate_pages) from [<c00d0cb0>] (alloc_contig_range+0x168/0x2f4)
[  213.490000] [<c00d0cb0>] (alloc_contig_range) from [<c010ec00>] (cma_alloc+0x170/0x2c0)
[  213.490000] [<c010ec00>] (cma_alloc) from [<c001a958>] (__alloc_from_contiguous+0x38/0xd8)
[  213.490000] [<c001a958>] (__alloc_from_contiguous) from [<c001ad44>] (__dma_alloc+0x23c/0x274)
[  213.490000] [<c001ad44>] (__dma_alloc) from [<c001ae08>] (arm_dma_alloc+0x54/0x5c)
[  213.490000] [<c001ae08>] (arm_dma_alloc) from [<c035cecc>] (drm_gem_cma_create+0xb8/0xf0)
[  213.490000] [<c035cecc>] (drm_gem_cma_create) from [<c035cf20>] (drm_gem_cma_create_with_handle+0x1c/0xe8)
[  213.490000] [<c035cf20>] (drm_gem_cma_create_with_handle) from [<c035d088>] (drm_gem_cma_dumb_create+0x3c/0x48)
[  213.490000] [<c035d088>] (drm_gem_cma_dumb_create) from [<c0341ed8>] (drm_ioctl+0x12c/0x444)
[  213.490000] [<c0341ed8>] (drm_ioctl) from [<c0121adc>] (do_vfs_ioctl+0x3f4/0x614)
[  213.490000] [<c0121adc>] (do_vfs_ioctl) from [<c0121d30>] (SyS_ioctl+0x34/0x5c)
[  213.490000] [<c0121d30>] (SyS_ioctl) from [<c000f2c0>] (ret_fast_syscall+0x0/0x34)

UBIFS is using PagePrivate() which can have different meanings across
filesystems. Therefore the generic page migration code cannot handle this
case correctly.
We have to implement our own migration function which basically does a
plain copy but also duplicates the page private flag.
UBIFS is not a block device filesystem and cannot use buffer_migrate_page().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
[rw: Massaged changelog, build fixes, etc...]
Signed-off-by: Richard Weinberger <richard@nod.at>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 fs/ubifs/file.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b56eb6275744..c0d8fde3e6d9 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -54,6 +54,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
+#include <linux/migrate.h>
 
 static int read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
@@ -1423,6 +1424,26 @@ static int ubifs_set_page_dirty(struct page *page)
 	return ret;
 }
 
+#ifdef CONFIG_MIGRATION
+static int ubifs_migrate_page(struct address_space *mapping,
+		struct page *newpage, struct page *page, enum migrate_mode mode)
+{
+	int rc;
+
+	rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
+	if (rc != MIGRATEPAGE_SUCCESS)
+		return rc;
+
+	if (PagePrivate(page)) {
+		ClearPagePrivate(page);
+		SetPagePrivate(newpage);
+	}
+
+	migrate_page_copy(newpage, page);
+	return MIGRATEPAGE_SUCCESS;
+}
+#endif
+
 static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
 {
 	/*
@@ -1559,6 +1580,9 @@ const struct address_space_operations ubifs_file_address_operations = {
 	.write_end      = ubifs_write_end,
 	.invalidatepage = ubifs_invalidatepage,
 	.set_page_dirty = ubifs_set_page_dirty,
+#ifdef CONFIG_MIGRATION
+	.migratepage	= ubifs_migrate_page,
+#endif
 	.releasepage    = ubifs_releasepage,
 };
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 66/88] scsi: remove scsi_end_request
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (64 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 65/88] UBIFS: Implement ->migratepage() Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:15 ` [PATCH 3.12 67/88] scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands Jiri Slaby
                   ` (23 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Christoph Hellwig, Jack Wang, Jiri Slaby

From: Christoph Hellwig <hch@lst.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit bc85dc500f9df9b2eec15077e5046672c46adeaa upstream.

By folding scsi_end_request into its only caller we can significantly clean
up the completion logic.  We can use simple goto labels now to only have
a single place to finish or requeue command there instead of the previous
convoluted logic.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[jwang: backport to 3.12]
Signed-off-by: Jack Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/scsi/scsi_lib.c | 113 +++++++++++++-----------------------------------
 1 file changed, 31 insertions(+), 82 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 2b01c88ad416..4b7893364c7a 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -540,66 +540,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
 
 static void __scsi_release_buffers(struct scsi_cmnd *, int);
 
-/*
- * Function:    scsi_end_request()
- *
- * Purpose:     Post-processing of completed commands (usually invoked at end
- *		of upper level post-processing and scsi_io_completion).
- *
- * Arguments:   cmd	 - command that is complete.
- *              error    - 0 if I/O indicates success, < 0 for I/O error.
- *              bytes    - number of bytes of completed I/O
- *		requeue  - indicates whether we should requeue leftovers.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns:     cmd if requeue required, NULL otherwise.
- *
- * Notes:       This is called for block device requests in order to
- *              mark some number of sectors as complete.
- * 
- *		We are guaranteeing that the request queue will be goosed
- *		at some point during this call.
- * Notes:	If cmd was requeued, upon return it will be a stale pointer.
- */
-static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
-					  int bytes, int requeue)
-{
-	struct request_queue *q = cmd->device->request_queue;
-	struct request *req = cmd->request;
-
-	/*
-	 * If there are blocks left over at the end, set up the command
-	 * to queue the remainder of them.
-	 */
-	if (blk_end_request(req, error, bytes)) {
-		/* kill remainder if no retrys */
-		if (error && scsi_noretry_cmd(cmd))
-			blk_end_request_all(req, error);
-		else {
-			if (requeue) {
-				/*
-				 * Bleah.  Leftovers again.  Stick the
-				 * leftovers in the front of the
-				 * queue, and goose the queue again.
-				 */
-				scsi_release_buffers(cmd);
-				scsi_requeue_command(q, cmd);
-				cmd = NULL;
-			}
-			return cmd;
-		}
-	}
-
-	/*
-	 * This will goose the queue request function at the end, so we don't
-	 * need to worry about launching another command.
-	 */
-	__scsi_release_buffers(cmd, 0);
-	scsi_next_command(cmd);
-	return NULL;
-}
-
 static inline unsigned int scsi_sgtable_index(unsigned short nents)
 {
 	unsigned int index;
@@ -751,16 +691,9 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
  *
  * Returns:     Nothing
  *
- * Notes:       This function is matched in terms of capabilities to
- *              the function that created the scatter-gather list.
- *              In other words, if there are no bounce buffers
- *              (the normal case for most drivers), we don't need
- *              the logic to deal with cleaning up afterwards.
- *
- *		We must call scsi_end_request().  This will finish off
- *		the specified number of sectors.  If we are done, the
- *		command block will be released and the queue function
- *		will be goosed.  If we are not done then we have to
+ * Notes:       We will finish off the specified number of sectors.  If we
+ *		are done, the command block will be released and the queue
+ *		function will be goosed.  If we are not done then we have to
  *		figure out what to do next:
  *
  *		a) We can call scsi_requeue_command().  The request
@@ -769,7 +702,7 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
  *		   be used if we made forward progress, or if we want
  *		   to switch from READ(10) to READ(6) for example.
  *
- *		b) We can call scsi_queue_insert().  The request will
+ *		b) We can call __scsi_queue_insert().  The request will
  *		   be put back on the queue and retried using the same
  *		   command as before, possibly after a delay.
  *
@@ -873,12 +806,25 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 	}
 
 	/*
-	 * A number of bytes were successfully read.  If there
-	 * are leftovers and there is some kind of error
-	 * (result != 0), retry the rest.
+	 * If we finished all bytes in the request we are done now.
 	 */
-	if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
-		return;
+	if (!blk_end_request(req, error, good_bytes))
+		goto next_command;
+
+	/*
+	 * Kill remainder if no retrys.
+	 */
+	if (error && scsi_noretry_cmd(cmd)) {
+		blk_end_request_all(req, error);
+		goto next_command;
+	}
+
+	/*
+	 * If there had been no error, but we have leftover bytes in the
+	 * requeues just queue the command up again.
+	 */
+	if (result == 0)
+		goto requeue;
 
 	error = __scsi_error_from_host_byte(cmd, result);
 
@@ -1000,7 +946,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 	switch (action) {
 	case ACTION_FAIL:
 		/* Give up and fail the remainder of the request */
-		scsi_release_buffers(cmd);
 		if (!(req->cmd_flags & REQ_QUIET)) {
 			if (description)
 				scmd_printk(KERN_INFO, cmd, "%s\n",
@@ -1010,12 +955,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 				scsi_print_sense("", cmd);
 			scsi_print_command(cmd);
 		}
-		if (blk_end_request_err(req, error))
-			scsi_requeue_command(q, cmd);
-		else
-			scsi_next_command(cmd);
-		break;
+		if (!blk_end_request_err(req, error))
+			goto next_command;
+		/*FALLTHRU*/
 	case ACTION_REPREP:
+	requeue:
 		/* Unprep the request and put it back at the head of the queue.
 		 * A new command will be prepared and issued.
 		 */
@@ -1031,6 +975,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 		__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
 		break;
 	}
+	return;
+
+next_command:
+	__scsi_release_buffers(cmd, 0);
+	scsi_next_command(cmd);
 }
 
 static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 67/88] scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (65 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 66/88] scsi: remove scsi_end_request Jiri Slaby
@ 2016-07-14  8:15 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 68/88] Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address Jiri Slaby
                   ` (22 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:15 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, James Bottomley, James E . J . Bottomley,
	Martin K . Petersen, Jack Wang, Jiri Slaby

From: James Bottomley <James.Bottomley@HansenPartnership.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit a621bac3044ed6f7ec5fa0326491b2d4838bfa93 upstream.

When SCSI was written, all commands coming from the filesystem
(REQ_TYPE_FS commands) had data.  This meant that our signal for needing
to complete the command was the number of bytes completed being equal to
the number of bytes in the request.  Unfortunately, with the advent of
flush barriers, we can now get zero length REQ_TYPE_FS commands, which
confuse this logic because they satisfy the condition every time.  This
means they never get retried even for retryable conditions, like UNIT
ATTENTION because we complete them early assuming they're done.  Fix
this by special casing the early completion condition to recognise zero
length commands with errors and let them drop through to the retry code.

Cc: stable@vger.kernel.org
Reported-by: Sebastian Parschauer <s.parschauer@gmx.de>
Signed-off-by: James E.J. Bottomley <jejb@linux.vnet.ibm.com>
Tested-by: Jack Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
[ jwang: backport from upstream 4.7 to fix scsi resize issue ]
Signed-off-by: Jack Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/scsi/scsi_lib.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4b7893364c7a..aeff39767588 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -806,9 +806,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 	}
 
 	/*
-	 * If we finished all bytes in the request we are done now.
+	 * special case: failed zero length commands always need to
+	 * drop down into the retry code. Otherwise, if we finished
+	 * all bytes in the request we are done now.
 	 */
-	if (!blk_end_request(req, error, good_bytes))
+	if (!(blk_rq_bytes(req) == 0 && error) &&
+	    !blk_end_request(req, error, good_bytes))
 		goto next_command;
 
 	/*
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 68/88] Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (66 preceding siblings ...)
  2016-07-14  8:15 ` [PATCH 3.12 67/88] scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 69/88] USB: usbfs: fix potential infoleak in devio Jiri Slaby
                   ` (21 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, daniel, David S . Miller, Jiri Slaby

From: daniel <daniel@dd-wrt.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 0888d5f3c0f183ea6177355752ada433d370ac89 ]

The bridge is falsly dropping ipv6 mulitcast packets if there is:
 1. No ipv6 address assigned on the brigde.
 2. No external mld querier present.
 3. The internal querier enabled.

When the bridge fails to build mld queries, because it has no
ipv6 address, it slilently returns, but keeps the local querier enabled.
This specific case causes confusing packet loss.

Ipv6 multicast snooping can only work if:
 a) An external querier is present
 OR
 b) The bridge has an ipv6 address an is capable of sending own queries

Otherwise it has to forward/flood the ipv6 multicast traffic,
because snooping cannot work.

This patch fixes the issue by adding a flag to the bridge struct that
indicates that there is currently no ipv6 address assinged to the bridge
and returns a false state for the local querier in
__br_multicast_querier_exists().

Special thanks to Linus Lüssing.

Fixes: d1d81d4c3dd8 ("bridge: check return value of ipv6_dev_get_saddr()")
Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
Acked-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bridge/br_multicast.c |  4 ++++
 net/bridge/br_private.h   | 25 ++++++++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f2c104900163..91fed8147c39 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -449,8 +449,11 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
 	if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
 			       &ip6h->saddr)) {
 		kfree_skb(skb);
+		br->has_ipv6_addr = 0;
 		return NULL;
 	}
+
+	br->has_ipv6_addr = 1;
 	ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
 
 	hopopt = (u8 *)(ip6h + 1);
@@ -1776,6 +1779,7 @@ void br_multicast_init(struct net_bridge *br)
 #if IS_ENABLED(CONFIG_IPV6)
 	br->ip6_querier.delay_time = 0;
 #endif
+	br->has_ipv6_addr = 1;
 
 	spin_lock_init(&br->multicast_lock);
 	setup_timer(&br->multicast_router_timer,
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index f02acd7c5472..8b7db15212b9 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -265,6 +265,7 @@ struct net_bridge
 	u8				multicast_disabled:1;
 	u8				multicast_querier:1;
 	u8				multicast_query_use_ifaddr:1;
+	u8				has_ipv6_addr:1;
 
 	u32				hash_elasticity;
 	u32				hash_max;
@@ -512,10 +513,22 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
 
 static inline bool
 __br_multicast_querier_exists(struct net_bridge *br,
-			      struct bridge_mcast_querier *querier)
-{
+				struct bridge_mcast_querier *querier,
+				const bool is_ipv6)
+{
+	bool own_querier_enabled;
+
+	if (br->multicast_querier) {
+		if (is_ipv6 && !br->has_ipv6_addr)
+			own_querier_enabled = false;
+		else
+			own_querier_enabled = true;
+	} else {
+		own_querier_enabled = false;
+	}
+
 	return time_is_before_jiffies(querier->delay_time) &&
-	       (br->multicast_querier || timer_pending(&querier->timer));
+	       (own_querier_enabled || timer_pending(&querier->timer));
 }
 
 static inline bool br_multicast_querier_exists(struct net_bridge *br,
@@ -523,10 +536,12 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
 {
 	switch (eth->h_proto) {
 	case (htons(ETH_P_IP)):
-		return __br_multicast_querier_exists(br, &br->ip4_querier);
+		return __br_multicast_querier_exists(br,
+			&br->ip4_querier, false);
 #if IS_ENABLED(CONFIG_IPV6)
 	case (htons(ETH_P_IPV6)):
-		return __br_multicast_querier_exists(br, &br->ip6_querier);
+		return __br_multicast_querier_exists(br,
+			&br->ip6_querier, true);
 #endif
 	default:
 		return false;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 69/88] USB: usbfs: fix potential infoleak in devio
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (67 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 68/88] Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 70/88] ktime: export ktime_divns Jiri Slaby
                   ` (20 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Kangjie Lu, Kangjie Lu, Greg Kroah-Hartman, Jiri Slaby

From: Kangjie Lu <kangjielu@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 681fef8380eb818c0b845fca5d2ab1dcbab114ee upstream.

The stack object “ci” has a total size of 8 bytes. Its last 3 bytes
are padding bytes which are not initialized and leaked to userland
via “copy_to_user”.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/core/devio.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index c076050cab47..a7b10c18759c 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1106,10 +1106,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
 
 static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 {
-	struct usbdevfs_connectinfo ci = {
-		.devnum = ps->dev->devnum,
-		.slow = ps->dev->speed == USB_SPEED_LOW
-	};
+	struct usbdevfs_connectinfo ci;
+
+	memset(&ci, 0, sizeof(ci));
+	ci.devnum = ps->dev->devnum;
+	ci.slow = ps->dev->speed == USB_SPEED_LOW;
 
 	if (copy_to_user(arg, &ci, sizeof(ci)))
 		return -EFAULT;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 70/88] ktime: export ktime_divns
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (68 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 69/88] USB: usbfs: fix potential infoleak in devio Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 71/88] ALSA: hrtimer: Handle start/stop more properly Jiri Slaby
                   ` (19 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Jiri Slaby, Takashi Iwai, Thomas Gleixner, John Stultz

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

ktime_divns was exported in upstream as a side-effect of commit
166afb64511eef08e13331b970c44fe91cea45ef (ktime: Sanitize
ktime_to_us/ms conversion). But we do not want the commit given ktime
is not nanoseconds in 3.12 yet.

So we only export the function here as it is needed by upstream commit
d2c5cf88d5282de258f4eb6ab40040b80a075cd8 (ALSA: hrtimer: Handle
start/stop more properly):
ERROR: "ktime_divns" [sound/core/snd-hrtimer.ko] undefined!

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
---
 kernel/hrtimer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index aa149222cd8e..63903212933a 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -349,6 +349,7 @@ u64 ktime_divns(const ktime_t kt, s64 div)
 
 	return dclc;
 }
+EXPORT_SYMBOL_GPL(ktime_divns);
 #endif /* BITS_PER_LONG >= 64 */
 
 /*
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 71/88] ALSA: hrtimer: Handle start/stop more properly
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (69 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 70/88] ktime: export ktime_divns Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 72/88] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS Jiri Slaby
                   ` (18 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Takashi Iwai, Jiri Slaby

From: Takashi Iwai <tiwai@suse.de>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit d2c5cf88d5282de258f4eb6ab40040b80a075cd8 upstream.

This patch tries to address the still remaining issues in ALSA hrtimer
driver:
- Spurious use-after-free was detected in hrtimer callback
- Incorrect rescheduling due to delayed start
- WARN_ON() is triggered in hrtimer_forward() invoked in hrtimer
  callback

The first issue happens only when the new timer is scheduled even
while hrtimer is being closed.  It's related with the second and third
items; since ALSA timer core invokes hw.start callback during hrtimer
interrupt, this may result in the explicit call of hrtimer_start().

Also, the similar problem is seen for the stop; ALSA timer core
invokes hw.stop callback even in the hrtimer handler, too.  Since we
must not call the synced hrtimer_cancel() in such a context, it's just
a hrtimer_try_to_cancel() call that doesn't properly work.

Another culprit of the second and third items is the call of
hrtimer_forward_now() before snd_timer_interrupt().  The timer->stick
value may change during snd_timer_interrupt() call, but this
possibility is ignored completely.

For covering these subtle and messy issues, the following changes have
been done in this patch:
- A new flag, in_callback, is introduced in the private data to
  indicate that the hrtimer handler is being processed.
- Both start and stop callbacks skip when called from (during)
  in_callback flag.
- The hrtimer handler returns properly HRTIMER_RESTART and NORESTART
  depending on the running state now.
- The hrtimer handler reprograms the expiry properly after
  snd_timer_interrupt() call, instead of before.
- The close callback clears running flag and sets in_callback flag
  to block any further start/stop calls.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 sound/core/hrtimer.c | 56 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 14d483d6b3b0..327bbf797c6c 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -38,37 +38,53 @@ static unsigned int resolution;
 struct snd_hrtimer {
 	struct snd_timer *timer;
 	struct hrtimer hrt;
-	atomic_t running;
+	bool in_callback;
 };
 
 static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
 {
 	struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
 	struct snd_timer *t = stime->timer;
-	unsigned long oruns;
-
-	if (!atomic_read(&stime->running))
-		return HRTIMER_NORESTART;
-
-	oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
-	snd_timer_interrupt(stime->timer, t->sticks * oruns);
+	ktime_t delta;
+	unsigned long ticks;
+	enum hrtimer_restart ret = HRTIMER_NORESTART;
+
+	spin_lock(&t->lock);
+	if (!t->running)
+		goto out; /* fast path */
+	stime->in_callback = true;
+	ticks = t->sticks;
+	spin_unlock(&t->lock);
+
+	/* calculate the drift */
+	delta = ktime_sub(hrt->base->get_time(), hrtimer_get_expires(hrt));
+	if (delta.tv64 > 0)
+		ticks += ktime_divns(delta, ticks * resolution);
+
+	snd_timer_interrupt(stime->timer, ticks);
+
+	spin_lock(&t->lock);
+	if (t->running) {
+		hrtimer_add_expires_ns(hrt, t->sticks * resolution);
+		ret = HRTIMER_RESTART;
+	}
 
-	if (!atomic_read(&stime->running))
-		return HRTIMER_NORESTART;
-	return HRTIMER_RESTART;
+	stime->in_callback = false;
+ out:
+	spin_unlock(&t->lock);
+	return ret;
 }
 
 static int snd_hrtimer_open(struct snd_timer *t)
 {
 	struct snd_hrtimer *stime;
 
-	stime = kmalloc(sizeof(*stime), GFP_KERNEL);
+	stime = kzalloc(sizeof(*stime), GFP_KERNEL);
 	if (!stime)
 		return -ENOMEM;
 	hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	stime->timer = t;
 	stime->hrt.function = snd_hrtimer_callback;
-	atomic_set(&stime->running, 0);
 	t->private_data = stime;
 	return 0;
 }
@@ -78,6 +94,11 @@ static int snd_hrtimer_close(struct snd_timer *t)
 	struct snd_hrtimer *stime = t->private_data;
 
 	if (stime) {
+		spin_lock_irq(&t->lock);
+		t->running = 0; /* just to be sure */
+		stime->in_callback = 1; /* skip start/stop */
+		spin_unlock_irq(&t->lock);
+
 		hrtimer_cancel(&stime->hrt);
 		kfree(stime);
 		t->private_data = NULL;
@@ -89,18 +110,19 @@ static int snd_hrtimer_start(struct snd_timer *t)
 {
 	struct snd_hrtimer *stime = t->private_data;
 
-	atomic_set(&stime->running, 0);
-	hrtimer_try_to_cancel(&stime->hrt);
+	if (stime->in_callback)
+		return 0;
 	hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
 		      HRTIMER_MODE_REL);
-	atomic_set(&stime->running, 1);
 	return 0;
 }
 
 static int snd_hrtimer_stop(struct snd_timer *t)
 {
 	struct snd_hrtimer *stime = t->private_data;
-	atomic_set(&stime->running, 0);
+
+	if (stime->in_callback)
+		return 0;
 	hrtimer_try_to_cancel(&stime->hrt);
 	return 0;
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 72/88] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (70 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 71/88] ALSA: hrtimer: Handle start/stop more properly Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 73/88] ALSA: timer: Fix leak in events via snd_timer_user_ccallback Jiri Slaby
                   ` (17 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Kangjie Lu, Kangjie Lu, Takashi Iwai, Jiri Slaby

From: Kangjie Lu <kangjielu@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e upstream.

The stack object “tread” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 sound/core/timer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 10463beae4bb..7bf8186472fb 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1717,6 +1717,7 @@ static int snd_timer_user_params(struct file *file,
 	if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
 		if (tu->tread) {
 			struct snd_timer_tread tread;
+			memset(&tread, 0, sizeof(tread));
 			tread.event = SNDRV_TIMER_EVENT_EARLY;
 			tread.tstamp.tv_sec = 0;
 			tread.tstamp.tv_nsec = 0;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 73/88] ALSA: timer: Fix leak in events via snd_timer_user_ccallback
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (71 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 72/88] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 74/88] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt Jiri Slaby
                   ` (16 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Kangjie Lu, Kangjie Lu, Takashi Iwai, Jiri Slaby

From: Kangjie Lu <kangjielu@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 upstream.

The stack object “r1” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 sound/core/timer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 7bf8186472fb..aa0582c5dd2e 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1218,6 +1218,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
 		tu->tstamp = *tstamp;
 	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
 		return;
+	memset(&r1, 0, sizeof(r1));
 	r1.event = event;
 	r1.tstamp = *tstamp;
 	r1.val = resolution;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 00/88] 3.12.62-stable review
@ 2016-07-14  8:16 Jiri Slaby
  2016-07-14  8:14 ` [PATCH 3.12 01/88] PCI/AER: Clear error status registers during enumeration and restore Jiri Slaby
                   ` (89 more replies)
  0 siblings, 90 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux, shuah.kh, linux-kernel, Jiri Slaby

This is the start of the stable review cycle for the 3.12.62 release.
There are 88 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Mon Jul 18 10:12:31 CEST 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
	http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.62-rc1.xz
and the diffstat can be found below.

thanks,
js

===============


Aaro Koskinen (1):
  drivers: macintosh: rack-meter: limit idle ticks to total ticks

Al Viro (2):
  fix d_walk()/non-delayed __d_free() race
  make nfs_atomic_open() call d_drop() on all ->open_context() errors.

Alan Stern (1):
  USB: EHCI: declare hostpc register as zero-length array

Andrew Goodbody (2):
  usb: musb: Stop bulk endpoint while queue is rotated
  usb: musb: Ensure rx reinit occurs for shared_fifo endpoints

Andrey Ryabinin (1):
  perf/x86: Fix undefined shift on 32-bit kernels

Babu Moger (1):
  sparc/PCI: Fix for panic while enabling SR-IOV

Bernhard Thaler (1):
  Revert "netfilter: ensure number of counters is >0 in do_replace()"

Bjørn Mork (1):
  cdc_ncm: workaround for EM7455 "silent" data interface

Bob Copeland (1):
  mac80211: mesh: flush mesh paths unconditionally

Borislav Petkov (1):
  x86/amd_nb: Fix boot crash on non-AMD systems

Brian King (1):
  SCSI: Increase REPORT_LUNS timeout

Christoph Hellwig (1):
  scsi: remove scsi_end_request

Dan Carpenter (2):
  KEYS: potential uninitialized variable
  ALSA: compress: fix an integer overflow check

Dave Jones (1):
  netfilter: ensure number of counters is >0 in do_replace()

David S. Miller (5):
  sparc64: Fix bootup regressions on some Kconfig combinations.
  sparc64: Fix sparc64_set_context stack handling.
  sparc64: Take ctx_alloc_lock properly in hugetlb_setup().
  sparc: Harden signal return frame checks.
  sparc64: Fix return from trap window fill crashes.

Feng Tang (1):
  net: alx: Work around the DMA RX overflow issue

Florian Westphal (16):
  netfilter: x_tables: don't move to non-existent next rule
  netfilter: x_tables: validate targets of jumps
  netfilter: x_tables: add and use xt_check_entry_offsets
  netfilter: x_tables: kill check_entry helper
  netfilter: x_tables: assert minimum target size
  netfilter: x_tables: add compat version of xt_check_entry_offsets
  netfilter: x_tables: check standard target size too
  netfilter: x_tables: check for bogus target offset
  netfilter: x_tables: validate all offsets and sizes in a rule
  netfilter: x_tables: don't reject valid target size on some
    architectures
  netfilter: arp_tables: simplify translate_compat_table args
  netfilter: ip_tables: simplify translate_compat_table args
  netfilter: ip6_tables: simplify translate_compat_table args
  netfilter: x_tables: xt_compat_match_from_user doesn't need a retval
  netfilter: x_tables: do compat validation via translate_table
  netfilter: x_tables: introduce and use xt_copy_counters_from_user

Gavin Shan (2):
  powerpc/pseries: Fix PCI config address for DDW
  net/qlge: Avoids recursive EEH error

Guilherme G. Piccoli (1):
  powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism

H. Peter Anvin (1):
  x86, build: copy ldlinux.c32 to image.iso

Hannes Frederic Sowa (1):
  udp: prevent skbs lingering in tunnel socket queues

Hans de Goede (1):
  usb: quirks: Add no-lpm quirk for Acer C120 LED Projector

Helge Deller (1):
  parisc: Fix pagefault crash in unaligned __get_user() call

Herbert Xu (1):
  netlink: Fix dump skb leak/double free

Jakub Sitnicki (1):
  ipv6: Skip XFRM lookup if dst_entry in socket cache is valid

James Bottomley (1):
  scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands

James Hogan (1):
  MIPS: KVM: Fix modular KVM under QEMU

Jann Horn (1):
  ecryptfs: forbid opening files without mmap handler

Jason Gunthorpe (1):
  IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs

Javier Martinez Canillas (1):
  macintosh/therm_windtunnel: Export I2C module alias information

Jiri Slaby (2):
  ktime: export ktime_divns
  base: make module_create_drivers_dir race-free

Kangjie Lu (5):
  USB: usbfs: fix potential infoleak in devio
  ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS
  ALSA: timer: Fix leak in events via snd_timer_user_ccallback
  ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt
  rds: fix an infoleak in rds_inc_info_copy

Kirill A. Shutemov (1):
  UBIFS: Implement ->migratepage()

Linus Walleij (1):
  crypto: ux500 - memmove the right size

Lukasz Odzioba (1):
  mm/swap.c: flush lru pvecs on compound page arrival

Marcelo Tosatti (1):
  KVM: x86: expose invariant tsc cpuid bit (v2)

Martin Willi (1):
  mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL

Masami Hiramatsu (1):
  kprobes/x86: Clear TF bit in fault on single-stepping

Mike Frysinger (1):
  sparc: Fix system call tracing register handling.

Oliver Neukum (1):
  HID: elo: kill not flush the work

Palik, Imre (1):
  perf/x86: Honor the architectural performance monitoring version

Paolo Bonzini (1):
  KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS

Prasun Maiti (1):
  wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Ralf Baechle (1):
  MIPS: Fix 64k page support for 32 bit kernels.

Richard Weinberger (1):
  mm: Export migrate_page_move_mapping and migrate_page_copy

Russell Currey (1):
  powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Russell King (1):
  ARM: fix PTRACE_SETVFPREGS on SMP systems

Scott Bauer (1):
  HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES
    commands

Simon Horman (1):
  sit: correct IP protocol used in ipip6_err

Takashi Iwai (1):
  ALSA: hrtimer: Handle start/stop more properly

Taku Izumi (1):
  PCI/AER: Clear error status registers during enumeration and restore

Thomas Huth (2):
  powerpc: Fix definition of SIAR and SDAR registers
  powerpc: Use privileged SPR number for MMCR2

Tom Goff (1):
  ipmr/ip6mr: Initialize the last assert time of mfc entries.

Tony Luck (1):
  EDAC: Remove arbitrary limit on number of channels

Trond Myklebust (1):
  NFS: Fix another OPEN_DOWNGRADE bug

Vladimir Davydov (1):
  signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo

Will Deacon (1):
  ARM: 8578/1: mm: ensure pmd_present only checks the valid bit

Yuchung Cheng (1):
  tcp: record TLP and ER timer stats in v6 stats

daniel (1):
  Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address

 arch/arm/include/asm/pgtable-2level.h        |   1 +
 arch/arm/include/asm/pgtable-3level.h        |   1 +
 arch/arm/include/asm/pgtable.h               |   1 -
 arch/arm/kernel/ptrace.c                     |   2 +-
 arch/mips/include/asm/kvm_host.h             |   1 +
 arch/mips/include/asm/processor.h            |   2 +-
 arch/mips/kvm/kvm_locore.S                   |   1 +
 arch/mips/kvm/kvm_mips.c                     |  11 +-
 arch/mips/kvm/kvm_mips_int.h                 |   2 +
 arch/parisc/kernel/unaligned.c               |  10 +-
 arch/powerpc/include/asm/reg.h               |   6 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c |  51 +++--
 arch/powerpc/platforms/pseries/iommu.c       |  24 +-
 arch/sparc/include/asm/head_64.h             |   4 +
 arch/sparc/include/asm/ttable.h              |   8 +-
 arch/sparc/kernel/Makefile                   |   1 +
 arch/sparc/kernel/cherrs.S                   |  14 +-
 arch/sparc/kernel/entry.S                    |  17 ++
 arch/sparc/kernel/fpu_traps.S                |  11 +-
 arch/sparc/kernel/head_64.S                  |  24 +-
 arch/sparc/kernel/misctrap.S                 |  12 +-
 arch/sparc/kernel/pci.c                      |  17 ++
 arch/sparc/kernel/rtrap_64.S                 |  57 +----
 arch/sparc/kernel/signal32.c                 |  46 ++--
 arch/sparc/kernel/signal_32.c                |  41 ++--
 arch/sparc/kernel/signal_64.c                |  33 ++-
 arch/sparc/kernel/sigutil_32.c               |   9 +-
 arch/sparc/kernel/sigutil_64.c               |  10 +-
 arch/sparc/kernel/spiterrs.S                 |  18 +-
 arch/sparc/kernel/syscalls.S                 |  36 +++
 arch/sparc/kernel/urtt_fill.S                |  98 ++++++++
 arch/sparc/kernel/utrap.S                    |   3 +-
 arch/sparc/kernel/vmlinux.lds.S              |   4 +
 arch/sparc/kernel/winfixup.S                 |   3 +-
 arch/sparc/mm/init_64.c                      |  10 +-
 arch/x86/boot/Makefile                       |   3 +
 arch/x86/kernel/amd_nb.c                     |   4 +-
 arch/x86/kernel/cpu/perf_event_intel.c       |  12 +-
 arch/x86/kernel/kprobes/core.c               |  12 +
 arch/x86/kvm/cpuid.c                         |   8 +-
 arch/x86/kvm/x86.c                           |   5 +
 drivers/base/module.c                        |   8 +-
 drivers/crypto/ux500/hash/hash_core.c        |   4 +-
 drivers/edac/edac_mc_sysfs.c                 |   5 -
 drivers/hid/hid-elo.c                        |   2 +-
 drivers/hid/usbhid/hiddev.c                  |  10 +-
 drivers/infiniband/hw/mlx4/ah.c              |   2 +-
 drivers/macintosh/rack-meter.c               |   1 +
 drivers/macintosh/therm_windtunnel.c         |   1 +
 drivers/net/ethernet/atheros/alx/main.c      |   7 +-
 drivers/net/ethernet/qlogic/qlge/qlge_main.c |   3 +-
 drivers/net/usb/cdc_ncm.c                    |   7 +
 drivers/net/vxlan.c                          |   8 +-
 drivers/net/wireless/mac80211_hwsim.c        |   1 +
 drivers/pci/pci.c                            |   3 +
 drivers/pci/pcie/aer/aerdrv_core.c           |  28 +++
 drivers/pci/probe.c                          |   3 +
 drivers/scsi/scsi_lib.c                      | 116 +++-------
 drivers/scsi/scsi_scan.c                     |   3 +-
 drivers/usb/core/devio.c                     |   9 +-
 drivers/usb/core/quirks.c                    |   3 +
 drivers/usb/musb/musb_host.c                 |  21 +-
 fs/dcache.c                                  |   4 +-
 fs/ecryptfs/kthread.c                        |  13 +-
 fs/nfs/dir.c                                 |   2 +-
 fs/nfs/nfs4proc.c                            |   5 +-
 fs/ubifs/file.c                              |  24 ++
 include/linux/aer.h                          |   5 +
 include/linux/netfilter/x_tables.h           |  12 +-
 include/linux/usb/ehci_def.h                 |   4 +-
 kernel/hrtimer.c                             |   1 +
 kernel/signal.c                              |  14 +-
 mm/migrate.c                                 |   2 +
 mm/swap.c                                    |   9 +-
 net/bridge/br_multicast.c                    |   4 +
 net/bridge/br_private.h                      |  25 ++-
 net/ipv4/ipmr.c                              |   4 +-
 net/ipv4/netfilter/arp_tables.c              | 295 ++++++++----------------
 net/ipv4/netfilter/ip_tables.c               | 323 ++++++++-------------------
 net/ipv4/udp.c                               |   2 +-
 net/ipv6/ip6_output.c                        |  13 +-
 net/ipv6/ip6mr.c                             |   1 +
 net/ipv6/netfilter/ip6_tables.c              | 317 +++++++-------------------
 net/ipv6/sit.c                               |   4 +-
 net/ipv6/tcp_ipv6.c                          |   4 +-
 net/ipv6/udp.c                               |   2 +-
 net/mac80211/mesh.c                          |   4 +
 net/netfilter/x_tables.c                     | 245 +++++++++++++++++++-
 net/netlink/af_netlink.c                     |   7 +-
 net/rds/recv.c                               |   2 +
 net/wireless/wext-core.c                     |  25 ++-
 security/keys/key.c                          |   2 +-
 sound/core/compress_offload.c                |   2 +-
 sound/core/hrtimer.c                         |  56 +++--
 sound/core/timer.c                           |   3 +
 95 files changed, 1260 insertions(+), 1053 deletions(-)
 create mode 100644 arch/sparc/kernel/urtt_fill.S

-- 
2.9.1

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 3.12 74/88] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (72 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 73/88] ALSA: timer: Fix leak in events via snd_timer_user_ccallback Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 75/88] net/qlge: Avoids recursive EEH error Jiri Slaby
                   ` (15 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Kangjie Lu, Kangjie Lu, Takashi Iwai, Jiri Slaby

From: Kangjie Lu <kangjielu@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e4ec8cc8039a7063e24204299b462bd1383184a5 upstream.

The stack object “r1” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 sound/core/timer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index aa0582c5dd2e..1902ec0d4487 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1253,6 +1253,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
 	}
 	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
 	    tu->last_resolution != resolution) {
+		memset(&r1, 0, sizeof(r1));
 		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
 		r1.tstamp = tstamp;
 		r1.val = resolution;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 75/88] net/qlge: Avoids recursive EEH error
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (73 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 74/88] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 76/88] rds: fix an infoleak in rds_inc_info_copy Jiri Slaby
                   ` (14 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Gavin Shan, David S . Miller, Jiri Slaby

From: Gavin Shan <gwshan@linux.vnet.ibm.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 3275c0c6c522ab04afa14f80efdac6213c3883d6 upstream.

One timer, whose handler keeps reading on MMIO register for EEH
core to detect error in time, is started when the PCI device driver
is loaded. MMIO register can't be accessed during PE reset in EEH
recovery. Otherwise, the unexpected recursive error is triggered.
The timer isn't closed that time if the interface isn't brought
up. So the unexpected recursive error is seen during EEH recovery
when the interface is down.

This avoids the unexpected recursive EEH error by closing the timer
in qlge_io_error_detected() before EEH PE reset unconditionally. The
timer is started unconditionally after EEH PE reset in qlge_io_resume().
Also, the timer should be closed unconditionally when the device is
removed from the system permanently in qlge_io_error_detected().

Reported-by: Shriya R. Kulkarni <shriyakul@in.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/ethernet/qlogic/qlge/qlge_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 151478a59e30..a8cbeed1968a 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -4780,7 +4780,6 @@ static void ql_eeh_close(struct net_device *ndev)
 	}
 
 	/* Disabling the timer */
-	del_timer_sync(&qdev->timer);
 	ql_cancel_all_work_sync(qdev);
 
 	for (i = 0; i < qdev->rss_ring_count; i++)
@@ -4807,6 +4806,7 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
 		return PCI_ERS_RESULT_CAN_RECOVER;
 	case pci_channel_io_frozen:
 		netif_device_detach(ndev);
+		del_timer_sync(&qdev->timer);
 		if (netif_running(ndev))
 			ql_eeh_close(ndev);
 		pci_disable_device(pdev);
@@ -4814,6 +4814,7 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
 	case pci_channel_io_perm_failure:
 		dev_err(&pdev->dev,
 			"%s: pci_channel_io_perm_failure.\n", __func__);
+		del_timer_sync(&qdev->timer);
 		ql_eeh_close(ndev);
 		set_bit(QL_EEH_FATAL, &qdev->flags);
 		return PCI_ERS_RESULT_DISCONNECT;
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 76/88] rds: fix an infoleak in rds_inc_info_copy
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (74 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 75/88] net/qlge: Avoids recursive EEH error Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 77/88] EDAC: Remove arbitrary limit on number of channels Jiri Slaby
                   ` (13 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Kangjie Lu, Kangjie Lu, David S . Miller, Jiri Slaby

From: Kangjie Lu <kangjielu@gmail.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 4116def2337991b39919f3b448326e21c40e0dbb upstream.

The last field "flags" of object "minfo" is not initialized.
Copying this object out may leak kernel stack data.
Assign 0 to it to avoid leak.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/rds/recv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/rds/recv.c b/net/rds/recv.c
index de339b24ca14..917f36af8d37 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -544,5 +544,7 @@ void rds_inc_info_copy(struct rds_incoming *inc,
 		minfo.fport = inc->i_hdr.h_dport;
 	}
 
+	minfo.flags = 0;
+
 	rds_info_copy(iter, &minfo, sizeof(minfo));
 }
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 77/88] EDAC: Remove arbitrary limit on number of channels
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (75 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 76/88] rds: fix an infoleak in rds_inc_info_copy Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 78/88] SCSI: Increase REPORT_LUNS timeout Jiri Slaby
                   ` (12 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Tony Luck, Mauro Carvalho Chehab, Jiri Slaby

From: Tony Luck <tony.luck@intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit c44696fff04ff62f65441afe9ea244b47653dd6d upstream.

Currently set to "6", but the reset of the code will dynamically
allocate as needed.  We need to go to "8" today, but drop the check
completely to save doing this again when we need even larger numbers.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Acked-by: Aristeu Rozanski <aris@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/edac/edac_mc_sysfs.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index e5fde4382552..252e2fc83e8e 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -305,8 +305,6 @@ static struct device_type csrow_attr_type = {
  *
  */
 
-#define EDAC_NR_CHANNELS	6
-
 DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
 	channel_dimm_label_show, channel_dimm_label_store, 0);
 DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
@@ -370,9 +368,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
 {
 	int err, chan;
 
-	if (csrow->nr_channels >= EDAC_NR_CHANNELS)
-		return -ENODEV;
-
 	csrow->dev.type = &csrow_attr_type;
 	csrow->dev.bus = mci->bus;
 	device_initialize(&csrow->dev);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 78/88] SCSI: Increase REPORT_LUNS timeout
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (76 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 77/88] EDAC: Remove arbitrary limit on number of channels Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 79/88] KEYS: potential uninitialized variable Jiri Slaby
                   ` (11 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Brian King, Martin K . Petersen, Jiri Slaby

From: Brian King <brking@linux.vnet.ibm.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit b39c9a661b9bc77e064cade26cf913a1d4255d55 upstream.

This patch fixes an issue seen with an IBM 2145 (SVC) where, following an error
injection test which results in paths going offline, when they came
back online, the path would timeout the REPORT_LUNS issued during the
scan. This timeout situation continued until retries were expired, resulting in
falling back to a sequential LUN scan. Then, since the target responds
with PQ=1, PDT=0 for all possible LUNs, due to the way the sequential
LUN scan code works, we end up adding 512 LUNs for each target, when there
is really only a small handful of LUNs that are actually present.

This patch increases the timeout used on the REPORT_LUNS to 30 seconds.
This patch solves the issue of 512 non existent LUNs showing up after
this event.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/scsi/scsi_scan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 054ec2c412a4..25073167bcc4 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -54,6 +54,7 @@
  * Default timeout
  */
 #define SCSI_TIMEOUT (2*HZ)
+#define SCSI_REPORT_LUNS_TIMEOUT (30*HZ)
 
 /*
  * Prefix values for the SCSI id's (stored in sysfs name field)
@@ -1447,7 +1448,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
 
 		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
 					  lun_data, length, &sshdr,
-					  SCSI_TIMEOUT + 4 * HZ, 3, NULL);
+					  SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
 
 		SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
 				" %s (try %d) result 0x%x\n", result
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 79/88] KEYS: potential uninitialized variable
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (77 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 78/88] SCSI: Increase REPORT_LUNS timeout Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 80/88] base: make module_create_drivers_dir race-free Jiri Slaby
                   ` (10 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Dan Carpenter, David Howells, Linus Torvalds, Jiri Slaby

From: Dan Carpenter <dan.carpenter@oracle.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 38327424b40bcebe2de92d07312c89360ac9229a upstream.

If __key_link_begin() failed then "edit" would be uninitialized.  I've
added a check to fix that.

This allows a random user to crash the kernel, though it's quite
difficult to achieve.  There are three ways it can be done as the user
would have to cause an error to occur in __key_link():

 (1) Cause the kernel to run out of memory.  In practice, this is difficult
     to achieve without ENOMEM cropping up elsewhere and aborting the
     attempt.

 (2) Revoke the destination keyring between the keyring ID being looked up
     and it being tested for revocation.  In practice, this is difficult to
     time correctly because the KEYCTL_REJECT function can only be used
     from the request-key upcall process.  Further, users can only make use
     of what's in /sbin/request-key.conf, though this does including a
     rejection debugging test - which means that the destination keyring
     has to be the caller's session keyring in practice.

 (3) Have just enough key quota available to create a key, a new session
     keyring for the upcall and a link in the session keyring, but not then
     sufficient quota to create a link in the nominated destination keyring
     so that it fails with EDQUOT.

The bug can be triggered using option (3) above using something like the
following:

	echo 80 >/proc/sys/kernel/keys/root_maxbytes
	keyctl request2 user debug:fred negate @t

The above sets the quota to something much lower (80) to make the bug
easier to trigger, but this is dependent on the system.  Note also that
the name of the keyring created contains a random number that may be
between 1 and 10 characters in size, so may throw the test off by
changing the amount of quota used.

Assuming the failure occurs, something like the following will be seen:

	kfree_debugcheck: out of range ptr 6b6b6b6b6b6b6b68h
	------------[ cut here ]------------
	kernel BUG at ../mm/slab.c:2821!
	...
	RIP: 0010:[<ffffffff811600f9>] kfree_debugcheck+0x20/0x25
	RSP: 0018:ffff8804014a7de8  EFLAGS: 00010092
	RAX: 0000000000000034 RBX: 6b6b6b6b6b6b6b68 RCX: 0000000000000000
	RDX: 0000000000040001 RSI: 00000000000000f6 RDI: 0000000000000300
	RBP: ffff8804014a7df0 R08: 0000000000000001 R09: 0000000000000000
	R10: ffff8804014a7e68 R11: 0000000000000054 R12: 0000000000000202
	R13: ffffffff81318a66 R14: 0000000000000000 R15: 0000000000000001
	...
	Call Trace:
	  kfree+0xde/0x1bc
	  assoc_array_cancel_edit+0x1f/0x36
	  __key_link_end+0x55/0x63
	  key_reject_and_link+0x124/0x155
	  keyctl_reject_key+0xb6/0xe0
	  keyctl_negate_key+0x10/0x12
	  SyS_keyctl+0x9f/0xe7
	  do_syscall_64+0x63/0x13a
	  entry_SYSCALL64_slow_path+0x25/0x25

Fixes: f70e2e06196a ('KEYS: Do preallocation for __key_link()')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 security/keys/key.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/keys/key.c b/security/keys/key.c
index 8fb7c7bd4657..6595b2dd89fe 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -580,7 +580,7 @@ int key_reject_and_link(struct key *key,
 
 	mutex_unlock(&key_construction_mutex);
 
-	if (keyring)
+	if (keyring && link_ret == 0)
 		__key_link_end(keyring, key->type, prealloc);
 
 	/* wake up anyone waiting for a key to be constructed */
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 80/88] base: make module_create_drivers_dir race-free
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (78 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 79/88] KEYS: potential uninitialized variable Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2) Jiri Slaby
                   ` (9 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Jiri Slaby, Greg Kroah-Hartman

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 7e1b1fc4dabd6ec8e28baa0708866e13fa93c9b3 upstream.

Modules which register drivers via standard path (driver_register) in
parallel can cause a warning:
WARNING: CPU: 2 PID: 3492 at ../fs/sysfs/dir.c:31 sysfs_warn_dup+0x62/0x80
sysfs: cannot create duplicate filename '/module/saa7146/drivers'
Modules linked in: hexium_gemini(+) mxb(+) ...
...
Call Trace:
...
 [<ffffffff812e63a2>] sysfs_warn_dup+0x62/0x80
 [<ffffffff812e6487>] sysfs_create_dir_ns+0x77/0x90
 [<ffffffff8140f2c4>] kobject_add_internal+0xb4/0x340
 [<ffffffff8140f5b8>] kobject_add+0x68/0xb0
 [<ffffffff8140f631>] kobject_create_and_add+0x31/0x70
 [<ffffffff8157a703>] module_add_driver+0xc3/0xd0
 [<ffffffff8155e5d4>] bus_add_driver+0x154/0x280
 [<ffffffff815604c0>] driver_register+0x60/0xe0
 [<ffffffff8145bed0>] __pci_register_driver+0x60/0x70
 [<ffffffffa0273e14>] saa7146_register_extension+0x64/0x90 [saa7146]
 [<ffffffffa0033011>] hexium_init_module+0x11/0x1000 [hexium_gemini]
...

As can be (mostly) seen, driver_register causes this call sequence:
  -> bus_add_driver
    -> module_add_driver
      -> module_create_drivers_dir
The last one creates "drivers" directory in /sys/module/<...>. When
this is done in parallel, the directory is attempted to be created
twice at the same time.

This can be easily reproduced by loading mxb and hexium_gemini in
parallel:
while :; do
  modprobe mxb &
  modprobe hexium_gemini
  wait
  rmmod mxb hexium_gemini saa7146_vv saa7146
done

saa7146 calls pci_register_driver for both mxb and hexium_gemini,
which means /sys/module/saa7146/drivers is to be created for both of
them.

Fix this by a new mutex in module_create_drivers_dir which makes the
test-and-create "drivers" dir atomic.

I inverted the condition and removed 'return' to avoid multiple
unlocks or a goto.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Fixes: fe480a2675ed (Modules: only add drivers/ direcory if needed)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/base/module.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/base/module.c b/drivers/base/module.c
index db930d3ee312..2a215780eda2 100644
--- a/drivers/base/module.c
+++ b/drivers/base/module.c
@@ -24,10 +24,12 @@ static char *make_driver_name(struct device_driver *drv)
 
 static void module_create_drivers_dir(struct module_kobject *mk)
 {
-	if (!mk || mk->drivers_dir)
-		return;
+	static DEFINE_MUTEX(drivers_dir_mutex);
 
-	mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
+	mutex_lock(&drivers_dir_mutex);
+	if (mk && !mk->drivers_dir)
+		mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
+	mutex_unlock(&drivers_dir_mutex);
 }
 
 void module_add_driver(struct module *mod, struct device_driver *drv)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2)
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (79 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 80/88] base: make module_create_drivers_dir race-free Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:40   ` Paolo Bonzini
  2016-07-14  8:16 ` [PATCH 3.12 82/88] mm/swap.c: flush lru pvecs on compound page arrival Jiri Slaby
                   ` (8 subsequent siblings)
  89 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Marcelo Tosatti, Paolo Bonzini, Jiri Slaby

From: Marcelo Tosatti <mtosatti@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e4c9a5a17567f8ea975bdcfdd1bf9d63965de6c9 upstream.

Invariant TSC is a property of TSC, no additional
support code necessary.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/kvm/cpuid.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index b132551528e5..6620ac307215 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -437,6 +437,13 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 		entry->ecx &= kvm_supported_word6_x86_features;
 		cpuid_mask(&entry->ecx, 6);
 		break;
+	case 0x80000007: /* Advanced power management */
+		/* invariant TSC is CPUID.80000007H:EDX[8] */
+		entry->edx &= (1 << 8);
+		/* mask against host */
+		entry->edx &= boot_cpu_data.x86_power;
+		entry->eax = entry->ebx = entry->ecx = 0;
+		break;
 	case 0x80000008: {
 		unsigned g_phys_as = (entry->eax >> 16) & 0xff;
 		unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
@@ -467,7 +474,6 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 	case 3: /* Processor serial number */
 	case 5: /* MONITOR/MWAIT */
 	case 6: /* Thermal management */
-	case 0x80000007: /* Advanced power management */
 	case 0xC0000002:
 	case 0xC0000003:
 	case 0xC0000004:
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 82/88] mm/swap.c: flush lru pvecs on compound page arrival
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (80 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2) Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 83/88] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands Jiri Slaby
                   ` (7 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Lukasz Odzioba, Kirill Shutemov, Andrea Arcangeli,
	Vladimir Davydov, Ming Li, Minchan Kim, Andrew Morton,
	Linus Torvalds, Jiri Slaby

From: Lukasz Odzioba <lukasz.odzioba@intel.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 8f182270dfec432e93fae14f9208a6b9af01009f upstream.

Currently we can have compound pages held on per cpu pagevecs, which
leads to a lot of memory unavailable for reclaim when needed.  In the
systems with hundreads of processors it can be GBs of memory.

On of the way of reproducing the problem is to not call munmap
explicitly on all mapped regions (i.e.  after receiving SIGTERM).  After
that some pages (with THP enabled also huge pages) may end up on
lru_add_pvec, example below.

  void main() {
  #pragma omp parallel
  {
	size_t size = 55 * 1000 * 1000; // smaller than  MEM/CPUS
	void *p = mmap(NULL, size, PROT_READ | PROT_WRITE,
		MAP_PRIVATE | MAP_ANONYMOUS , -1, 0);
	if (p != MAP_FAILED)
		memset(p, 0, size);
	//munmap(p, size); // uncomment to make the problem go away
  }
  }

When we run it with THP enabled it will leave significant amount of
memory on lru_add_pvec.  This memory will be not reclaimed if we hit
OOM, so when we run above program in a loop:

	for i in `seq 100`; do ./a.out; done

many processes (95% in my case) will be killed by OOM.

The primary point of the LRU add cache is to save the zone lru_lock
contention with a hope that more pages will belong to the same zone and
so their addition can be batched.  The huge page is already a form of
batched addition (it will add 512 worth of memory in one go) so skipping
the batching seems like a safer option when compared to a potential
excess in the caching which can be quite large and much harder to fix
because lru_add_drain_all is way to expensive and it is not really clear
what would be a good moment to call it.

Similarly we can reproduce the problem on lru_deactivate_pvec by adding:
madvise(p, size, MADV_FREE); after memset.

This patch flushes lru pvecs on compound page arrival making the problem
less severe - after applying it kill rate of above example drops to 0%,
due to reducing maximum amount of memory held on pvec from 28MB (with
THP) to 56kB per CPU.

Suggested-by: Michal Hocko <mhocko@suse.com>
Link: http://lkml.kernel.org/r/1466180198-18854-1-git-send-email-lukasz.odzioba@intel.com
Signed-off-by: Lukasz Odzioba <lukasz.odzioba@intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Vladimir Davydov <vdavydov@parallels.com>
Cc: Ming Li <mingli199x@qq.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 mm/swap.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/mm/swap.c b/mm/swap.c
index 16e70ce1912a..a8e94391b2de 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -410,7 +410,7 @@ void rotate_reclaimable_page(struct page *page)
 		page_cache_get(page);
 		local_irq_save(flags);
 		pvec = &__get_cpu_var(lru_rotate_pvecs);
-		if (!pagevec_add(pvec, page))
+		if (!pagevec_add(pvec, page) || PageCompound(page))
 			pagevec_move_tail(pvec);
 		local_irq_restore(flags);
 	}
@@ -466,7 +466,7 @@ void activate_page(struct page *page)
 		struct pagevec *pvec = &get_cpu_var(activate_page_pvecs);
 
 		page_cache_get(page);
-		if (!pagevec_add(pvec, page))
+		if (!pagevec_add(pvec, page) || PageCompound(page))
 			pagevec_lru_move_fn(pvec, __activate_page, NULL);
 		put_cpu_var(activate_page_pvecs);
 	}
@@ -564,9 +564,8 @@ static void __lru_cache_add(struct page *page)
 	struct pagevec *pvec = &get_cpu_var(lru_add_pvec);
 
 	page_cache_get(page);
-	if (!pagevec_space(pvec))
+	if (!pagevec_add(pvec, page) || PageCompound(page))
 		__pagevec_lru_add(pvec);
-	pagevec_add(pvec, page);
 	put_cpu_var(lru_add_pvec);
 }
 
@@ -745,7 +744,7 @@ void deactivate_page(struct page *page)
 	if (likely(get_page_unless_zero(page))) {
 		struct pagevec *pvec = &get_cpu_var(lru_deactivate_pvecs);
 
-		if (!pagevec_add(pvec, page))
+		if (!pagevec_add(pvec, page) || PageCompound(page))
 			pagevec_lru_move_fn(pvec, lru_deactivate_fn, NULL);
 		put_cpu_var(lru_deactivate_pvecs);
 	}
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 83/88] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (81 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 82/88] mm/swap.c: flush lru pvecs on compound page arrival Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 84/88] ALSA: compress: fix an integer overflow check Jiri Slaby
                   ` (6 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Scott Bauer, Jiri Kosina, Jiri Slaby

From: Scott Bauer <sbauer@plzdonthack.me>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 93a2001bdfd5376c3dc2158653034c20392d15c5 upstream.

This patch validates the num_values parameter from userland during the
HIDIOCGUSAGES and HIDIOCSUSAGES commands. Previously, if the report id was set
to HID_REPORT_ID_UNKNOWN, we would fail to validate the num_values parameter
leading to a heap overflow.

Signed-off-by: Scott Bauer <sbauer@plzdonthack.me>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/hid/usbhid/hiddev.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 2f1ddca6f2e0..700145b15088 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
 					goto inval;
 			} else if (uref->usage_index >= field->report_count)
 				goto inval;
-
-			else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
-				 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
-				  uref->usage_index + uref_multi->num_values > field->report_count))
-				goto inval;
 		}
 
+		if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+		    (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+		     uref->usage_index + uref_multi->num_values > field->report_count))
+			goto inval;
+
 		switch (cmd) {
 		case HIDIOCGUSAGE:
 			uref->value = field->value[uref->usage_index];
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 84/88] ALSA: compress: fix an integer overflow check
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (82 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 83/88] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 85/88] HID: elo: kill not flush the work Jiri Slaby
                   ` (5 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Dan Carpenter, Takashi Iwai, Jiri Slaby

From: Dan Carpenter <dan.carpenter@oracle.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 6217e5ede23285ddfee10d2e4ba0cc2d4c046205 upstream.

I previously added an integer overflow check here but looking at it now,
it's still buggy.

The bug happens in snd_compr_allocate_buffer().  We multiply
".fragments" and ".fragment_size" and that doesn't overflow but then we
save it in an unsigned int so it truncates the high bits away and we
allocate a smaller than expected size.

Fixes: b35cc8225845 ('ALSA: compress_core: integer overflow in snd_compr_allocate_buffer()')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 sound/core/compress_offload.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 3f2b4b7f2ec9..a20650d28844 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -501,7 +501,7 @@ static int snd_compress_check_input(struct snd_compr_params *params)
 {
 	/* first let's check the buffer parameter's */
 	if (params->buffer.fragment_size == 0 ||
-			params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
+	    params->buffer.fragments > INT_MAX / params->buffer.fragment_size)
 		return -EINVAL;
 
 	/* now codec parameters */
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 85/88] HID: elo: kill not flush the work
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (83 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 84/88] ALSA: compress: fix an integer overflow check Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 86/88] cdc_ncm: workaround for EM7455 "silent" data interface Jiri Slaby
                   ` (4 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Oliver Neukum, Oliver Neukum, Jiri Kosina, Jiri Slaby

From: Oliver Neukum <oneukum@suse.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit ed596a4a88bd161f868ccba078557ee7ede8a6ef upstream.

Flushing a work that reschedules itself is not a sensible operation. It needs
to be killed. Failure to do so leads to a kernel panic in the timer code.

Signed-off-by: Oliver Neukum <ONeukum@suse.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/hid/hid-elo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
index 55e4920f967b..0cd5f767d861 100644
--- a/drivers/hid/hid-elo.c
+++ b/drivers/hid/hid-elo.c
@@ -259,7 +259,7 @@ static void elo_remove(struct hid_device *hdev)
 	struct elo_priv *priv = hid_get_drvdata(hdev);
 
 	hid_hw_stop(hdev);
-	flush_workqueue(wq);
+	cancel_delayed_work_sync(&priv->work);
 	kfree(priv);
 }
 
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 86/88] cdc_ncm: workaround for EM7455 "silent" data interface
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (84 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 85/88] HID: elo: kill not flush the work Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 87/88] MIPS: KVM: Fix modular KVM under QEMU Jiri Slaby
                   ` (3 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable; +Cc: linux-kernel, Bjørn Mork, David S . Miller, Jiri Slaby

From: Bjørn Mork <bjorn@mork.no>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit c086e7096170390594c425114d98172bc9aceb8a ]

Several Lenovo users have reported problems with their Sierra
Wireless EM7455 modem. The driver has loaded successfully and
the MBIM management channel has appeared to work, including
establishing a connection to the mobile network. But no frames
have been received over the data interface.

The problem affects all EM7455 and MC7455, and is assumed to
affect other modems based on the same Qualcomm chipset and
baseband firmware.

Testing narrowed the problem down to what seems to be a
firmware timing bug during initialization. Adding a short sleep
while probing is sufficient to make the problem disappear.
Experiments have shown that 1-2 ms is too little to have any
effect, while 10-20 ms is enough to reliably succeed.

Reported-by: Stefan Armbruster <ml001@armbruster-it.de>
Reported-by: Ralph Plawetzki <ralph@purejava.org>
Reported-by: Andreas Fett <andreas.fett@secunet.com>
Reported-by: Rasmus Lerdorf <rasmus@lerdorf.com>
Reported-by: Samo Ratnik <samo.ratnik@gmail.com>
Reported-and-tested-by: Aleksander Morgado <aleksander@aleksander.es>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/usb/cdc_ncm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 6ee9665e20b2..a5802419381f 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -477,6 +477,13 @@ advance:
 	if (cdc_ncm_setup(ctx))
 		goto error2;
 
+	/* Some firmwares need a pause here or they will silently fail
+	 * to set up the interface properly.  This value was decided
+	 * empirically on a Sierra Wireless MC7455 running 02.08.02.00
+	 * firmware.
+	 */
+	usleep_range(10000, 20000);
+
 	/* configure data interface */
 	temp = usb_set_interface(dev->udev, iface_no, data_altsetting);
 	if (temp)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 87/88] MIPS: KVM: Fix modular KVM under QEMU
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (85 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 86/88] cdc_ncm: workaround for EM7455 "silent" data interface Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14  8:16 ` [PATCH 3.12 88/88] signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo Jiri Slaby
                   ` (2 subsequent siblings)
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, James Hogan, Paolo Bonzini,
	Radim Krčmář,
	Ralf Baechle, kvm, linux-mips, Jiri Slaby

From: James Hogan <james.hogan@imgtec.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 797179bc4fe06c89e47a9f36f886f68640b423f8 upstream.

Copy __kvm_mips_vcpu_run() into unmapped memory, so that we can never
get a TLB refill exception in it when KVM is built as a module.

This was observed to happen with the host MIPS kernel running under
QEMU, due to a not entirely transparent optimisation in the QEMU TLB
handling where TLB entries replaced with TLBWR are copied to a separate
part of the TLB array. Code in those pages continue to be executable,
but those mappings persist only until the next ASID switch, even if they
are marked global.

An ASID switch happens in __kvm_mips_vcpu_run() at exception level after
switching to the guest exception base. Subsequent TLB mapped kernel
instructions just prior to switching to the guest trigger a TLB refill
exception, which enters the guest exception handlers without updating
EPC. This appears as a guest triggered TLB refill on a host kernel
mapped (host KSeg2) address, which is not handled correctly as user
(guest) mode accesses to kernel (host) segments always generate address
error exceptions.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[james.hogan@imgtec.com: backported for stable 3.14]
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/mips/include/asm/kvm_host.h |  1 +
 arch/mips/kvm/kvm_locore.S       |  1 +
 arch/mips/kvm/kvm_mips.c         | 11 ++++++++++-
 arch/mips/kvm/kvm_mips_int.h     |  2 ++
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 4d6fa0bf1305..883a162083af 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -349,6 +349,7 @@ struct kvm_mips_tlb {
 #define KVM_MIPS_GUEST_TLB_SIZE     64
 struct kvm_vcpu_arch {
 	void *host_ebase, *guest_ebase;
+	int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	unsigned long host_stack;
 	unsigned long host_gp;
 
diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S
index ba5ce99c021d..d1fa2a57218b 100644
--- a/arch/mips/kvm/kvm_locore.S
+++ b/arch/mips/kvm/kvm_locore.S
@@ -229,6 +229,7 @@ FEXPORT(__kvm_mips_load_k0k1)
 
 	/* Jump to guest */
 	eret
+EXPORT(__kvm_mips_vcpu_run_end)
 
 VECTOR(MIPSX(exception), unknown)
 /*
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index 7e7de1f2b8ed..08972791edb4 100644
--- a/arch/mips/kvm/kvm_mips.c
+++ b/arch/mips/kvm/kvm_mips.c
@@ -347,6 +347,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 	memcpy(gebase + offset, mips32_GuestException,
 	       mips32_GuestExceptionEnd - mips32_GuestException);
 
+#ifdef MODULE
+	offset += mips32_GuestExceptionEnd - mips32_GuestException;
+	memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
+	       __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
+	vcpu->arch.vcpu_run = gebase + offset;
+#else
+	vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
+#endif
+
 	/* Invalidate the icache for these ranges */
 	mips32_SyncICache((unsigned long) gebase, ALIGN(size, PAGE_SIZE));
 
@@ -430,7 +439,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 	kvm_guest_enter();
 
-	r = __kvm_mips_vcpu_run(run, vcpu);
+	r = vcpu->arch.vcpu_run(run, vcpu);
 
 	kvm_guest_exit();
 	local_irq_enable();
diff --git a/arch/mips/kvm/kvm_mips_int.h b/arch/mips/kvm/kvm_mips_int.h
index 20da7d29eede..bf41ea36210e 100644
--- a/arch/mips/kvm/kvm_mips_int.h
+++ b/arch/mips/kvm/kvm_mips_int.h
@@ -27,6 +27,8 @@
 #define MIPS_EXC_MAX                12
 /* XXXSL More to follow */
 
+extern char __kvm_mips_vcpu_run_end[];
+
 #define C_TI        (_ULCAST_(1) << 30)
 
 #define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0)
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH 3.12 88/88] signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (86 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 87/88] MIPS: KVM: Fix modular KVM under QEMU Jiri Slaby
@ 2016-07-14  8:16 ` Jiri Slaby
  2016-07-14 20:20 ` [PATCH 3.12 00/88] 3.12.62-stable review Guenter Roeck
  2016-07-14 21:45 ` Shuah Khan
  89 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  8:16 UTC (permalink / raw)
  To: stable
  Cc: linux-kernel, Vladimir Davydov, Richard Weinberger,
	Paul E. McKenney, Andrew Morton, Linus Torvalds, Jiri Slaby

From: Vladimir Davydov <vdavydov@parallels.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 69828dce7af2cb6d08ef5a03de687d422fb7ec1f upstream.

Sending SI_TKILL from rt_[tg]sigqueueinfo was deprecated, so now we issue
a warning on the first attempt of doing it.  We use WARN_ON_ONCE, which is
not informative and, what is worse, taints the kernel, making the trinity
syscall fuzzer complain false-positively from time to time.

It does not look like we need this warning at all, because the behaviour
changed quite a long time ago (2.6.39), and if an application relies on
the old API, it gets EPERM anyway and can issue a warning by itself.

So let us zap the warning in kernel.

Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 kernel/signal.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index e99136208d7e..1a1b0e88c23d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3004,11 +3004,9 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
 	 * Nor can they impersonate a kill()/tgkill(), which adds source info.
 	 */
 	if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
-	    (task_pid_vnr(current) != pid)) {
-		/* We used to allow any < 0 si_code */
-		WARN_ON_ONCE(info->si_code < 0);
+	    (task_pid_vnr(current) != pid))
 		return -EPERM;
-	}
+
 	info->si_signo = sig;
 
 	/* POSIX.1b doesn't mention process groups.  */
@@ -3053,12 +3051,10 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
 	/* Not even root can pretend to send signals from the kernel.
 	 * Nor can they impersonate a kill()/tgkill(), which adds source info.
 	 */
-	if (((info->si_code >= 0 || info->si_code == SI_TKILL)) &&
-	    (task_pid_vnr(current) != pid)) {
-		/* We used to allow any < 0 si_code */
-		WARN_ON_ONCE(info->si_code < 0);
+	if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
+	    (task_pid_vnr(current) != pid))
 		return -EPERM;
-	}
+
 	info->si_signo = sig;
 
 	return do_send_specific(tgid, pid, sig, info);
-- 
2.9.1

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2)
  2016-07-14  8:16 ` [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2) Jiri Slaby
@ 2016-07-14  8:40   ` Paolo Bonzini
  2016-07-14  9:22     ` Jiri Slaby
  0 siblings, 1 reply; 109+ messages in thread
From: Paolo Bonzini @ 2016-07-14  8:40 UTC (permalink / raw)
  To: Jiri Slaby, stable; +Cc: linux-kernel, Marcelo Tosatti



On 14/07/2016 10:16, Jiri Slaby wrote:
> From: Marcelo Tosatti <mtosatti@redhat.com>
> 
> 3.12-stable review patch.  If anyone has any objections, please let me know.

Why stable?  The commit is in 3.16, but AFAICS it never went into other
stable kernels.

Paolo

> ===============
> 
> commit e4c9a5a17567f8ea975bdcfdd1bf9d63965de6c9 upstream.
> 
> Invariant TSC is a property of TSC, no additional
> support code necessary.
> 
> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> ---
>  arch/x86/kvm/cpuid.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index b132551528e5..6620ac307215 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -437,6 +437,13 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>  		entry->ecx &= kvm_supported_word6_x86_features;
>  		cpuid_mask(&entry->ecx, 6);
>  		break;
> +	case 0x80000007: /* Advanced power management */
> +		/* invariant TSC is CPUID.80000007H:EDX[8] */
> +		entry->edx &= (1 << 8);
> +		/* mask against host */
> +		entry->edx &= boot_cpu_data.x86_power;
> +		entry->eax = entry->ebx = entry->ecx = 0;
> +		break;
>  	case 0x80000008: {
>  		unsigned g_phys_as = (entry->eax >> 16) & 0xff;
>  		unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
> @@ -467,7 +474,6 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>  	case 3: /* Processor serial number */
>  	case 5: /* MONITOR/MWAIT */
>  	case 6: /* Thermal management */
> -	case 0x80000007: /* Advanced power management */
>  	case 0xC0000002:
>  	case 0xC0000003:
>  	case 0xC0000004:
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2)
  2016-07-14  8:40   ` Paolo Bonzini
@ 2016-07-14  9:22     ` Jiri Slaby
  2016-07-14  9:41       ` Paolo Bonzini
  0 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-14  9:22 UTC (permalink / raw)
  To: Paolo Bonzini, stable; +Cc: linux-kernel, Marcelo Tosatti

On 07/14/2016, 10:40 AM, Paolo Bonzini wrote:
> 
> 
> On 14/07/2016 10:16, Jiri Slaby wrote:
>> From: Marcelo Tosatti <mtosatti@redhat.com>
>>
>> 3.12-stable review patch.  If anyone has any objections, please let me know.
> 
> Why stable?  The commit is in 3.16, but AFAICS it never went into other
> stable kernels.

Hi,

we (SUSE) have the patch in SLE12 (based on 3.12) for some time as our
customer needs to see the invtsc flag. And given it is so simple and
belongs IMO to the "New device IDs and quirks are also accepted."
category, I decided to take it into 3.12.

If you see some problem this could lead to, I can drop it from stable of
course. But then I would be definitely interested in details to fix this
in SLE12 as well.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2)
  2016-07-14  9:22     ` Jiri Slaby
@ 2016-07-14  9:41       ` Paolo Bonzini
  0 siblings, 0 replies; 109+ messages in thread
From: Paolo Bonzini @ 2016-07-14  9:41 UTC (permalink / raw)
  To: Jiri Slaby, stable; +Cc: linux-kernel, Marcelo Tosatti



On 14/07/2016 11:22, Jiri Slaby wrote:
> Hi,
> 
> we (SUSE) have the patch in SLE12 (based on 3.12) for some time as our
> customer needs to see the invtsc flag. And given it is so simple and
> belongs IMO to the "New device IDs and quirks are also accepted."
> category, I decided to take it into 3.12.
> 
> If you see some problem this could lead to, I can drop it from stable of
> course. But then I would be definitely interested in details to fix this
> in SLE12 as well.

Ok, fair enough.

Paolo

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 00/88] 3.12.62-stable review
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (87 preceding siblings ...)
  2016-07-14  8:16 ` [PATCH 3.12 88/88] signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo Jiri Slaby
@ 2016-07-14 20:20 ` Guenter Roeck
  2016-07-15  7:31   ` Jiri Slaby
  2016-07-14 21:45 ` Shuah Khan
  89 siblings, 1 reply; 109+ messages in thread
From: Guenter Roeck @ 2016-07-14 20:20 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: stable, shuah.kh, linux-kernel

On Thu, Jul 14, 2016 at 10:16:06AM +0200, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.62 release.
> There are 88 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Mon Jul 18 10:12:31 CEST 2016.
> Anything received after that time might be too late.
> 

Build results:
	total: 127 pass: 127 fail: 0
Qemu test results:
	total: 85 pass: 85 fail: 0

Details are available at http://kerneltests.org/builders.

Guenter

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 00/88] 3.12.62-stable review
  2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
                   ` (88 preceding siblings ...)
  2016-07-14 20:20 ` [PATCH 3.12 00/88] 3.12.62-stable review Guenter Roeck
@ 2016-07-14 21:45 ` Shuah Khan
  89 siblings, 0 replies; 109+ messages in thread
From: Shuah Khan @ 2016-07-14 21:45 UTC (permalink / raw)
  To: Jiri Slaby, stable; +Cc: linux, shuah.kh, linux-kernel

On 07/14/2016 02:16 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.62 release.
> There are 88 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Mon Jul 18 10:12:31 CEST 2016.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
> 	http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.62-rc1.xz
> and the diffstat can be found below.
> 
> thanks,
> js

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 00/88] 3.12.62-stable review
  2016-07-14 20:20 ` [PATCH 3.12 00/88] 3.12.62-stable review Guenter Roeck
@ 2016-07-15  7:31   ` Jiri Slaby
  0 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-15  7:31 UTC (permalink / raw)
  To: Guenter Roeck, shuah.kh; +Cc: stable, linux-kernel

On 07/14/2016, 10:20 PM, Guenter Roeck wrote:
> On Thu, Jul 14, 2016 at 10:16:06AM +0200, Jiri Slaby wrote:
>> This is the start of the stable review cycle for the 3.12.62 release.
>> There are 88 patches in this series, all will be posted as a response
>> to this one.  If anyone has any issues with these being applied, please
>> let me know.
>>
>> Responses should be made by Mon Jul 18 10:12:31 CEST 2016.
>> Anything received after that time might be too late.
>>
> 
> Build results:
> 	total: 127 pass: 127 fail: 0
> Qemu test results:
> 	total: 85 pass: 85 fail: 0
> 
> Details are available at http://kerneltests.org/builders.

On 07/14/2016, 11:45 PM, Shuah Khan wrote:
> Compiled and booted on my test system. No dmesg regressions.

Thank you both!

-- 
js
suse labs

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 24/88] ecryptfs: forbid opening files without mmap handler
       [not found]   ` <20160716192134.72132405@desktop.jensen.local>
@ 2016-07-18 11:55     ` Jiri Slaby
  0 siblings, 0 replies; 109+ messages in thread
From: Jiri Slaby @ 2016-07-18 11:55 UTC (permalink / raw)
  To: Henry Jensen; +Cc: Jeff Mahoney, stable

On 07/16/2016, 07:21 PM, Henry Jensen wrote:
> Hi,
> 
> 
> On Thu, 14 Jul 2016 10:15:16 +0200 Jiri Slaby <jslaby@suse.cz> wrote:
> 
>> From: Jann Horn <jannh@google.com>
>>
>> 3.12-stable review patch.  If anyone has any objections, please let me know.
> 
> in 4.4.14 this backported patch led to a regression which makes
> ecryptfs unusable because directories can't be accessed any more. 
> 
> See  
> http://thread.gmane.org/gmane.comp.file-systems.ecryptfs.general/881
> http://article.gmane.org/gmane.linux.kernel.stable/183050

Thanks, I dropped
  ecryptfs: forbid opening files without mmap handler
and applied
  ecryptfs: don't allow mmap when the lower fs doesn't support it
to 3.12 instead.

-- 
js
suse labs

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table
  2016-07-14  8:15 ` [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table Jiri Slaby
@ 2016-07-19  7:13   ` Michal Kubecek
  2016-07-19  8:40     ` Florian Westphal
  0 siblings, 1 reply; 109+ messages in thread
From: Michal Kubecek @ 2016-07-19  7:13 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: stable, linux-kernel, Florian Westphal, Pablo Neira Ayuso

On Thu, Jul 14, 2016 at 10:15:34AM +0200, Jiri Slaby wrote:
> From: Florian Westphal <fw@strlen.de>
> 
> 3.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ===============
> 
> 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: Jiri Slaby <jslaby@suse.cz>
> ---
>  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 020b0e97c206..b7f3b31a3cc3 100644
> --- a/net/ipv4/netfilter/arp_tables.c
> +++ b/net/ipv4/netfilter/arp_tables.c
> @@ -1223,19 +1223,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 ||
> @@ -1280,17 +1278,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:
> @@ -1340,7 +1327,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;
>  
> @@ -1349,12 +1336,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);
> @@ -1363,9 +1344,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;
> @@ -1378,23 +1357,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)
> @@ -1411,51 +1373,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);

These four lines should be preserved, IMHO, as 3.12 doesn't have commit
482cfc318559 ("netfilter: xtables: avoid percpu ruleset duplication")
(introduced in 4.2) which removed the need for per-cpu copies.

The same applies to the other two instances of translate_compat_table()
in net/ipv4/netfilter/ip_tables.c and net/ipv6/netfilter/ip6_tables.c

Florian, do you agree?

Michal Kubecek

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table
  2016-07-19  7:13   ` Michal Kubecek
@ 2016-07-19  8:40     ` Florian Westphal
  2016-07-19  9:13       ` Florian Westphal
  0 siblings, 1 reply; 109+ messages in thread
From: Florian Westphal @ 2016-07-19  8:40 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: Jiri Slaby, stable, linux-kernel, Florian Westphal, Pablo Neira Ayuso

Michal Kubecek <mkubecek@suse.cz> wrote:
> > -	/* 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);
> 
> These four lines should be preserved, IMHO, as 3.12 doesn't have commit
> 482cfc318559 ("netfilter: xtables: avoid percpu ruleset duplication")
> (introduced in 4.2) which removed the need for per-cpu copies.
> 
> The same applies to the other two instances of translate_compat_table()
> in net/ipv4/netfilter/ip_tables.c and net/ipv6/netfilter/ip6_tables.c
> 
> Florian, do you agree?

Sorry, I have to look at this in more detail.
The patches change the compat translation version into a preprocessing
step rather than a 1:1 replacement of translate_table.

>From first glance the removal is thus ok.
I will review this later today.

Also, please be aware of this bug:
http://patchwork.ozlabs.org/patch/648446/

If possible this patchset should not be pushed to all -stable
kernels yet.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table
  2016-07-19  8:40     ` Florian Westphal
@ 2016-07-19  9:13       ` Florian Westphal
  2016-07-19  9:45         ` Michal Kubecek
  0 siblings, 1 reply; 109+ messages in thread
From: Florian Westphal @ 2016-07-19  9:13 UTC (permalink / raw)
  To: Florian Westphal
  Cc: Michal Kubecek, Jiri Slaby, stable, linux-kernel, Pablo Neira Ayuso

Florian Westphal <fw@strlen.de> wrote:
> Michal Kubecek <mkubecek@suse.cz> wrote:
> > > -	/* 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);
> > 
> > These four lines should be preserved, IMHO, as 3.12 doesn't have commit
> > 482cfc318559 ("netfilter: xtables: avoid percpu ruleset duplication")
> > (introduced in 4.2) which removed the need for per-cpu copies.
> > 
> > The same applies to the other two instances of translate_compat_table()
> > in net/ipv4/netfilter/ip_tables.c and net/ipv6/netfilter/ip6_tables.c
> > 
> > Florian, do you agree?
> 
> Sorry, I have to look at this in more detail.
> The patches change the compat translation version into a preprocessing
> step rather than a 1:1 replacement of translate_table.
> 
> From first glance the removal is thus ok.

Removal is correct, the expanded ruleset is passed to
translate_table() which will do the percpu duplication as last step.

[ I looked at 3.14.y tree which also dropped these lines in the backport ]

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table
  2016-07-19  9:13       ` Florian Westphal
@ 2016-07-19  9:45         ` Michal Kubecek
  0 siblings, 0 replies; 109+ messages in thread
From: Michal Kubecek @ 2016-07-19  9:45 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Jiri Slaby, stable, linux-kernel, Pablo Neira Ayuso

On Tue, Jul 19, 2016 at 11:13:12AM +0200, Florian Westphal wrote:
> Florian Westphal <fw@strlen.de> wrote:
> > Michal Kubecek <mkubecek@suse.cz> wrote:
> > > > -	/* 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);
> > > 
> > > These four lines should be preserved, IMHO, as 3.12 doesn't have commit
> > > 482cfc318559 ("netfilter: xtables: avoid percpu ruleset duplication")
> > > (introduced in 4.2) which removed the need for per-cpu copies.
> > > 
> > > The same applies to the other two instances of translate_compat_table()
> > > in net/ipv4/netfilter/ip_tables.c and net/ipv6/netfilter/ip6_tables.c
> > > 
> > > Florian, do you agree?
> > 
> > Sorry, I have to look at this in more detail.
> > The patches change the compat translation version into a preprocessing
> > step rather than a 1:1 replacement of translate_table.
> > 
> > From first glance the removal is thus ok.
> 
> Removal is correct, the expanded ruleset is passed to
> translate_table() which will do the percpu duplication as last step.
> 
> [ I looked at 3.14.y tree which also dropped these lines in the backport ]

You are right, I didn't notice that. Thanks for the clarification.
I'll send v2 of the patch for 4.1 stable in a moment.

Michal Kubecek

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-14  8:15 ` [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps Jiri Slaby
@ 2016-07-21  6:36   ` Jiri Slaby
  2016-07-21 18:56     ` Greg KH
  0 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-21  6:36 UTC (permalink / raw)
  To: Jiri Slaby, stable; +Cc: linux-kernel, Florian Westphal, Pablo Neira Ayuso

On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> From: Florian Westphal <fw@strlen.de>
> 
> 3.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ===============
> 
> commit 36472341017529e2b12573093cc0f68719300997 upstream.

I am now dropping this one. 3.12.62 will be released without that patch.
After the performance issue is resolved, it will be requeued.

> When we see a jump also check that the offset gets us to beginning of
> a rule (an ipt_entry).
> 
> The extra overhead is negible, even with absurd cases.
> 
> 300k custom rules, 300k jumps to 'next' user chain:
> [ plus one jump from INPUT to first userchain ]:
> 
> Before:
> real    0m24.874s
> user    0m7.532s
> sys     0m16.076s
> 
> After:
> real    0m27.464s
> user    0m7.436s
> sys     0m18.840s
> 
> Signed-off-by: Florian Westphal <fw@strlen.de>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> ---
>  net/ipv4/netfilter/arp_tables.c | 17 +++++++++++++++++
>  net/ipv4/netfilter/ip_tables.c  | 17 +++++++++++++++++
>  net/ipv6/netfilter/ip6_tables.c | 17 +++++++++++++++++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
> index 7460b7bef3ab..473ec559ce7b 100644
> --- a/net/ipv4/netfilter/arp_tables.c
> +++ b/net/ipv4/netfilter/arp_tables.c
> @@ -358,6 +358,19 @@ static inline bool unconditional(const struct arpt_entry *e)
>  	       memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
>  }
>  
> +static bool find_jump_target(const struct xt_table_info *t,
> +			     const void *entry0,
> +			     const struct arpt_entry *target)
> +{
> +	struct arpt_entry *iter;
> +
> +	xt_entry_foreach(iter, entry0, t->size) {
> +		 if (iter == target)
> +			return true;
> +	}
> +	return false;
> +}
> +
>  /* Figures out from what hook each rule can be called: returns 0 if
>   * there are loops.  Puts hook bitmask in comefrom.
>   */
> @@ -451,6 +464,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
>  					/* This a jump; chase it. */
>  					duprintf("Jump rule %u -> %u\n",
>  						 pos, newpos);
> +					e = (struct arpt_entry *)
> +						(entry0 + newpos);
> +					if (!find_jump_target(newinfo, entry0, e))
> +						return 0;
>  				} else {
>  					/* ... this is a fallthru */
>  					newpos = pos + e->next_offset;
> diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
> index 8fc22eed9603..dba9d8070d07 100644
> --- a/net/ipv4/netfilter/ip_tables.c
> +++ b/net/ipv4/netfilter/ip_tables.c
> @@ -434,6 +434,19 @@ ipt_do_table(struct sk_buff *skb,
>  #endif
>  }
>  
> +static bool find_jump_target(const struct xt_table_info *t,
> +			     const void *entry0,
> +			     const struct ipt_entry *target)
> +{
> +	struct ipt_entry *iter;
> +
> +	xt_entry_foreach(iter, entry0, t->size) {
> +		 if (iter == target)
> +			return true;
> +	}
> +	return false;
> +}
> +
>  /* Figures out from what hook each rule can be called: returns 0 if
>     there are loops.  Puts hook bitmask in comefrom. */
>  static int
> @@ -531,6 +544,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
>  					/* This a jump; chase it. */
>  					duprintf("Jump rule %u -> %u\n",
>  						 pos, newpos);
> +					e = (struct ipt_entry *)
> +						(entry0 + newpos);
> +					if (!find_jump_target(newinfo, entry0, e))
> +						return 0;
>  				} else {
>  					/* ... this is a fallthru */
>  					newpos = pos + e->next_offset;
> diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
> index 63f7876c4f29..97a8d2525c26 100644
> --- a/net/ipv6/netfilter/ip6_tables.c
> +++ b/net/ipv6/netfilter/ip6_tables.c
> @@ -444,6 +444,19 @@ ip6t_do_table(struct sk_buff *skb,
>  #endif
>  }
>  
> +static bool find_jump_target(const struct xt_table_info *t,
> +			     const void *entry0,
> +			     const struct ip6t_entry *target)
> +{
> +	struct ip6t_entry *iter;
> +
> +	xt_entry_foreach(iter, entry0, t->size) {
> +		 if (iter == target)
> +			return true;
> +	}
> +	return false;
> +}
> +
>  /* Figures out from what hook each rule can be called: returns 0 if
>     there are loops.  Puts hook bitmask in comefrom. */
>  static int
> @@ -541,6 +554,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
>  					/* This a jump; chase it. */
>  					duprintf("Jump rule %u -> %u\n",
>  						 pos, newpos);
> +					e = (struct ip6t_entry *)
> +						(entry0 + newpos);
> +					if (!find_jump_target(newinfo, entry0, e))
> +						return 0;
>  				} else {
>  					/* ... this is a fallthru */
>  					newpos = pos + e->next_offset;
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-21  6:36   ` Jiri Slaby
@ 2016-07-21 18:56     ` Greg KH
  2016-07-21 19:00       ` Jiri Slaby
  0 siblings, 1 reply; 109+ messages in thread
From: Greg KH @ 2016-07-21 18:56 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Jiri Slaby, stable, linux-kernel, Florian Westphal, Pablo Neira Ayuso

On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> > From: Florian Westphal <fw@strlen.de>
> > 
> > 3.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ===============
> > 
> > commit 36472341017529e2b12573093cc0f68719300997 upstream.
> 
> I am now dropping this one. 3.12.62 will be released without that patch.
> After the performance issue is resolved, it will be requeued.

Personally, I think the bug fixes were more important than the
performance issues at this point in time, but it's your call to make :)

greg k-h

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-21 18:56     ` Greg KH
@ 2016-07-21 19:00       ` Jiri Slaby
  2016-07-25  5:45         ` Michal Kubecek
  0 siblings, 1 reply; 109+ messages in thread
From: Jiri Slaby @ 2016-07-21 19:00 UTC (permalink / raw)
  To: Greg KH, Jiri Slaby
  Cc: stable, linux-kernel, Florian Westphal, Pablo Neira Ayuso

On 07/21/2016, 08:56 PM, Greg KH wrote:
> On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
>> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
>>> From: Florian Westphal <fw@strlen.de>
>>>
>>> 3.12-stable review patch.  If anyone has any objections, please let me know.
>>>
>>> ===============
>>>
>>> commit 36472341017529e2b12573093cc0f68719300997 upstream.
>>
>> I am now dropping this one. 3.12.62 will be released without that patch.
>> After the performance issue is resolved, it will be requeued.
> 
> Personally, I think the bug fixes were more important than the
> performance issues at this point in time, but it's your call to make :)

Ok, but to quote [1]:
iptables-restore will take forever (gave up after 10 minutes)

I would say it proved itself not to be a performance issue, but rather a
functional issue :). Both Pablo and Florian suggested to postpone the patch.

[1]
http://thread.gmane.org/gmane.comp.security.firewalls.netfilter.devel/64099

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-21 19:00       ` Jiri Slaby
@ 2016-07-25  5:45         ` Michal Kubecek
  2016-07-25  6:41           ` Florian Westphal
  0 siblings, 1 reply; 109+ messages in thread
From: Michal Kubecek @ 2016-07-25  5:45 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Greg KH, Jiri Slaby, stable, linux-kernel, Florian Westphal,
	Pablo Neira Ayuso

On Thu, Jul 21, 2016 at 09:00:33PM +0200, Jiri Slaby wrote:
> On 07/21/2016, 08:56 PM, Greg KH wrote:
> > On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
> >> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> >>> From: Florian Westphal <fw@strlen.de>
> >>>
> >>> 3.12-stable review patch.  If anyone has any objections, please let me know.
> >>>
> >>> ===============
> >>>
> >>> commit 36472341017529e2b12573093cc0f68719300997 upstream.
> >>
> >> I am now dropping this one. 3.12.62 will be released without that patch.
> >> After the performance issue is resolved, it will be requeued.
> > 
> > Personally, I think the bug fixes were more important than the
> > performance issues at this point in time, but it's your call to make :)
> 
> Ok, but to quote [1]:
> iptables-restore will take forever (gave up after 10 minutes)
> 
> I would say it proved itself not to be a performance issue, but rather a
> functional issue :). Both Pablo and Florian suggested to postpone the patch.

Even worse: because of a shared lock which is held for all this time,
this allows (on kernel >= 3.8) an unprivileged user to block similar
operation in all network namespaces including init_net.

While a partial DoS like this is certainly better than allowing to crash
the system, it could still be considered a security issue.

Michal Kubecek

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-25  5:45         ` Michal Kubecek
@ 2016-07-25  6:41           ` Florian Westphal
  2016-07-25  6:51               ` Michal Kubecek
  0 siblings, 1 reply; 109+ messages in thread
From: Florian Westphal @ 2016-07-25  6:41 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: Jiri Slaby, Greg KH, Jiri Slaby, stable, linux-kernel,
	Florian Westphal, Pablo Neira Ayuso

Michal Kubecek <mkubecek@suse.cz> wrote:
> On Thu, Jul 21, 2016 at 09:00:33PM +0200, Jiri Slaby wrote:
> > On 07/21/2016, 08:56 PM, Greg KH wrote:
> > > On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
> > >> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> > >>> From: Florian Westphal <fw@strlen.de>
> > >>>
> > >>> 3.12-stable review patch.  If anyone has any objections, please let me know.
> > >>>
> > >>> ===============
> > >>>
> > >>> commit 36472341017529e2b12573093cc0f68719300997 upstream.
> > >>
> > >> I am now dropping this one. 3.12.62 will be released without that patch.
> > >> After the performance issue is resolved, it will be requeued.
> > > 
> > > Personally, I think the bug fixes were more important than the
> > > performance issues at this point in time, but it's your call to make :)
> > 
> > Ok, but to quote [1]:
> > iptables-restore will take forever (gave up after 10 minutes)
> > 
> > I would say it proved itself not to be a performance issue, but rather a
> > functional issue :). Both Pablo and Florian suggested to postpone the patch.
> 
> Even worse: because of a shared lock which is held for all this time,
> this allows (on kernel >= 3.8) an unprivileged user to block similar
> operation in all network namespaces including init_net.

What lock are you talking about?

The table lock is aquired after the sanity/translation pass.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-25  6:41           ` Florian Westphal
@ 2016-07-25  6:51               ` Michal Kubecek
  0 siblings, 0 replies; 109+ messages in thread
From: Michal Kubecek @ 2016-07-25  6:51 UTC (permalink / raw)
  To: Florian Westphal
  Cc: Jiri Slaby, Greg KH, Jiri Slaby, stable, linux-kernel, Pablo Neira Ayuso

On pondělí 25. července 2016 8:41 Florian Westphal wrote:
> Michal Kubecek <mkubecek@suse.cz> wrote:
> > On Thu, Jul 21, 2016 at 09:00:33PM +0200, Jiri Slaby wrote:
> > > On 07/21/2016, 08:56 PM, Greg KH wrote:
> > > > On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
> > > >> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> > > >>> From: Florian Westphal <fw@strlen.de>
> > > >>> 
> > > >>> 3.12-stable review patch.  If anyone has any objections,
> > > >>> please let me know.
> > > >>> 
> > > >>> ===============
> > > >>> 
> > > >>> commit 36472341017529e2b12573093cc0f68719300997 upstream.
> > > >> 
> > > >> I am now dropping this one. 3.12.62 will be released without
> > > >> that patch. After the performance issue is resolved, it will
> > > >> be requeued.> > > 
> > > > Personally, I think the bug fixes were more important than the
> > > > performance issues at this point in time, but it's your call to
> > > > make :)> > 
> > > Ok, but to quote [1]:
> > > iptables-restore will take forever (gave up after 10 minutes)
> > > 
> > > I would say it proved itself not to be a performance issue, but
> > > rather a functional issue :). Both Pablo and Florian suggested to
> > > postpone the patch.> 
> > Even worse: because of a shared lock which is held for all this
> > time,
> > this allows (on kernel >= 3.8) an unprivileged user to block similar
> > operation in all network namespaces including init_net.
> 
> What lock are you talking about?
> 
> The table lock is aquired after the sanity/translation pass.

I meant xt_compat_lock(AF_INET) (or AF_INET6 or NFPROTO_ARP) which is 
held for almost all of translate_compat_table().

Michal Kubecek

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
@ 2016-07-25  6:51               ` Michal Kubecek
  0 siblings, 0 replies; 109+ messages in thread
From: Michal Kubecek @ 2016-07-25  6:51 UTC (permalink / raw)
  To: Florian Westphal
  Cc: Jiri Slaby, Greg KH, Jiri Slaby, stable, linux-kernel, Pablo Neira Ayuso

On pond�l� 25. �ervence 2016 8:41 Florian Westphal wrote:
> Michal Kubecek <mkubecek@suse.cz> wrote:
> > On Thu, Jul 21, 2016 at 09:00:33PM +0200, Jiri Slaby wrote:
> > > On 07/21/2016, 08:56 PM, Greg KH wrote:
> > > > On Thu, Jul 21, 2016 at 08:36:18AM +0200, Jiri Slaby wrote:
> > > >> On 07/14/2016, 10:15 AM, Jiri Slaby wrote:
> > > >>> From: Florian Westphal <fw@strlen.de>
> > > >>> 
> > > >>> 3.12-stable review patch.  If anyone has any objections,
> > > >>> please let me know.
> > > >>> 
> > > >>> ===============
> > > >>> 
> > > >>> commit 36472341017529e2b12573093cc0f68719300997 upstream.
> > > >> 
> > > >> I am now dropping this one. 3.12.62 will be released without
> > > >> that patch. After the performance issue is resolved, it will
> > > >> be requeued.> > > 
> > > > Personally, I think the bug fixes were more important than the
> > > > performance issues at this point in time, but it's your call to
> > > > make :)> > 
> > > Ok, but to quote [1]:
> > > iptables-restore will take forever (gave up after 10 minutes)
> > > 
> > > I would say it proved itself not to be a performance issue, but
> > > rather a functional issue :). Both Pablo and Florian suggested to
> > > postpone the patch.> 
> > Even worse: because of a shared lock which is held for all this
> > time,
> > this allows (on kernel >= 3.8) an unprivileged user to block similar
> > operation in all network namespaces including init_net.
> 
> What lock are you talking about?
> 
> The table lock is aquired after the sanity/translation pass.

I meant xt_compat_lock(AF_INET) (or AF_INET6 or NFPROTO_ARP) which is 
held for almost all of translate_compat_table().

Michal Kubecek

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps
  2016-07-25  6:51               ` Michal Kubecek
  (?)
@ 2016-07-25  7:27               ` Florian Westphal
  -1 siblings, 0 replies; 109+ messages in thread
From: Florian Westphal @ 2016-07-25  7:27 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: Florian Westphal, Jiri Slaby, Greg KH, Jiri Slaby, stable,
	linux-kernel, Pablo Neira Ayuso

Michal Kubecek <mkubecek@suse.cz> wrote:
> > What lock are you talking about?
> > 
> > The table lock is aquired after the sanity/translation pass.
> 
> I meant xt_compat_lock(AF_INET) (or AF_INET6 or NFPROTO_ARP) which is 
> held for almost all of translate_compat_table().

Ah, true.  Fortunately most installations won't use this.

^ permalink raw reply	[flat|nested] 109+ messages in thread

end of thread, other threads:[~2016-07-25  7:27 UTC | newest]

Thread overview: 109+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-14  8:16 [PATCH 3.12 00/88] 3.12.62-stable review Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 01/88] PCI/AER: Clear error status registers during enumeration and restore Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 02/88] MIPS: Fix 64k page support for 32 bit kernels Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 03/88] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 04/88] sparc: Fix system call tracing register handling Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 05/88] sparc64: Fix bootup regressions on some Kconfig combinations Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 06/88] sparc64: Fix sparc64_set_context stack handling Jiri Slaby
2016-07-14  8:14 ` [PATCH 3.12 07/88] sparc/PCI: Fix for panic while enabling SR-IOV Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 08/88] sparc64: Take ctx_alloc_lock properly in hugetlb_setup() Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 09/88] sparc: Harden signal return frame checks Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 10/88] sparc64: Fix return from trap window fill crashes Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 11/88] perf/x86: Honor the architectural performance monitoring version Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 12/88] perf/x86: Fix undefined shift on 32-bit kernels Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 13/88] netlink: Fix dump skb leak/double free Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 14/88] udp: prevent skbs lingering in tunnel socket queues Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 15/88] tcp: record TLP and ER timer stats in v6 stats Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 16/88] ipv6: Skip XFRM lookup if dst_entry in socket cache is valid Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 17/88] macintosh/therm_windtunnel: Export I2C module alias information Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 18/88] drivers: macintosh: rack-meter: limit idle ticks to total ticks Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 19/88] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 20/88] ARM: fix PTRACE_SETVFPREGS on SMP systems Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 21/88] powerpc: Fix definition of SIAR and SDAR registers Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 22/88] powerpc: Use privileged SPR number for MMCR2 Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 23/88] parisc: Fix pagefault crash in unaligned __get_user() call Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 24/88] ecryptfs: forbid opening files without mmap handler Jiri Slaby
     [not found]   ` <20160716192134.72132405@desktop.jensen.local>
2016-07-18 11:55     ` Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 25/88] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 26/88] fix d_walk()/non-delayed __d_free() race Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 27/88] netfilter: x_tables: don't move to non-existent next rule Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 28/88] netfilter: x_tables: validate targets of jumps Jiri Slaby
2016-07-21  6:36   ` Jiri Slaby
2016-07-21 18:56     ` Greg KH
2016-07-21 19:00       ` Jiri Slaby
2016-07-25  5:45         ` Michal Kubecek
2016-07-25  6:41           ` Florian Westphal
2016-07-25  6:51             ` Michal Kubecek
2016-07-25  6:51               ` Michal Kubecek
2016-07-25  7:27               ` Florian Westphal
2016-07-14  8:15 ` [PATCH 3.12 29/88] netfilter: x_tables: add and use xt_check_entry_offsets Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 30/88] netfilter: x_tables: kill check_entry helper Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 31/88] netfilter: x_tables: assert minimum target size Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 32/88] netfilter: x_tables: add compat version of xt_check_entry_offsets Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 33/88] netfilter: x_tables: check standard target size too Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 34/88] netfilter: x_tables: check for bogus target offset Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 35/88] netfilter: x_tables: validate all offsets and sizes in a rule Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 36/88] netfilter: x_tables: don't reject valid target size on some architectures Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 37/88] netfilter: arp_tables: simplify translate_compat_table args Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 38/88] netfilter: ip_tables: " Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 39/88] netfilter: ip6_tables: " Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 40/88] netfilter: x_tables: xt_compat_match_from_user doesn't need a retval Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 41/88] netfilter: ensure number of counters is >0 in do_replace() Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 42/88] netfilter: x_tables: do compat validation via translate_table Jiri Slaby
2016-07-19  7:13   ` Michal Kubecek
2016-07-19  8:40     ` Florian Westphal
2016-07-19  9:13       ` Florian Westphal
2016-07-19  9:45         ` Michal Kubecek
2016-07-14  8:15 ` [PATCH 3.12 43/88] Revert "netfilter: ensure number of counters is >0 in do_replace()" Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 44/88] netfilter: x_tables: introduce and use xt_copy_counters_from_user Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 45/88] crypto: ux500 - memmove the right size Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 46/88] sit: correct IP protocol used in ipip6_err Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 47/88] ipmr/ip6mr: Initialize the last assert time of mfc entries Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 48/88] net: alx: Work around the DMA RX overflow issue Jiri Slaby
2016-07-14  8:15   ` Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 49/88] usb: quirks: Add no-lpm quirk for Acer C120 LED Projector Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 50/88] usb: musb: Stop bulk endpoint while queue is rotated Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 51/88] usb: musb: Ensure rx reinit occurs for shared_fifo endpoints Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 52/88] mac80211: mesh: flush mesh paths unconditionally Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 53/88] mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 54/88] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 55/88] powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 56/88] powerpc/pseries: Fix PCI config address for DDW Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 57/88] USB: EHCI: declare hostpc register as zero-length array Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 58/88] x86, build: copy ldlinux.c32 to image.iso Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 59/88] kprobes/x86: Clear TF bit in fault on single-stepping Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 60/88] x86/amd_nb: Fix boot crash on non-AMD systems Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 61/88] make nfs_atomic_open() call d_drop() on all ->open_context() errors Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 62/88] NFS: Fix another OPEN_DOWNGRADE bug Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 63/88] ARM: 8578/1: mm: ensure pmd_present only checks the valid bit Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 64/88] mm: Export migrate_page_move_mapping and migrate_page_copy Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 65/88] UBIFS: Implement ->migratepage() Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 66/88] scsi: remove scsi_end_request Jiri Slaby
2016-07-14  8:15 ` [PATCH 3.12 67/88] scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 68/88] Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 69/88] USB: usbfs: fix potential infoleak in devio Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 70/88] ktime: export ktime_divns Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 71/88] ALSA: hrtimer: Handle start/stop more properly Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 72/88] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 73/88] ALSA: timer: Fix leak in events via snd_timer_user_ccallback Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 74/88] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 75/88] net/qlge: Avoids recursive EEH error Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 76/88] rds: fix an infoleak in rds_inc_info_copy Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 77/88] EDAC: Remove arbitrary limit on number of channels Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 78/88] SCSI: Increase REPORT_LUNS timeout Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 79/88] KEYS: potential uninitialized variable Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 80/88] base: make module_create_drivers_dir race-free Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 81/88] KVM: x86: expose invariant tsc cpuid bit (v2) Jiri Slaby
2016-07-14  8:40   ` Paolo Bonzini
2016-07-14  9:22     ` Jiri Slaby
2016-07-14  9:41       ` Paolo Bonzini
2016-07-14  8:16 ` [PATCH 3.12 82/88] mm/swap.c: flush lru pvecs on compound page arrival Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 83/88] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 84/88] ALSA: compress: fix an integer overflow check Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 85/88] HID: elo: kill not flush the work Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 86/88] cdc_ncm: workaround for EM7455 "silent" data interface Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 87/88] MIPS: KVM: Fix modular KVM under QEMU Jiri Slaby
2016-07-14  8:16 ` [PATCH 3.12 88/88] signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo Jiri Slaby
2016-07-14 20:20 ` [PATCH 3.12 00/88] 3.12.62-stable review Guenter Roeck
2016-07-15  7:31   ` Jiri Slaby
2016-07-14 21:45 ` Shuah Khan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.