Skip to contentSkip to conversation

3.14.72-stable review

PATCH In review Greg Kroah-Hartman 5 participants 27 messages Jun 5, 2016 – Jun 8, 2016

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 3.14.72-stable review

This is the start of the stable review cycle for the 3.14.72 release. There are 23 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 Tue Jun 7 21:38:01 UTC 2016. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.72-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 3.14.72-rc1

Dave Chinner <[email protected]>
xfs: skip stale inodes in xfs_iflush_cluster

Dave Chinner <[email protected]>
xfs: fix inode validity check in xfs_iflush_cluster

Dave Chinner <[email protected]>
xfs: xfs_iflush_cluster fails to abort on error

Ville Syrjälä <[email protected]>
dma-debug: avoid spinlock recursion when disabling dma-debug

Nicolai Stange <[email protected]>
ext4: silence UBSAN in ext4_mb_init()

Nicolai Stange <[email protected]>
ext4: address UBSAN warning in mb_find_order_for_block()

Theodore Ts'o <[email protected]>
ext4: fix hang when processing corrupted orphaned inode list

Lyude <[email protected]>

    drm/fb_helper: Fix references to dev->mode_config.num_connector

Itai Handler <[email protected]>
drm/gma500: Fix possible out of bounds read

Tomáš Trnka <[email protected]>
sunrpc: fix stripping of padded MIC tokens

Ross Lagerwall <[email protected]>
xen/events: Don't move disabled irqs

Hari Bathini <[email protected]>
powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel

Ben Hutchings <[email protected]>
pipe: Fix buffer offset after partially failed read

wang yanqing <[email protected]>
rtlwifi: Fix logic error in enter/exit power-save mode

Prarit Bhargava <[email protected]>
PCI: Disable all BAR sizing for devices with non-compliant BARs

Dave Gerlach <[email protected]>
cpuidle: Indicate when a device has been unregistered

Raghava Aditya Renukunta <[email protected]>
aacraid: Fix for aac_command_thread hang

Raghava Aditya Renukunta <[email protected]>
aacraid: Relinquish CPU during timeout wait

Joseph Salisbury <[email protected]>
ath5k: Change led pin configuration for compaq c700 laptop

Ricky Liang <[email protected]>
Input: uinput - handle compat ioctl for UI_SET_PHYS

Matthias Schiffer <[email protected]>
MIPS: ath79: make bootconsole wait for both THRE and TEMT

James Hogan <[email protected]>
MIPS: Fix siginfo.h to use strict posix types

Paul Burton <[email protected]>

    MIPS: math-emu: Fix jalr emulation when rd == $0

-------------

Diffstat:

 Makefile                                      |  4 ++--
 arch/mips/ath79/early_printk.c                |  6 ++++--
 arch/mips/include/uapi/asm/siginfo.h          | 18 +++++++++---------
 arch/mips/math-emu/cp1emu.c                   |  8 +++++---
 arch/powerpc/kernel/exceptions-64s.S          | 16 +++++++++++-----
 drivers/cpuidle/cpuidle.c                     |  2 ++
 drivers/gpu/drm/drm_fb_helper.c               |  5 ++---
 drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c |  2 +-
 drivers/input/misc/uinput.c                   |  6 ++++++
 drivers/net/wireless/ath/ath5k/led.c          |  2 +-
 drivers/net/wireless/rtlwifi/base.c           |  4 ++--
 drivers/pci/probe.c                           |  6 +++---
 drivers/scsi/aacraid/commsup.c                | 12 ++++++++----
 drivers/xen/events/events_base.c              |  6 ++++--
 fs/ext4/ialloc.c                              | 10 ++++++----
 fs/ext4/mballoc.c                             | 10 +++++++---
 fs/pipe.c                                     |  5 ++++-
 fs/xfs/xfs_inode.c                            | 26 ++++++++++++++++++--------
 lib/dma-debug.c                               |  2 +-
 net/sunrpc/auth_gss/svcauth_gss.c             |  4 ++--
 20 files changed, 98 insertions(+), 56 deletions(-)
author maintainer
#1 lore raw

PATCH 1/23 MIPS: math-emu: Fix jalr emulation when rd == $0

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

------------------

From: Paul Burton <[email protected]>

commit ab4a92e66741b35ca12f8497896bafbe579c28a1 upstream.

When emulating a jalr instruction with rd == $0, the code in isBranchInstr was incorrectly writing to GPR $0 which should actually always remain zeroed. This would lead to any further instructions emulated which use $0 operating on a bogus value until the task is next context switched, at which point the value of $0 in the task context would be restored to the correct zero by a store in SAVE_SOME. Fix this by not writing to rd if it is $0.

Fixes 102cedc32a6e ("MIPS: microMIPS: Floating point support.")
Cc Maciej W. Rozycki <[email protected]>
Cc James Hogan <[email protected]>

Patchwork: https://patchwork.linux-mips.org/patch/13160/

---
 arch/mips/math-emu/cp1emu.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
arch/mips/math-emu/cp1emu.c +5 -3
@@ -676,9 +676,11 @@ static int isBranchInstr(struct pt_regs
 	case spec_op:
 		switch (insn.r_format.func) {
 		case jalr_op:
-			regs->regs[insn.r_format.rd] =
-				regs->cp0_epc + dec_insn.pc_inc +
-				dec_insn.next_pc_inc;
+			if (insn.r_format.rd != 0) {
+				regs->regs[insn.r_format.rd] =
+					regs->cp0_epc + dec_insn.pc_inc +
+					dec_insn.next_pc_inc;
+			}
 			/* Fall through */
 		case jr_op:
 			*contpc = regs->regs[insn.r_format.rs];
author maintainer
#2 lore raw

PATCH 2/23 MIPS: Fix siginfo.h to use strict posix types

In reply to Greg Kroah-Hartman

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

------------------

From: James Hogan <[email protected]>

commit 5daebc477da4dfeb31ae193d83084def58fd2697 upstream.

Commit 85efde6f4e0d ("make exported headers use strict posix types") changed the asm-generic siginfo.h to use the __kernel_* types, and commit 3a471cbc081b ("remove __KERNEL_STRICT_NAMES") make the internal types accessible only to the kernel, but the MIPS implementation hasn't been updated to match.

Switch to proper types now so that the exported asm/siginfo.h won't produce quite so many compiler errors when included alone by a user program.

Patchwork: https://patchwork.linux-mips.org/patch/12477/

---
 arch/mips/include/uapi/asm/siginfo.h |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
arch/mips/include/uapi/asm/siginfo.h +9 -9
@@ -48,13 +48,13 @@ typedef struct siginfo {
 
 		/* kill() */
 		struct {
-			pid_t _pid;		/* sender's pid */
+			__kernel_pid_t _pid;	/* sender's pid */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 		} _kill;
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;		/* timer id */
+			__kernel_timer_t _tid;	/* timer id */
 			int _overrun;		/* overrun count */
 			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
 			sigval_t _sigval;	/* same as below */
@@ -63,26 +63,26 @@ typedef struct siginfo {
 
 		/* POSIX.1b signals */
 		struct {
-			pid_t _pid;		/* sender's pid */
+			__kernel_pid_t _pid;	/* sender's pid */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 			sigval_t _sigval;
 		} _rt;
 
 		/* SIGCHLD */
 		struct {
-			pid_t _pid;		/* which child */
+			__kernel_pid_t _pid;	/* which child */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 			int _status;		/* exit code */
-			clock_t _utime;
-			clock_t _stime;
+			__kernel_clock_t _utime;
+			__kernel_clock_t _stime;
 		} _sigchld;
 
 		/* IRIX SIGCHLD */
 		struct {
-			pid_t _pid;		/* which child */
-			clock_t _utime;
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_clock_t _utime;
 			int _status;		/* exit code */
-			clock_t _stime;
+			__kernel_clock_t _stime;
 		} _irix_sigchld;
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
author maintainer
#3 lore raw

PATCH 3/23 MIPS: ath79: make bootconsole wait for both THRE and TEMT

In reply to Greg Kroah-Hartman

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

------------------

From: Matthias Schiffer <[email protected]>

commit f5b556c94c8490d42fea79d7b4ae0ecbc291e69d upstream.

This makes the ath79 bootconsole behave the same way as the generic 8250 bootconsole.

Also waiting for TEMT (transmit buffer is empty) instead of just THRE (transmit buffer is not full) ensures that all characters have been transmitted before the real serial driver starts reconfiguring the serial controller (which would sometimes result in garbage being transmitted.) This change does not cause a visible performance loss.

In addition, this seems to fix a hang observed in certain configurations on many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver.

A more complete follow-up patch will disable 8250 autoconfig for ath79 altogether (the serial controller is detected as a 16550A, which is not fully compatible with the ath79 serial, and the autoconfig may lead to undefined behavior on ath79.)

---
 arch/mips/ath79/early_printk.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/mips/ath79/early_printk.c +4 -2
@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(voi
 	} while (1);
 }
 
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
 static void prom_putchar_ar71xx(unsigned char ch)
 {
 	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
 
-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
 	__raw_writel(ch, base + UART_TX * 4);
-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
 }
 
 static void prom_putchar_ar933x(unsigned char ch)
author maintainer
#4 lore raw

PATCH 4/23 Input: uinput - handle compat ioctl for UI_SET_PHYS

In reply to Greg Kroah-Hartman

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

------------------

From: Ricky Liang <[email protected]>

commit affa80bd97f7ca282d1faa91667b3ee9e4c590e6 upstream.

When running a 32-bit userspace on a 64-bit kernel, the UI_SET_PHYS ioctl needs to be treated with special care, as it has the pointer size encoded in the command.

---
 drivers/input/misc/uinput.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/input/misc/uinput.c +6 -0
@@ -845,9 +845,15 @@ static long uinput_ioctl(struct file *fi
 }
 
 #ifdef CONFIG_COMPAT
+
+#define UI_SET_PHYS_COMPAT	_IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
+
 static long uinput_compat_ioctl(struct file *file,
 				unsigned int cmd, unsigned long arg)
 {
+	if (cmd == UI_SET_PHYS_COMPAT)
+		cmd = UI_SET_PHYS;
+
 	return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
 }
 #endif
author maintainer
#5 lore raw

PATCH 5/23 ath5k: Change led pin configuration for compaq c700 laptop

In reply to Greg Kroah-Hartman

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

------------------

From: Joseph Salisbury <[email protected]>

commit 7b9bc799a445aea95f64f15e0083cb19b5789abe upstream.

Commit 09c9bae26b0d3c9472cb6ae45010460a2cee8b8d ("ath5k: add led pin configuration for compaq c700 laptop") added a pin configuration for the Compaq c700 laptop. However, the polarity of the led pin is reversed. It should be red for wifi off and blue for wifi on, but it is the opposite. This bug was reported in the following bug report:
http://pad.lv/972604

Fixes 09c9bae26b0d3c9472cb6ae45010460a2cee8b8d ("ath5k: add led pin configuration for compaq c700 laptop")
---
 drivers/net/wireless/ath/ath5k/led.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath5k/led.c +1 -1
@@ -77,7 +77,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_led
 	/* HP Compaq CQ60-206US ([email protected]) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
 	/* HP Compaq C700 ([email protected]) */
-	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
+	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 0) },
 	/* LiteOn AR5BXB63 ([email protected]) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
 	/* IBM-specific AR5212 (all others) */
author maintainer
#6 lore raw

PATCH 6/23 aacraid: Relinquish CPU during timeout wait

In reply to Greg Kroah-Hartman

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

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit 07beca2be24cc710461c0b131832524c9ee08910 upstream.

aac_fib_send has a special function case for initial commands during driver initialization using wait < 0(pseudo sync mode). In this case, the command does not sleep but rather spins checking for timeout.This loop is calls cpu_relax() in an attempt to allow other processes/threads to use the CPU, but this function does not relinquish the CPU and so the command will hog the processor. This was observed in a KDUMP "crashkernel" and that prevented the "command thread" (which is responsible for completing the command from being timed out) from starting because it could not get the CPU.

Fixed by replacing "cpu_relax()" call with "schedule()"

---
 drivers/scsi/aacraid/commsup.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/aacraid/commsup.c +4 -4
@@ -590,10 +590,10 @@ int aac_fib_send(u16 command, struct fib
 					}
 					return -EFAULT;
 				}
-				/* We used to udelay() here but that absorbed
-				 * a CPU when a timeout occured. Not very
-				 * useful. */
-				cpu_relax();
+				/*
+				 * Allow other processes / CPUS to use core
+				 */
+				schedule();
 			}
 		} else if (down_interruptible(&fibptr->event_wait)) {
 			/* Do nothing ... satisfy
author maintainer
#7 lore raw

PATCH 7/23 aacraid: Fix for aac_command_thread hang

In reply to Greg Kroah-Hartman

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

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit fc4bf75ea300a5e62a2419f89dd0e22189dd7ab7 upstream.

Typically under error conditions, it is possible for aac_command_thread() to miss the wakeup from kthread_stop() and go back to sleep, causing it to hang aac_shutdown.

In the observed scenario, the adapter is not functioning correctly and so aac_fib_send() never completes (or time-outs depending on how it was called). Shortly after aac_command_thread() starts it performs aac_fib_send(SendHostTime) which hangs. When aac_probe_one /aac_get_adapter_info send time outs, kthread_stop is called which breaks the command thread out of it's hang.

The code will still go back to sleep in schedule_timeout() without checking kthread_should_stop() so it causes aac_probe_one to hang until the schedule_timeout() which is 30 minutes.

Fixed by: Adding another kthread_should_stop() before schedule_timeout()

---
 drivers/scsi/aacraid/commsup.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/scsi/aacraid/commsup.c +4 -0
@@ -1921,6 +1921,10 @@ int aac_command_thread(void *data)
 		if (difference <= 0)
 			difference = 1;
 		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (kthread_should_stop())
+			break;
+
 		schedule_timeout(difference);
 
 		if (kthread_should_stop())
author maintainer
#8 lore raw

PATCH 8/23 cpuidle: Indicate when a device has been unregistered

In reply to Greg Kroah-Hartman

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

------------------

From: Dave Gerlach <[email protected]>

commit c998c07836f985b24361629dc98506ec7893e7a0 upstream.

Currently the 'registered' member of the cpuidle_device struct is set to 1 during cpuidle_register_device. In this same function there are checks to see if the device is already registered to prevent duplicate calls to register the device, but this value is never set to 0 even on unregister of the device. Because of this, any attempt to call cpuidle_register_device after a call to cpuidle_unregister_device will fail which shouldn't be the case.

To prevent this, set registered to 0 when the device is unregistered.

Fixes c878a52d3c7c (cpuidle: Check if device is already registered)
---
 drivers/cpuidle/cpuidle.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/cpuidle/cpuidle.c +2 -0
@@ -313,6 +313,8 @@ static void __cpuidle_unregister_device(
 	list_del(&dev->device_list);
 	per_cpu(cpuidle_devices, dev->cpu) = NULL;
 	module_put(drv->owner);
+
+	dev->registered = 0;
 }
 
 static void __cpuidle_device_init(struct cpuidle_device *dev)
author maintainer
#9 lore raw

PATCH 9/23 PCI: Disable all BAR sizing for devices with non-compliant BARs

In reply to Greg Kroah-Hartman

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

------------------

From: Prarit Bhargava <[email protected]>

commit ad67b437f187ea818b2860524d10f878fadfdd99 upstream.

b84106b4e229 ("PCI: Disable IO/MEM decoding for devices with non-compliant BARs") disabled BAR sizing for BARs 0-5 of devices that don't comply with the PCI spec. But it didn't do anything for expansion ROM BARs, so we still try to size them, resulting in warnings like this on Broadwell-EP:

pci 0000:ff:12.0: BAR 6: failed to assign [mem size 0x00000001 pref]

Move the non-compliant BAR check from __pci_read_base() up to pci_read_bases() so it applies to the expansion ROM BAR as well as to BARs 0-5.

Note that direct callers of __pci_read_base(), like sriov_init(), will now bypass this check. We haven't had reports of devices with broken SR-IOV BARs yet.

[bhelgaas: changelog]
Fixes b84106b4e229 ("PCI: Disable IO/MEM decoding for devices with non-compliant BARs")
CC Thomas Gleixner <[email protected]>
CC Ingo Molnar <[email protected]>
CC "H. Peter Anvin" <[email protected]>
CC Andi Kleen <[email protected]>
---
 drivers/pci/probe.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pci/probe.c +3 -3
@@ -175,9 +175,6 @@ int __pci_read_base(struct pci_dev *dev,
 	struct pci_bus_region region, inverted_region;
 	bool bar_too_big = false, bar_disabled = false;
 
-	if (dev->non_compliant_bars)
-		return 0;
-
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
 	/* No printks while decoding is disabled! */
@@ -319,6 +316,9 @@ static void pci_read_bases(struct pci_de
 {
 	unsigned int pos, reg;
 
+	if (dev->non_compliant_bars)
+		return;
+
 	for (pos = 0; pos < howmany; pos++) {
 		struct resource *res = &dev->resource[pos];
 		reg = PCI_BASE_ADDRESS_0 + (pos << 2);
author maintainer
#10 lore raw

PATCH 10/23 rtlwifi: Fix logic error in enter/exit power-save mode

In reply to Greg Kroah-Hartman

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

------------------

From: wang yanqing <[email protected]>

commit 873ffe154ae074c46ed2d72dbd9a2a99f06f55b4 upstream.

In commit a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter() to use work queue"), the tests for enter/exit power-save mode were inverted. With this change applied, the wifi connection becomes much more stable.

Fixes a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter() to use work queue")
---
 drivers/net/wireless/rtlwifi/base.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/rtlwifi/base.c +2 -2
@@ -1401,9 +1401,9 @@ void rtl_watchdog_wq_callback(void *data
 		if (((rtlpriv->link_info.num_rx_inperiod +
 		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
 		    (rtlpriv->link_info.num_rx_inperiod > 2))
-			rtlpriv->enter_ps = true;
-		else
 			rtlpriv->enter_ps = false;
+		else
+			rtlpriv->enter_ps = true;
 
 		/* LeisurePS only work in infra mode. */
 		schedule_work(&rtlpriv->works.lps_change_work);
author maintainer
#11 lore raw

PATCH 11/23 pipe: Fix buffer offset after partially failed read

In reply to Greg Kroah-Hartman

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

------------------

From: Ben Hutchings <[email protected]>

commit feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 upstream.

Quoting the RHEL advisory:

Quoted 5 lines

It was found that the fix for CVE-2015-1805 incorrectly kept buffer offset and buffer length in sync on a failed atomic read, potentially resulting in a pipe buffer state corruption. A local, unprivileged user could use this flaw to crash the system or leak kernel memory to user space. (CVE-2016-0774, Moderate)

The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds.

References: https://rhn.redhat.com/errata/RHSA-2016-0103.html

---
 fs/pipe.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/pipe.c +4 -1
@@ -401,6 +401,7 @@ pipe_read(struct kiocb *iocb, const stru
 			void *addr;
 			size_t chars = buf->len, remaining;
 			int error, atomic;
+			int offset;
 
 			if (chars > total_len)
 				chars = total_len;
@@ -414,9 +415,10 @@ pipe_read(struct kiocb *iocb, const stru
 
 			atomic = !iov_fault_in_pages_write(iov, chars);
 			remaining = chars;
+			offset = buf->offset;
 redo:
 			addr = ops->map(pipe, buf, atomic);
-			error = pipe_iov_copy_to_user(iov, addr, &buf->offset,
+			error = pipe_iov_copy_to_user(iov, addr, &offset,
 						      &remaining, atomic);
 			ops->unmap(pipe, buf, addr);
 			if (unlikely(error)) {
@@ -432,6 +434,7 @@ redo:
 				break;
 			}
 			ret += chars;
+			buf->offset += chars;
 			buf->len -= chars;
 
 			/* Was it a packet buffer? Clean up and exit */
#12 lore raw

Re: [PATCH 3.14 11/23] pipe: Fix buffer offset after partially failed read

Quoted 7 lines · Greg Kroah-Hartman

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

------------------

From: Ben Hutchings <[email protected]>

commit feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 upstream.

This is not a SHA of an upstream commit ;).

Quoted 13 lines

Quoting the RHEL advisory:

Quoted 5 lines

It was found that the fix for CVE-2015-1805 incorrectly kept buffer offset and buffer length in sync on a failed atomic read, potentially resulting in a pipe buffer state corruption. A local, unprivileged user could use this flaw to crash the system or leak kernel memory to user space. (CVE-2016-0774, Moderate)

The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds.

Quoted 4 lines

References: https://rhn.redhat.com/errata/RHSA-2016-0103.html

thanks,

Signature · 2 lines
js
suse labs
#13 lore raw

Re: [PATCH 3.14 11/23] pipe: Fix buffer offset after partially failed read

Quoted 11 lines · Jiri Slaby
Quoted 8 lines · Greg Kroah-Hartman

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

------------------

From: Ben Hutchings <[email protected]>

commit feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 upstream.

This is not a SHA of an upstream commit ;).

Indeed, that's from the stable/linux-3.2.y branch.  There is no upstream commit since the bug was never introduced there.

Ben.

Quoted 23 lines
Quoted 17 lines

Quoting the RHEL advisory:

Quoted 9 lines

It was found that the fix for CVE-2015-1805 incorrectly kept buffer
offset and buffer length in sync on a failed atomic read, potentially
resulting in a pipe buffer state corruption. A local, unprivileged user
could use this flaw to crash the system or leak kernel memory to user
space. (CVE-2016-0774, Moderate)

The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds.

Quoted 4 lines

References: https://rhn.redhat.com/errata/RHSA-2016-0103.html

thanks,

Signature · 2 lines
Ben Hutchings
When in doubt, use brute force. - Ken Thompson
author maintainer
#14 lore raw

PATCH 12/23 powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel

In reply to Greg Kroah-Hartman

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

------------------

From: Hari Bathini <[email protected]>

commit 8ed8ab40047a570fdd8043a40c104a57248dd3fd upstream.

Some of the interrupt vectors on 64-bit POWER server processors are only 32 bytes long (8 instructions), which is not enough for the full first-level interrupt handler. For these we need to branch to an out-of-line (OOL) handler. But when we are running a relocatable kernel, interrupt vectors till __end_interrupts marker are copied down to real address 0x100. So, branching to labels (ie. OOL handlers) outside this section must be handled differently (see LOAD_HANDLER()), considering relocatable kernel, which would need at least 4 instructions.

However, branching from interrupt vector means that we corrupt the CFAR (come-from address register) on POWER7 and later processors as mentioned in commit 1707dd16. So, EXCEPTION_PROLOG_0 (6 instructions) that contains the part up to the point where the CFAR is saved in the PACA should be part of the short interrupt vectors before we branch out to OOL handlers.

But as mentioned already, there are interrupt vectors on 64-bit POWER server processors that are only 32 bytes long (like vectors 0x4f00, 0x4f20, etc.), which cannot accomodate the above two cases at the same time owing to space constraint. Currently, in these interrupt vectors, we simply branch out to OOL handlers, without using LOAD_HANDLER(), which leaves us vulnerable when running a relocatable kernel (eg. kdump case). While this has been the case for sometime now and kdump is used widely, we were fortunate not to see any problems so far, for three reasons:

1. In almost all cases, production kernel (relocatable) is used for kdump as well, which would mean that crashed kernel's OOL handler would be at the same place where we end up branching to, from short interrupt vector of kdump kernel.
2. Also, OOL handler was unlikely the reason for crash in almost all the kdump scenarios, which meant we had a sane OOL handler from crashed kernel that we branched to.
3. On most 64-bit POWER server processors, page size is large enough that marking interrupt vector code as executable (see commit 429d2e83) leads to marking OOL handler code from crashed kernel, that sits right below interrupt vector code from kdump kernel, as executable as well.

Let us fix this by moving the __end_interrupts marker down past OOL handlers to make sure that we also copy OOL handlers to real address 0x100 when running a relocatable kernel.

This fix has been tested successfully in kdump scenario, on an LPAR with 4K page size by using different default/production kernel and kdump kernel.

Also tested by manually corrupting the OOL handlers in the first kernel and then kdump'ing, and then causing the OOL handlers to fire - mpe.

Fixes c1fb6816fb1b ("powerpc: Add relocation on exception vector handlers")
---
 arch/powerpc/kernel/exceptions-64s.S |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
arch/powerpc/kernel/exceptions-64s.S +11 -5
@@ -946,11 +946,6 @@ hv_facility_unavailable_relon_trampoline
 #endif
 	STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
 
-	/* Other future vectors */
-	.align	7
-	.globl	__end_interrupts
-__end_interrupts:
-
 	.align	7
 system_call_entry_direct:
 #if defined(CONFIG_RELOCATABLE)
@@ -1304,6 +1299,17 @@ __end_handlers:
 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
 	STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
 
+	/*
+	 * The __end_interrupts marker must be past the out-of-line (OOL)
+	 * handlers, so that they are copied to real address 0x100 when running
+	 * a relocatable kernel. This ensures they can be reached from the short
+	 * trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch
+	 * directly, without using LOAD_HANDLER().
+	 */
+	.align	7
+	.globl	__end_interrupts
+__end_interrupts:
+
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
  * Data area reserved for FWNMI option.
author maintainer
#15 lore raw

PATCH 13/23 xen/events: Dont move disabled irqs

In reply to Greg Kroah-Hartman

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

------------------

From: Ross Lagerwall <[email protected]>

commit f0f393877c71ad227d36705d61d1e4062bc29cf5 upstream.

Commit ff1e22e7a638 ("xen/events: Mask a moving irq") open-coded irq_move_irq() but left out checking if the IRQ is disabled. This broke resuming from suspend since it tries to move a (disabled) irq without holding the IRQ's desc->lock. Fix it by adding in a check for disabled IRQs.

The resulting stacktrace was:
kernel BUG at /build/linux-UbQGH5/linux-4.4.0/kernel/irq/migration.c:31! invalid opcode: 0000 [#1] SMP

Modules linked in: xenfs xen_privcmd ...
CPU: 0 PID: 9 Comm: migration/0 Not tainted 4.4.0-22-generic #39-Ubuntu
Hardware name: Xen HVM domU, BIOS 4.6.1-xs125180 05/04/2016
task: ffff88003d75ee00 ti: ffff88003d7bc000 task.ti: ffff88003d7bc000
RIP: 0010:[<ffffffff810e26e2>]  [<ffffffff810e26e2>] irq_move_masked_irq+0xd2/0xe0
RSP: 0018:ffff88003d7bfc50  EFLAGS: 00010046
RAX: 0000000000000000 RBX: ffff88003d40ba00 RCX: 0000000000000001
RDX: 0000000000000001 RSI: 0000000000000100 RDI: ffff88003d40bad8
RBP: ffff88003d7bfc68 R08: 0000000000000000 R09: ffff88003d000000
R10: 0000000000000000 R11: 000000000000023c R12: ffff88003d40bad0
R13: ffffffff81f3a4a0 R14: 0000000000000010 R15: 00000000ffffffff
FS:  0000000000000000(0000) GS:ffff88003da00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd4264de624 CR3: 0000000037922000 CR4: 00000000003406f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Stack:
 ffff88003d40ba38 0000000000000024 0000000000000000 ffff88003d7bfca0
 ffffffff814c8d92 00000010813ef89d 00000000805ea732 0000000000000009
 0000000000000024 ffff88003cc39b80 ffff88003d7bfce0 ffffffff814c8f66
Call Trace:
 [<ffffffff814c8d92>] eoi_pirq+0xb2/0xf0
 [<ffffffff814c8f66>] __startup_pirq+0xe6/0x150
 [<ffffffff814ca659>] xen_irq_resume+0x319/0x360
 [<ffffffff814c7e75>] xen_suspend+0xb5/0x180
 [<ffffffff81120155>] multi_cpu_stop+0xb5/0xe0
 [<ffffffff811200a0>] ? cpu_stop_queue_work+0x80/0x80
 [<ffffffff811203d0>] cpu_stopper_thread+0xb0/0x140
 [<ffffffff810a94e6>] ? finish_task_switch+0x76/0x220
 [<ffffffff810ca731>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20
 [<ffffffff810a3935>] smpboot_thread_fn+0x105/0x160
 [<ffffffff810a3830>] ? sort_range+0x30/0x30
 [<ffffffff810a0588>] kthread+0xd8/0xf0
 [<ffffffff810a04b0>] ? kthread_create_on_node+0x1e0/0x1e0
 [<ffffffff8182568f>] ret_from_fork+0x3f/0x70
 [<ffffffff810a04b0>] ? kthread_create_on_node+0x1e0/0x1e0
---
 drivers/xen/events/events_base.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/xen/events/events_base.c +4 -2
@@ -506,7 +506,8 @@ static void eoi_pirq(struct irq_data *da
 	if (!VALID_EVTCHN(evtchn))
 		return;
 
-	if (unlikely(irqd_is_setaffinity_pending(data))) {
+	if (unlikely(irqd_is_setaffinity_pending(data)) &&
+	    likely(!irqd_irq_disabled(data))) {
 		int masked = test_and_set_mask(evtchn);
 
 		clear_evtchn(evtchn);
@@ -1408,7 +1409,8 @@ static void ack_dynirq(struct irq_data *
 	if (!VALID_EVTCHN(evtchn))
 		return;
 
-	if (unlikely(irqd_is_setaffinity_pending(data))) {
+	if (unlikely(irqd_is_setaffinity_pending(data)) &&
+	    likely(!irqd_irq_disabled(data))) {
 		int masked = test_and_set_mask(evtchn);
 
 		clear_evtchn(evtchn);
author maintainer
#16 lore raw

PATCH 15/23 drm/gma500: Fix possible out of bounds read

In reply to Greg Kroah-Hartman

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

------------------

From: Itai Handler <[email protected]>

commit 7ccca1d5bf69fdd1d3c5fcf84faf1659a6e0ad11 upstream.

Fix possible out of bounds read, by adding missing comma. The code may read pass the end of the dsi_errors array when the most significant bit (bit #31) in the intr_stat register is set.
This bug has been detected using CppCheck (static analysis tool).

---
 drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c +1 -1
@@ -85,7 +85,7 @@ static const char *const dsi_errors[] =
 	"RX Prot Violation",
 	"HS Generic Write FIFO Full",
 	"LP Generic Write FIFO Full",
-	"Generic Read Data Avail"
+	"Generic Read Data Avail",
 	"Special Packet Sent",
 	"Tearing Effect",
 };
author maintainer
#17 lore raw

PATCH 16/23 drm/fb_helper: Fix references to dev->mode_config.num_connector

In reply to Greg Kroah-Hartman

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

------------------

From: Lyude <[email protected]>

commit 255f0e7c418ad95a4baeda017ae6182ba9b3c423 upstream.

During boot, MST hotplugs are generally expected (even if no physical hotplugging occurs) and result in DRM's connector topology changing. This means that using num_connector from the current mode configuration can lead to the number of connectors changing under us. This can lead to some nasty scenarios in fbcon:

- We allocate an array to the size of dev->mode_config.num_connectors.
- MST hotplug occurs, dev->mode_config.num_connectors gets incremented.
- We try to loop through each element in the array using the new value of dev->mode_config.num_connectors, and end up going out of bounds since dev->mode_config.num_connectors is now larger then the array we allocated.

fb_helper->connector_count however, will always remain consistent while we do a modeset in fb_helper.

Note: This is just polish for 4.7, Dave Airlie's drm_connector refcounting fixed these bugs for real. But it's good enough duct-tape for stable kernel backporting, since backporting the refcounting changes is way too invasive.

[danvet: Clarify why we need this. Also remove the now unused "dev" local variable to appease gcc.]

---
 drivers/gpu/drm/drm_fb_helper.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +2 -3
@@ -1347,7 +1347,6 @@ static int drm_pick_crtcs(struct drm_fb_
 			  int n, int width, int height)
 {
 	int c, o;
-	struct drm_device *dev = fb_helper->dev;
 	struct drm_connector *connector;
 	struct drm_connector_helper_funcs *connector_funcs;
 	struct drm_encoder *encoder;
@@ -1366,7 +1365,7 @@ static int drm_pick_crtcs(struct drm_fb_
 	if (modes[n] == NULL)
 		return best_score;
 
-	crtcs = kzalloc(dev->mode_config.num_connector *
+	crtcs = kzalloc(fb_helper->connector_count *
 			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
 	if (!crtcs)
 		return best_score;
@@ -1412,7 +1411,7 @@ static int drm_pick_crtcs(struct drm_fb_
 		if (score > best_score) {
 			best_score = score;
 			memcpy(best_crtcs, crtcs,
-			       dev->mode_config.num_connector *
+			       fb_helper->connector_count *
 			       sizeof(struct drm_fb_helper_crtc *));
 		}
 	}
author maintainer
#18 lore raw

PATCH 17/23 ext4: fix hang when processing corrupted orphaned inode list

In reply to Greg Kroah-Hartman

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

------------------

From: Theodore Ts'o <[email protected]>

commit c9eb13a9105e2e418f72e46a2b6da3f49e696902 upstream.

If the orphaned inode list contains inode #5, ext4_iget() returns a bad inode (since the bootloader inode should never be referenced directly). Because of the bad inode, we end up processing the inode repeatedly and this hangs the machine.

This can be reproduced via:

mke2fs -t ext4 /tmp/foo.img 100
debugfs -w -R "ssv last_orphan 5" /tmp/foo.img
mount -o loop /tmp/foo.img /mnt

(But don't do this if you are using an unpatched kernel if you care about the system staying functional. :-)

This bug was found by the port of American Fuzzy Lop into the kernel to find file system problems[1]. (Since it *only* happens if inode #5 shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not surprising that AFL needed two hours before it found it.)

[1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf

Reported by: Vegard Nossum <[email protected]>

---
 fs/ext4/ialloc.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
fs/ext4/ialloc.c +6 -4
@@ -1097,11 +1097,13 @@ struct inode *ext4_orphan_get(struct sup
 		goto iget_failed;
 
 	/*
-	 * If the orphans has i_nlinks > 0 then it should be able to be
-	 * truncated, otherwise it won't be removed from the orphan list
-	 * during processing and an infinite loop will result.
+	 * If the orphans has i_nlinks > 0 then it should be able to
+	 * be truncated, otherwise it won't be removed from the orphan
+	 * list during processing and an infinite loop will result.
+	 * Similarly, it must not be a bad inode.
 	 */
-	if (inode->i_nlink && !ext4_can_truncate(inode))
+	if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
+	    is_bad_inode(inode))
 		goto bad_orphan;
 
 	if (NEXT_ORPHAN(inode) > max_ino)
author maintainer
#19 lore raw

PATCH 18/23 ext4: address UBSAN warning in mb_find_order_for_block()

In reply to Greg Kroah-Hartman

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

------------------

From: Nicolai Stange <[email protected]>

commit b5cb316cdf3a3f5f6125412b0f6065185240cfdc upstream.

Currently, in mb_find_order_for_block(), there's a loop like the following:

  while (order <= e4b->bd_blkbits + 1) {
    ...
    bb += 1 << (e4b->bd_blkbits - order);
  }

Note that the updated bb is used in the loop's next iteration only.

However, at the last iteration, that is at order == e4b->bd_blkbits + 1, the shift count becomes negative (c.f. C99 6.5.7(3)) and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:1281:11
  shift exponent -1 is negative
  [...]
  Call Trace:
   [<ffffffff818c4d35>] dump_stack+0xbc/0x117
   [<ffffffff818c4c79>] ? _atomic_dec_and_lock+0x169/0x169
   [<ffffffff819411bb>] ubsan_epilogue+0xd/0x4e
   [<ffffffff81941cbc>] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [<ffffffff81941ac1>] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [<ffffffff816e93a0>] ? ext4_mb_generate_from_pa+0x590/0x590
   [<ffffffff816502c8>] ? ext4_read_block_bitmap_nowait+0x598/0xe80
   [<ffffffff816e7b7e>] mb_find_order_for_block+0x1ce/0x240
   [...]

Unless compilers start to do some fancy transformations (which at least GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the such calculated value of bb is never used again.

Silence UBSAN by introducing another variable, bb_incr, holding the next increment to apply to bb and adjust that one by right shifting it by one position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

---
 fs/ext4/mballoc.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/ext4/mballoc.c +3 -1
@@ -1236,6 +1236,7 @@ static void ext4_mb_unload_buddy(struct
 static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
 {
 	int order = 1;
+	int bb_incr = 1 << (e4b->bd_blkbits - 1);
 	void *bb;
 
 	BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
@@ -1248,7 +1249,8 @@ static int mb_find_order_for_block(struc
 			/* this block is part of buddy of order 'order' */
 			return order;
 		}
-		bb += 1 << (e4b->bd_blkbits - order);
+		bb += bb_incr;
+		bb_incr >>= 1;
 		order++;
 	}
 	return 0;
author maintainer
#20 lore raw

PATCH 19/23 ext4: silence UBSAN in ext4_mb_init()

In reply to Greg Kroah-Hartman

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

------------------

From: Nicolai Stange <[email protected]>

commit 935244cd54b86ca46e69bc6604d2adfb1aec2d42 upstream.

Currently, in ext4_mb_init(), there's a loop like the following:

  do {
    ...
    offset += 1 << (sb->s_blocksize_bits - i);
    i++;
  } while (i <= sb->s_blocksize_bits + 1);

Note that the updated offset is used in the loop's next iteration only.

However, at the last iteration, that is at i == sb->s_blocksize_bits + 1, the shift count becomes equal to (unsigned)-1 > 31 (c.f. C99 6.5.7(3)) and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:2621:15
  shift exponent 4294967295 is too large for 32-bit type 'int'
  [...]
  Call Trace:
   [<ffffffff818c4d25>] dump_stack+0xbc/0x117
   [<ffffffff818c4c69>] ? _atomic_dec_and_lock+0x169/0x169
   [<ffffffff819411ab>] ubsan_epilogue+0xd/0x4e
   [<ffffffff81941cac>] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [<ffffffff81941ab1>] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [<ffffffff814b6dc1>] ? kmem_cache_alloc+0x101/0x390
   [<ffffffff816fc13b>] ? ext4_mb_init+0x13b/0xfd0
   [<ffffffff814293c7>] ? create_cache+0x57/0x1f0
   [<ffffffff8142948a>] ? create_cache+0x11a/0x1f0
   [<ffffffff821c2168>] ? mutex_lock+0x38/0x60
   [<ffffffff821c23ab>] ? mutex_unlock+0x1b/0x50
   [<ffffffff814c26ab>] ? put_online_mems+0x5b/0xc0
   [<ffffffff81429677>] ? kmem_cache_create+0x117/0x2c0
   [<ffffffff816fcc49>] ext4_mb_init+0xc49/0xfd0
   [...]

Observe that the mentioned shift exponent, 4294967295, equals (unsigned)-1.

Unless compilers start to do some fancy transformations (which at least GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the such calculated value of offset is never used again.

Silence UBSAN by introducing another variable, offset_incr, holding the next increment to apply to offset and adjust that one by right shifting it by one position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

---
 fs/ext4/mballoc.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/mballoc.c +4 -2
@@ -2537,7 +2537,7 @@ int ext4_mb_init(struct super_block *sb)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	unsigned i, j;
-	unsigned offset;
+	unsigned offset, offset_incr;
 	unsigned max;
 	int ret;
 
@@ -2566,11 +2566,13 @@ int ext4_mb_init(struct super_block *sb)
 
 	i = 1;
 	offset = 0;
+	offset_incr = 1 << (sb->s_blocksize_bits - 1);
 	max = sb->s_blocksize << 2;
 	do {
 		sbi->s_mb_offsets[i] = offset;
 		sbi->s_mb_maxs[i] = max;
-		offset += 1 << (sb->s_blocksize_bits - i);
+		offset += offset_incr;
+		offset_incr = offset_incr >> 1;
 		max = max >> 1;
 		i++;
 	} while (i <= sb->s_blocksize_bits + 1);
author maintainer
#21 lore raw

PATCH 21/23 xfs: xfs_iflush_cluster fails to abort on error

In reply to Greg Kroah-Hartman

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

------------------

From: Dave Chinner <[email protected]>

commit b1438f477934f5a4d5a44df26f3079a7575d5946 upstream.

When a failure due to an inode buffer occurs, the error handling fails to abort the inode writeback correctly. This can result in the inode being reclaimed whilst still in the AIL, leading to use-after-free situations as well as filesystems that cannot be unmounted as the inode log items left in the AIL never get removed.

Fix this by ensuring fatal errors from xfs_imap_to_bp() result in the inode flush being aborted correctly.

---
 fs/xfs/xfs_inode.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
fs/xfs/xfs_inode.c +13 -4
@@ -3045,7 +3045,7 @@ xfs_iflush(
 	struct xfs_buf		**bpp)
 {
 	struct xfs_mount	*mp = ip->i_mount;
-	struct xfs_buf		*bp;
+	struct xfs_buf		*bp = NULL;
 	struct xfs_dinode	*dip;
 	int			error;
 
@@ -3087,14 +3087,22 @@ xfs_iflush(
 	}
 
 	/*
-	 * Get the buffer containing the on-disk inode.
+	 * Get the buffer containing the on-disk inode. We are doing a try-lock
+	 * operation here, so we may get  an EAGAIN error. In that case, we
+	 * simply want to return with the inode still dirty.
+	 *
+	 * If we get any other error, we effectively have a corruption situation
+	 * and we cannot flush the inode, so we treat it the same as failing
+	 * xfs_iflush_int().
 	 */
 	error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
 			       0);
-	if (error || !bp) {
+	if (error == -EAGAIN) {
 		xfs_ifunlock(ip);
 		return error;
 	}
+	if (error)
+		goto corrupt_out;
 
 	/*
 	 * First flush out the inode that xfs_iflush was called with.
@@ -3122,7 +3130,8 @@ xfs_iflush(
 	return 0;
 
 corrupt_out:
-	xfs_buf_relse(bp);
+	if (bp)
+		xfs_buf_relse(bp);
 	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
 cluster_corrupt_out:
 	error = XFS_ERROR(EFSCORRUPTED);
author maintainer
#22 lore raw

PATCH 22/23 xfs: fix inode validity check in xfs_iflush_cluster

In reply to Greg Kroah-Hartman

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

------------------

From: Dave Chinner <[email protected]>

commit 51b07f30a71c27405259a0248206ed4e22adbee2 upstream.

Some careless idiot(*) wrote crap code in commit 1a3e8f3 ("xfs:
convert inode cache lookups to use RCU locking") back in late 2010, and so xfs_iflush_cluster checks the wrong inode for whether it is still valid under RCU protection. Fix it to lock and check the correct inode.

(*) Careless-idiot: Dave Chinner <[email protected]>

---
 fs/xfs/xfs_inode.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
fs/xfs/xfs_inode.c +4 -4
@@ -2923,13 +2923,13 @@ xfs_iflush_cluster(
 		 * We need to check under the i_flags_lock for a valid inode
 		 * here. Skip it if it is not valid or the wrong inode.
 		 */
-		spin_lock(&ip->i_flags_lock);
-		if (!ip->i_ino ||
+		spin_lock(&iq->i_flags_lock);
+		if (!iq->i_ino ||
 		    (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
-			spin_unlock(&ip->i_flags_lock);
+			spin_unlock(&iq->i_flags_lock);
 			continue;
 		}
-		spin_unlock(&ip->i_flags_lock);
+		spin_unlock(&iq->i_flags_lock);
 
 		/*
 		 * Do an un-protected check to see if the inode is dirty and
author maintainer
#23 lore raw

PATCH 23/23 xfs: skip stale inodes in xfs_iflush_cluster

In reply to Greg Kroah-Hartman

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

------------------

From: Dave Chinner <[email protected]>

commit 7d3aa7fe970791f1a674b14572a411accf2f4d4e upstream.

We don't write back stale inodes so we should skip them in xfs_iflush_cluster, too.

---
 fs/xfs/xfs_inode.c |    1 +
 1 file changed, 1 insertion(+)
fs/xfs/xfs_inode.c +1 -0
@@ -2925,6 +2925,7 @@ xfs_iflush_cluster(
 		 */
 		spin_lock(&iq->i_flags_lock);
 		if (!iq->i_ino ||
+		    __xfs_iflags_test(iq, XFS_ISTALE) ||
 		    (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
 			spin_unlock(&iq->i_flags_lock);
 			continue;
#24 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.14.72 release. There are 23 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 Tue Jun 7 21:38:01 UTC 2016. Anything received after that time might be too late.

Quoted 7 lines

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.72-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah

author maintainer
#25 lore raw
Quoted 13 lines · Shuah Khan
Quoted 12 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.14.72 release. There are 23 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 Tue Jun 7 21:38:01 UTC 2016. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.72-rc1.gz

and the diffstat can be found below.

Quoted 5 lines
Quoted 3 lines

thanks,

greg k-h

Compiled and booted on my test system. No dmesg regressions.

Thanks for testing all of these and letting me know.

greg k-h

#26 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.14.72 release. There are 23 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 Tue Jun 7 21:38:01 UTC 2016. Anything received after that time might be too late.

Build results:

	total: 131 pass: 131 fail: 0
Qemu test results:
	total: 89 pass: 89 fail: 0

Details are available at http://kerneltests.org/builders.

Guenter