Skip to contentSkip to conversation

3.12.74-stable review

PATCH In review Jiri Slaby 4 participants 93 messages May 4, 2017 – May 9, 2017

Subsystems (3)
lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

cover 3.12.74-stable review

This is the start of the stable review cycle for the 3.12.74 release. There are 86 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 May 8 11:03:52 CEST 2017. 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.74-rc1.xz

and the diffstat can be found below.

thanks,
js

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

Al Viro (1):
p9_client_readdir() fix

Andrey Konovalov (3):
net/packet: fix overflow in check for priv area size net/packet: fix overflow in check for tp_frame_nr net/packet: fix overflow in check for tp_reserve

Arnd Bergmann (5):
dvb-usb-v2: avoid use-after-free
ACPI / power: Avoid maybe-uninitialized warning
tty: nozomi: avoid a harmless gcc warning
hostap: avoid uninitialized variable use in hfa384x_get_rid
gfs2: avoid uninitialized variable warning

Ben Hutchings (4):
pegasus: Use heap buffers for all register access
rtl8150: Use heap buffers for all register access
catc: Combine failure cleanup code in catc_probe()
catc: Use heap buffer for memory size test

Benjamin Herrenschmidt (1):
powerpc: Disable HFSCR[TM] if TM is not supported

Cameron Gutman (1):
Input: xpad - add support for Razer Wildcat gamepad

Chris Salls (1):
mm/mempolicy.c: fix error handling in set_mempolicy and mbind.

Chun-Yi Lee (1):
platform/x86: acer-wmi: setup accelerometer when machine has
appropriate notify event

Corey Minyard (1):
MIPS: Fix crash registers on non-crashing CPUs

Daeho Jeong (1):
ext4: fix inode checksum calculation problem if i_extra_size is small

Dan Williams (1):
block: fix del_gendisk() vs blkdev_ioctl crash

David Howells (2):
KEYS: Disallow keyrings beginning with '.' to be joined as session
keyrings
KEYS: Change the name of the dead type to ".dead" to prevent user
access

Dmitry Torokhov (1):
Input: i8042 - add Clevo P650RS to the i8042 reset list

Eric Biggers (1):
KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings

Eric Dumazet (2):
ping: implement proper locking
net: neigh: guard against NULL solicit() method

Eugenia Emantayev (1):
net/mlx4_en: Fix bad WQE issue

Florian Larysch (1):
net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given

Geert Uytterhoeven (1):
char: Drop bogus dependency of DEVPORT on !M68K

Germano Percossi (1):
CIFS: remove bad_network_name flag

Guenter Roeck (1):
usb: hub: Wait for connection to be reestablished after port reset

Guillaume Nault (1):
l2tp: take reference on sessions being dumped

Hongxu Jia (1):
netfilter: arp_tables: fix invoking 32bit "iptable -P INPUT ACCEPT"
failed in 64bit kernel

J. Bruce Fields (1):
nfsd: check for oversized NFSv2/v3 arguments

Jack Morgenstein (1):
net/mlx4_core: Fix racy CQ (Completion Queue) free

James Hogan (8):
metag/usercopy: Drop unused macros metag/usercopy: Fix alignment error checking metag/usercopy: Add early abort to copy_to_user metag/usercopy: Zero rest of buffer from copy_from_user metag/usercopy: Set flags before ADDZ metag/usercopy: Fix src fixup in from user rapf loops metag/usercopy: Add missing fixups
MIPS: KGDB: Use kernel context for sleeping threads

Jamie Bainbridge (1):
ipv6: check raw payload size correctly in ioctl

Jan-Marek Glogowski (1):
Reset TreeId to zero on SMB2 TREE_CONNECT

Janusz Dziedzic (1):
usb: dwc3: gadget: delay unmap of bounced requests

Josh Poimboeuf (1):
ftrace/x86: Fix triple fault with graph tracing and suspend-to-ram

Juergen Gross (1):
xen, fbfront: fix connecting to backend

Kees Cook (1):
mm: Tighten x86 /dev/mem with zeroing reads

Li Qiang (1):
drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl()

Mantas M (1):
net: ipv6: check route protocol when deleting routes

Marcelo Henrique Cerri (1):
s390/decompressor: fix initrd corruption caused by bss clear

Martin K. Petersen (2):
scsi: sr: Sanity check returned mode data
scsi: sd: Fix capacity calculation with 32-bit sector_t

Max Bires (1):
char: lack of bool string made CONFIG_DEVPORT always on

Michael Ellerman (1):
powerpc: Reject binutils 2.24 when building little endian

Minchan Kim (1):
zram: do not use copy_page with non-page aligned address

Murray McAllister (2):
drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl() drm/vmwgfx: avoid calling vzalloc with a 0 size in

    vmw_get_cap_3d_ioctl()

Nathan Sullivan (1):
net: phy: handle state correctly in phy_stop_machine

Nicholas Bellinger (2):
iscsi-target: Fix TMR reference leak during session shutdown
iscsi-target: Drop work-around for legacy GlobalSAN initiator

Nikolay Aleksandrov (1):
ip6mr: fix notification device destruction

Omar Sandoval (1):
virtio-console: avoid DMA from stack

Paul Mackerras (1):
powerpc: Don't try to fix up misaligned load-with-reservation
instructions

Peter Zijlstra (1):
perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32()

Rafał Miłecki (1):
mtd: bcm47xxpart: fix parsing first block after aligned TRX

Sachin Prabhu (1):
cifs: Do not send echoes before Negotiate is complete

Sebastian Siewior (1):
ubi/upd: Always flush after prepared for an update

Stefano Stabellini (1):
xen/x86: don't lose event interrupts

Steven Rostedt (VMware) (2):
tracing: Allocate the snapshot buffer before enabling probe
ring-buffer: Have ring_buffer_iter_empty() return true when empty

Suzuki K Poulose (1):
kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd

Takashi Iwai (1):
ALSA: seq: Don't break snd_use_lock_sync() loop by timeout

Theodore Ts'o (1):
ext4: check if in-inode xattr is corrupted in
ext4_expand_extra_isize_ea()

Thomas Gleixner (1):
x86/vdso: Plug race between mapping and ELF header setup

Thomas Hellstrom (1):
drm/vmwgfx: Remove getparam error message

Thorsten Leemhuis (1):
Input: elantech - add Fujitsu Lifebook E547 to force crc_enabled

Vitaly Kuznetsov (2):
Drivers: hv: don't leak memory in vmbus_establish_gpadl()
Drivers: hv: get rid of timeout in vmbus_open()

Wei Fang (1):
md:raid1: fix a dead loop when read from a WriteMostly disk

Wei Yongjun (1):
ring-buffer: Fix return value check in test_ringbuffer()

Xin Long (1):
sctp: listen on the sock only when it's state is listening or closed

Yazen Ghannam (1):
x86/mce/AMD: Give a name to MCA bank 3 when accessed with legacy MSRs

[email protected] (1):
ptrace: fix PTRACE_LISTEN race corrupting task->state

[email protected] (1):
RDS: Fix the atomicity for congestion map update

 arch/arm/kvm/mmu.c                             |  12 +
 arch/metag/include/asm/uaccess.h               |  15 +-
 arch/metag/lib/usercopy.c                      | 312 ++++++++++---------------
 arch/mips/kernel/crash.c                       |  16 +-
 arch/mips/kernel/kgdb.c                        |  48 ++--
 arch/powerpc/Makefile                          |   8 +
 arch/powerpc/kernel/align.c                    |  28 ++-
 arch/powerpc/kernel/setup_64.c                 |   9 +
 arch/s390/boot/compressed/misc.c               |  35 +--
 arch/x86/include/asm/elf.h                     |   2 +-
 arch/x86/kernel/cpu/mcheck/mce_amd.c           |   2 +-
 arch/x86/kernel/cpu/perf_event_intel_lbr.c     |   2 +
 arch/x86/kernel/ftrace.c                       |  12 +
 arch/x86/mm/init.c                             |  41 +++-
 arch/x86/xen/time.c                            |   6 +-
 block/genhd.c                                  |   1 -
 drivers/acpi/power.c                           |   1 +
 drivers/char/Kconfig                           |   6 +-
 drivers/char/mem.c                             |  82 ++++---
 drivers/char/virtio_console.c                  |  12 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c          |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c        |   9 +-
 drivers/hv/channel.c                           |  17 +-
 drivers/input/joystick/xpad.c                  |   2 +
 drivers/input/mouse/elantech.c                 |   8 +
 drivers/input/serio/i8042-x86ia64io.h          |   7 +
 drivers/md/raid1.c                             |   2 +-
 drivers/media/usb/dvb-usb-v2/dvb_usb_core.c    |   9 +-
 drivers/mtd/bcm47xxpart.c                      |  10 +-
 drivers/mtd/ubi/upd.c                          |   8 +-
 drivers/net/ethernet/mellanox/mlx4/cq.c        |  38 +--
 drivers/net/ethernet/mellanox/mlx4/en_rx.c     |   8 +-
 drivers/net/phy/phy.c                          |   2 +-
 drivers/net/usb/catc.c                         |  56 +++--
 drivers/net/usb/pegasus.c                      |  29 ++-
 drivers/net/usb/rtl8150.c                      |  34 ++-
 drivers/net/wireless/hostap/hostap_hw.c        |  15 +-
 drivers/platform/x86/acer-wmi.c                |  22 +-
 drivers/scsi/sd.c                              |  20 +-
 drivers/scsi/sr.c                              |   6 +-
 drivers/staging/zram/zram_drv.c                |   6 +-
 drivers/target/iscsi/iscsi_target_parameters.c |  16 --
 drivers/target/iscsi/iscsi_target_util.c       |  12 +-
 drivers/tty/nozomi.c                           |   2 +-
 drivers/usb/core/hub.c                         |  11 +-
 drivers/usb/dwc3/gadget.c                      |  21 +-
 drivers/video/xen-fbfront.c                    |   4 +-
 fs/cifs/cifsglob.h                             |   1 -
 fs/cifs/smb1ops.c                              |  10 +
 fs/cifs/smb2pdu.c                              |   9 +-
 fs/ext4/inode.c                                |   5 +-
 fs/ext4/xattr.c                                |  32 ++-
 fs/gfs2/dir.c                                  |   4 +-
 fs/nfsd/nfssvc.c                               |  36 +++
 kernel/ptrace.c                                |  14 +-
 kernel/trace/ring_buffer.c                     |  24 +-
 kernel/trace/trace.c                           |   8 +-
 mm/mempolicy.c                                 |  20 +-
 net/9p/client.c                                |   4 +
 net/core/neighbour.c                           |   3 +-
 net/ipv4/netfilter/arp_tables.c                |   4 +-
 net/ipv4/ping.c                                |   5 +-
 net/ipv4/route.c                               |   2 +-
 net/ipv6/ip6mr.c                               |  13 +-
 net/ipv6/raw.c                                 |   3 +-
 net/ipv6/route.c                               |   2 +
 net/l2tp/l2tp_core.c                           |   8 +-
 net/l2tp/l2tp_core.h                           |   3 +-
 net/l2tp/l2tp_debugfs.c                        |  10 +-
 net/l2tp/l2tp_netlink.c                        |   7 +-
 net/l2tp/l2tp_ppp.c                            |  10 +-
 net/packet/af_packet.c                         |   8 +-
 net/rds/cong.c                                 |   4 +-
 net/sctp/socket.c                              |   3 +
 security/keys/gc.c                             |   2 +-
 security/keys/keyctl.c                         |  20 +-
 security/keys/process_keys.c                   |  44 ++--
 sound/core/seq/seq_lock.c                      |   9 +-
 78 files changed, 833 insertions(+), 522 deletions(-)
Signature · 1 line
2.12.2
author
#1 lore raw

PATCH 1/86 drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl()

From: Murray McAllister <[email protected]>

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

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

commit 36274ab8c596f1240c606bb514da329add2a1bcd upstream.

Before memory allocations vmw_surface_define_ioctl() checks the upper-bounds of a user-supplied size, but does not check if the supplied size is 0.

Add check to avoid NULL pointer dereferences.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +2 -2
index 582814339748..a518493836a0 100644
@@ -680,8 +680,8 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
 		num_sizes += req->mip_levels[i];
 
-	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES *
-	    DRM_VMW_MAX_MIP_LEVELS)
+	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
+	    num_sizes == 0)
 		return -EINVAL;
 
 	size = vmw_user_surface_size + 128 +
Signature · 1 line
2.12.2
author
#2 lore raw

PATCH 2/86 drm/vmwgfx: avoid calling vzalloc with a 0 size in vmw_get_cap_3d_ioctl()

From: Murray McAllister <[email protected]>

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

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

commit 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 upstream.

In vmw_get_cap_3d_ioctl(), a user can supply 0 for a size that is used in vzalloc(). This eventually calls dump_stack() (in warn_alloc()), which can leak useful addresses to dmesg.

Add check to avoid a size of 0.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +1 -1
index c509d40c4897..f435b6c187f0 100644
@@ -90,7 +90,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
 	void *bounce;
 	int ret;
 
-	if (unlikely(arg->pad64 != 0)) {
+	if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) {
 		DRM_ERROR("Illegal GET_3D_CAP argument.\n");
 		return -EINVAL;
 	}
Signature · 1 line
2.12.2
author
#3 lore raw

PATCH 3/86 drm/vmwgfx: Remove getparam error message

In reply to Jiri Slaby

From: Thomas Hellstrom <[email protected]>

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

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

commit 53e16798b0864464c5444a204e1bb93ae246c429 upstream.

The mesa winsys sometimes uses unimplemented parameter requests to check for features. Remove the error message to avoid bloating the kernel log.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 2 --
 1 file changed, 2 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +0 -2
index f435b6c187f0..17a503ff260f 100644
@@ -69,8 +69,6 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
 		break;
 	}
 	default:
-		DRM_ERROR("Illegal vmwgfx get param request: %d\n",
-			  param->param);
 		return -EINVAL;
 	}
 
Signature · 1 line
2.12.2
author
#4 lore raw

PATCH 4/86 drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl()

In reply to Jiri Slaby

From: Li Qiang <[email protected]>

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

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

commit e7e11f99564222d82f0ce84bd521e57d78a6b678 upstream.

In vmw_surface_define_ioctl(), the 'num_sizes' is the sum of the 'req->mip_levels' array. This array can be assigned any value from the user space. As both the 'num_sizes' and the array is uint32_t, it is easy to make 'num_sizes' overflow. The later 'mip_levels' is used as the loop count. This can lead an oob write. Add the check of 'req->mip_levels' to avoid this.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +4 -1
index a518493836a0..12969378c06e 100644
@@ -677,8 +677,11 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
 			128;
 
 	num_sizes = 0;
-	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
+	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
+		if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
+			return -EINVAL;
 		num_sizes += req->mip_levels[i];
+	}
 
 	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
 	    num_sizes == 0)
Signature · 1 line
2.12.2
author
#5 lore raw

PATCH 5/86 Reset TreeId to zero on SMB2 TREE_CONNECT

In reply to Jiri Slaby

From: Jan-Marek Glogowski <[email protected]>

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

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

commit 806a28efe9b78ffae5e2757e1ee924b8e50c08ab upstream.

Currently the cifs module breaks the CIFS specs on reconnect as described in http://msdn.microsoft.com/en-us/library/cc246529.aspx:

"TreeId (4 bytes): Uniquely identifies the tree connect for the command. This MUST be 0 for the SMB2 TREE_CONNECT Request."

---
 fs/cifs/smb2pdu.c | 4 ++++
 1 file changed, 4 insertions(+)
fs/cifs/smb2pdu.c +4 -0
index 30d0751626e3..c7a400415d02 100644
@@ -853,6 +853,10 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
 		return -EINVAL;
 	}
 
+	/* SMB2 TREE_CONNECT request must be called with TreeId == 0 */
+	if (tcon)
+		tcon->tid = 0;
+
 	rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req);
 	if (rc) {
 		kfree(unc_path);
Signature · 1 line
2.12.2
author
#6 lore raw

PATCH 6/86 ptrace: fix PTRACE_LISTEN race corrupting task->state

In reply to Jiri Slaby

From: "[email protected]" <[email protected]>

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

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

commit 5402e97af667e35e54177af8f6575518bf251d51 upstream.

In PT_SEIZED + LISTEN mode STOP/CONT signals cause a wakeup against __TASK_TRACED. If this races with the ptrace_unfreeze_traced at the end of a PTRACE_LISTEN, this can wake the task /after/ the check against __TASK_TRACED, but before the reset of state to TASK_TRACED. This causes it to instead clobber TASK_WAKING, allowing a subsequent wakeup against TRACED while the task is still on the rq wake_list, corrupting it.

Oleg said:
"The kernel can crash or this can lead to other hard-to-debug problems.
In short, "task->state = TASK_TRACED" in ptrace_unfreeze_traced() assumes that nobody else can wake it up, but PTRACE_LISTEN breaks the contract. Obviusly it is very wrong to manipulate task->state if this task is already running, or WAKING, or it sleeps again"

[[email protected]: coding-style fixes]
Fixes 9899d11f ("ptrace: ensure arch_ptrace/ptrace_request can never race with SIGKILL")
---
 kernel/ptrace.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
kernel/ptrace.c +10 -4
index 4524314ecbb4..3e3d7841179b 100644
@@ -150,11 +150,17 @@ static void ptrace_unfreeze_traced(struct task_struct *task)
 
 	WARN_ON(!task->ptrace || task->parent != current);
 
+	/*
+	 * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely.
+	 * Recheck state under the lock to close this race.
+	 */
 	spin_lock_irq(&task->sighand->siglock);
-	if (__fatal_signal_pending(task))
-		wake_up_state(task, __TASK_TRACED);
-	else
-		task->state = TASK_TRACED;
+	if (task->state == __TASK_TRACED) {
+		if (__fatal_signal_pending(task))
+			wake_up_state(task, __TASK_TRACED);
+		else
+			task->state = TASK_TRACED;
+	}
 	spin_unlock_irq(&task->sighand->siglock);
 }
 
Signature · 1 line
2.12.2
author
#7 lore raw

PATCH 7/86 ring-buffer: Fix return value check in test_ringbuffer()

In reply to Jiri Slaby

From: Wei Yongjun <[email protected]>

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

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

commit 62277de758b155dc04b78f195a1cb5208c37b2df upstream.

In case of error, the function kthread_run() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().

Fixes 6c43e554a ("ring-buffer: Add ring buffer startup selftest")
---
 kernel/trace/ring_buffer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/trace/ring_buffer.c +4 -4
index f100767c8e0b..579821bd2484 100644
@@ -4823,9 +4823,9 @@ static __init int test_ringbuffer(void)
 		rb_data[cpu].cnt = cpu;
 		rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu],
 						 "rbtester/%d", cpu);
-		if (WARN_ON(!rb_threads[cpu])) {
+		if (WARN_ON(IS_ERR(rb_threads[cpu]))) {
 			pr_cont("FAILED\n");
-			ret = -1;
+			ret = PTR_ERR(rb_threads[cpu]);
 			goto out_free;
 		}
 
@@ -4835,9 +4835,9 @@ static __init int test_ringbuffer(void)
 
 	/* Now create the rb hammer! */
 	rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer");
-	if (WARN_ON(!rb_hammer)) {
+	if (WARN_ON(IS_ERR(rb_hammer))) {
 		pr_cont("FAILED\n");
-		ret = -1;
+		ret = PTR_ERR(rb_hammer);
 		goto out_free;
 	}
 
Signature · 1 line
2.12.2
author
#8 lore raw

PATCH 8/86 metag/usercopy: Drop unused macros

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit ef62a2d81f73d9cddef14bc3d9097a57010d551c upstream.

Metag's lib/usercopy.c has a bunch of copy_from_user macros for larger copies between 5 and 16 bytes which are completely unused. Before fixing zeroing lets drop these macros so there is less to fix.

---
 arch/metag/lib/usercopy.c | 113 ----------------------------------------------
 1 file changed, 113 deletions(-)
arch/metag/lib/usercopy.c +0 -113
index b3ebfe9c8e88..b4eb1f17069f 100644
@@ -651,119 +651,6 @@ EXPORT_SYMBOL(__copy_user);
 #define __asm_copy_from_user_4(to, from, ret) \
 	__asm_copy_from_user_4x_cont(to, from, ret, "", "", "")
 
-#define __asm_copy_from_user_5(to, from, ret) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"4:	SETB [%0++],D1Ar1\n",		\
-		"5:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 4b,5b\n")
-
-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"4:	SETW [%0++],D1Ar1\n" COPY,	\
-		"5:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 4b,5b\n" TENTRY)
-
-#define __asm_copy_from_user_6(to, from, ret) \
-	__asm_copy_from_user_6x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_7(to, from, ret) \
-	__asm_copy_from_user_6x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"6:	SETB [%0++],D1Ar1\n",		\
-		"7:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 6b,7b\n")
-
-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"4:	SETD [%0++],D1Ar1\n" COPY,	\
-		"5:	ADD  %2,%2,#4\n"			\
-		"	SETD [%0++],D1Ar1\n" FIXUP,		\
-		"	.long 4b,5b\n" TENTRY)
-
-#define __asm_copy_from_user_8(to, from, ret) \
-	__asm_copy_from_user_8x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_9(to, from, ret) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"6:	SETB [%0++],D1Ar1\n",		\
-		"7:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 6b,7b\n")
-
-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"6:	SETW [%0++],D1Ar1\n" COPY,	\
-		"7:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 6b,7b\n" TENTRY)
-
-#define __asm_copy_from_user_10(to, from, ret) \
-	__asm_copy_from_user_10x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_11(to, from, ret)		\
-	__asm_copy_from_user_10x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"8:	SETB [%0++],D1Ar1\n",		\
-		"9:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 8b,9b\n")
-
-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"6:	SETD [%0++],D1Ar1\n" COPY,	\
-		"7:	ADD  %2,%2,#4\n"		\
-		"	SETD [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 6b,7b\n" TENTRY)
-
-#define __asm_copy_from_user_12(to, from, ret) \
-	__asm_copy_from_user_12x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_13(to, from, ret) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"8:	SETB [%0++],D1Ar1\n",		\
-		"9:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 8b,9b\n")
-
-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETW D1Ar1,[%1++]\n"		\
-		"8:	SETW [%0++],D1Ar1\n" COPY,	\
-		"9:	ADD  %2,%2,#2\n"		\
-		"	SETW [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 8b,9b\n" TENTRY)
-
-#define __asm_copy_from_user_14(to, from, ret) \
-	__asm_copy_from_user_14x_cont(to, from, ret, "", "", "")
-
-#define __asm_copy_from_user_15(to, from, ret) \
-	__asm_copy_from_user_14x_cont(to, from, ret,	\
-		"	GETB D1Ar1,[%1++]\n"		\
-		"10:	SETB [%0++],D1Ar1\n",		\
-		"11:	ADD  %2,%2,#1\n"		\
-		"	SETB [%0++],D1Ar1\n",		\
-		"	.long 10b,11b\n")
-
-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
-	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	GETD D1Ar1,[%1++]\n"		\
-		"8:	SETD [%0++],D1Ar1\n" COPY,	\
-		"9:	ADD  %2,%2,#4\n"		\
-		"	SETD [%0++],D1Ar1\n" FIXUP,	\
-		"	.long 8b,9b\n" TENTRY)
-
-#define __asm_copy_from_user_16(to, from, ret) \
-	__asm_copy_from_user_16x_cont(to, from, ret, "", "", "")
 
 #define __asm_copy_from_user_8x64(to, from, ret) \
 	asm volatile (				\
Signature · 1 line
2.12.2
author
#9 lore raw

PATCH 9/86 metag/usercopy: Fix alignment error checking

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit 2257211942bbbf6c798ab70b487d7e62f7835a1a upstream.

Fix the error checking of the alignment adjustment code in raw_copy_from_user(), which mistakenly considers it safe to skip the error check when aligning the source buffer on a 2 or 4 byte boundary.

If the destination buffer was unaligned it may have started to copy using byte or word accesses, which could well be at the start of a new (valid) source page. This would result in it appearing to have copied 1 or 2 bytes at the end of the first (invalid) page rather than none at all.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/lib/usercopy.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
arch/metag/lib/usercopy.c +4 -6
index b4eb1f17069f..a6ced9691ddb 100644
@@ -717,6 +717,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
 	if ((unsigned long) src & 1) {
 		__asm_copy_from_user_1(dst, src, retn);
 		n--;
+		if (retn)
+			goto copy_exception_bytes;
 	}
 	if ((unsigned long) dst & 1) {
 		/* Worst case - byte copy */
@@ -730,6 +732,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
 	if (((unsigned long) src & 2) && n >= 2) {
 		__asm_copy_from_user_2(dst, src, retn);
 		n -= 2;
+		if (retn)
+			goto copy_exception_bytes;
 	}
 	if ((unsigned long) dst & 2) {
 		/* Second worst case - word copy */
@@ -741,12 +745,6 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
 		}
 	}
 
-	/* We only need one check after the unalignment-adjustments,
-	   because if both adjustments were done, either both or
-	   neither reference had an exception.  */
-	if (retn != 0)
-		goto copy_exception_bytes;
-
 #ifdef USE_RAPF
 	/* 64 bit copy loop */
 	if (!(((unsigned long) src | (unsigned long) dst) & 7)) {
Signature · 1 line
2.12.2
author
#10 lore raw

PATCH 10/86 metag/usercopy: Add early abort to copy_to_user

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b upstream.

When copying to userland on Meta, if any faults are encountered immediately abort the copy instead of continuing on and repeatedly faulting, and worse potentially copying further bytes successfully to subsequent valid pages.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/lib/usercopy.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/metag/lib/usercopy.c +20 -0
index a6ced9691ddb..714d8562aa20 100644
@@ -538,23 +538,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
 	if ((unsigned long) src & 1) {
 		__asm_copy_to_user_1(dst, src, retn);
 		n--;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 1) {
 		/* Worst case - byte copy */
 		while (n > 0) {
 			__asm_copy_to_user_1(dst, src, retn);
 			n--;
+			if (retn)
+				return retn + n;
 		}
 	}
 	if (((unsigned long) src & 2) && n >= 2) {
 		__asm_copy_to_user_2(dst, src, retn);
 		n -= 2;
+		if (retn)
+			return retn + n;
 	}
 	if ((unsigned long) dst & 2) {
 		/* Second worst case - word copy */
 		while (n >= 2) {
 			__asm_copy_to_user_2(dst, src, retn);
 			n -= 2;
+			if (retn)
+				return retn + n;
 		}
 	}
 
@@ -569,6 +577,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
 		while (n >= 8) {
 			__asm_copy_to_user_8x64(dst, src, retn);
 			n -= 8;
+			if (retn)
+				return retn + n;
 		}
 	}
 	if (n >= RAPF_MIN_BUF_SIZE) {
@@ -581,6 +591,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
 		while (n >= 8) {
 			__asm_copy_to_user_8x64(dst, src, retn);
 			n -= 8;
+			if (retn)
+				return retn + n;
 		}
 	}
 #endif
@@ -588,11 +600,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
 	while (n >= 16) {
 		__asm_copy_to_user_16(dst, src, retn);
 		n -= 16;
+		if (retn)
+			return retn + n;
 	}
 
 	while (n >= 4) {
 		__asm_copy_to_user_4(dst, src, retn);
 		n -= 4;
+		if (retn)
+			return retn + n;
 	}
 
 	switch (n) {
@@ -609,6 +625,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
 		break;
 	}
 
+	/*
+	 * If we get here, retn correctly reflects the number of failing
+	 * bytes.
+	 */
 	return retn;
 }
 EXPORT_SYMBOL(__copy_user);
Signature · 1 line
2.12.2
author
#11 lore raw

PATCH 11/86 metag/usercopy: Zero rest of buffer from copy_from_user

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit 563ddc1076109f2b3f88e6d355eab7b6fd4662cb upstream.

Currently we try to zero the destination for a failed read from userland in fixup code in the usercopy.c macros. The rest of the destination buffer is then zeroed from __copy_user_zeroing(), which is used for both copy_from_user() and __copy_from_user().

Unfortunately we fail to zero in the fixup code as D1Ar1 is set to 0 before the fixup code entry labels, and __copy_from_user() shouldn't even be zeroing the rest of the buffer.

Move the zeroing out into copy_from_user() and rename __copy_user_zeroing() to raw_copy_from_user() since it no longer does any zeroing. This also conveniently matches the name needed for RAW_COPY_USER support in a later patch.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/include/asm/uaccess.h | 15 ++++++-----
 arch/metag/lib/usercopy.c        | 57 +++++++++++++---------------------------
 2 files changed, 26 insertions(+), 46 deletions(-)
arch/metag/include/asm/uaccess.h +8 -7
index 7841f2290385..9d523375f68a 100644
@@ -192,20 +192,21 @@ extern long __must_check strnlen_user(const char __user *src, long count);
 
 #define strlen_user(str) strnlen_user(str, 32767)
 
-extern unsigned long __must_check __copy_user_zeroing(void *to,
-						      const void __user *from,
-						      unsigned long n);
+extern unsigned long raw_copy_from_user(void *to, const void __user *from,
+					unsigned long n);
 
 static inline unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+	unsigned long res = n;
 	if (likely(access_ok(VERIFY_READ, from, n)))
-		return __copy_user_zeroing(to, from, n);
-	memset(to, 0, n);
-	return n;
+		res = raw_copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n)
+#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n)
 #define __copy_from_user_inatomic __copy_from_user
 
 extern unsigned long __must_check __copy_user(void __user *to,
arch/metag/lib/usercopy.c +18 -39

154 lines not on this page · raw message

Signature · 1 line
2.12.2
author
#12 lore raw

PATCH 12/86 metag/usercopy: Set flags before ADDZ

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 upstream.

The fixup code for the copy_to_user rapf loops reads TXStatus.LSM_STEP to decide how far to rewind the source pointer. There is a special case for the last execution of an MGETL/MGETD, since it leaves LSM_STEP=0 even though the number of MGETLs/MGETDs attempted was 4. This uses ADDZ which is conditional upon the Z condition flag, but the AND instruction which masked the TXStatus.LSM_STEP field didn't set the condition flags based on the result.

Fix that now by using ANDS which does set the flags, and also marking the condition codes as clobbered by the inline assembly.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/lib/usercopy.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/metag/lib/usercopy.c +4 -4
index e1d553872fd7..4422928a1746 100644
@@ -315,7 +315,7 @@
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
-		: "D1Ar1", "D0Ar2", "memory")
+		: "D1Ar1", "D0Ar2", "cc", "memory")
 
 /*	rewind 'to' and 'from'  pointers when a fault occurs
  *
@@ -341,7 +341,7 @@
 #define __asm_copy_to_user_64bit_rapf_loop(to,	from, ret, n, id)\
 	__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id,		\
 		"LSR	D0Ar2, D0Ar2, #8\n"				\
-		"AND	D0Ar2, D0Ar2, #0x7\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x7\n"				\
 		"ADDZ	D0Ar2, D0Ar2, #4\n"				\
 		"SUB	D0Ar2, D0Ar2, #1\n"				\
 		"MOV	D1Ar1, #4\n"					\
@@ -486,7 +486,7 @@
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
-		: "D1Ar1", "D0Ar2", "memory")
+		: "D1Ar1", "D0Ar2", "cc", "memory")
 
 /*	rewind 'to' and 'from'  pointers when a fault occurs
  *
@@ -512,7 +512,7 @@
 #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\
 	__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id,		\
 		"LSR	D0Ar2, D0Ar2, #8\n"				\
-		"AND	D0Ar2, D0Ar2, #0x7\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x7\n"				\
 		"ADDZ	D0Ar2, D0Ar2, #4\n"				\
 		"SUB	D0Ar2, D0Ar2, #1\n"				\
 		"MOV	D1Ar1, #4\n"					\
Signature · 1 line
2.12.2
author
#13 lore raw

PATCH 13/86 metag/usercopy: Fix src fixup in from user rapf loops

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 upstream.

The fixup code to rewind the source pointer in __asm_copy_from_user_{32,64}bit_rapf_loop() always rewound the source by a single unit (4 or 8 bytes), however this is insufficient if the fault didn't occur on the first load in the loop, as the source pointer will have been incremented but nothing will have been stored until all 4 register [pairs] are loaded.

Read the LSM_STEP field of TXSTATUS (which is already loaded into a register), a bit like the copy_to_user versions, to determine how many iterations of MGET[DL] have taken place, all of which need rewinding.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/lib/usercopy.c | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)
arch/metag/lib/usercopy.c +28 -8
index 4422928a1746..e09c95ba028c 100644
@@ -687,29 +687,49 @@ EXPORT_SYMBOL(__copy_user);
  *
  *	Rationale:
  *		A fault occurs while reading from user buffer, which is the
- *		source. Since the fault is at a single address, we only
- *		need to rewind by 8 bytes.
+ *		source.
  *		Since we don't write to kernel buffer until we read first,
  *		the kernel buffer is at the right state and needn't be
- *		corrected.
+ *		corrected, but the source must be rewound to the beginning of
+ *		the block, which is LSM_STEP*8 bytes.
+ *		LSM_STEP is bits 10:8 in TXSTATUS which is already read
+ *		and stored in D0Ar2
+ *
+ *		NOTE: If a fault occurs at the last operation in M{G,S}ETL
+ *			LSM_STEP will be 0. ie: we do 4 writes in our case, if
+ *			a fault happens at the 4th write, LSM_STEP will be 0
+ *			instead of 4. The code copes with that.
  */
 #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id)	\
 	__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id,		\
-		"SUB	%1, %1, #8\n")
+		"LSR	D0Ar2, D0Ar2, #5\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x38\n"				\
+		"ADDZ	D0Ar2, D0Ar2, #32\n"				\
+		"SUB	%1, %1, D0Ar2\n")
 
 /*	rewind 'from' pointer when a fault occurs
  *
  *	Rationale:
  *		A fault occurs while reading from user buffer, which is the
- *		source. Since the fault is at a single address, we only
- *		need to rewind by 4 bytes.
+ *		source.
  *		Since we don't write to kernel buffer until we read first,
  *		the kernel buffer is at the right state and needn't be
- *		corrected.
+ *		corrected, but the source must be rewound to the beginning of
+ *		the block, which is LSM_STEP*4 bytes.
+ *		LSM_STEP is bits 10:8 in TXSTATUS which is already read
+ *		and stored in D0Ar2
+ *
+ *		NOTE: If a fault occurs at the last operation in M{G,S}ETL
+ *			LSM_STEP will be 0. ie: we do 4 writes in our case, if
+ *			a fault happens at the 4th write, LSM_STEP will be 0
+ *			instead of 4. The code copes with that.
  */
 #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id)	\
 	__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id,		\
-		"SUB	%1, %1, #4\n")
+		"LSR	D0Ar2, D0Ar2, #6\n"				\
+		"ANDS	D0Ar2, D0Ar2, #0x1c\n"				\
+		"ADDZ	D0Ar2, D0Ar2, #16\n"				\
+		"SUB	%1, %1, D0Ar2\n")
 
 
 /*
Signature · 1 line
2.12.2
author
#14 lore raw

PATCH 14/86 metag/usercopy: Add missing fixups

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit b884a190afcecdbef34ca508ea5ee88bb7c77861 upstream.

The rapf copy loops in the Meta usercopy code is missing some extable entries for HTP cores with unaligned access checking enabled, where faults occur on the instruction immediately after the faulting access.

Add the fixup labels and extable entries for these cases so that corner case user copy failures don't cause kernel crashes.

Fixes 373cd784d0fc ("metag: Memory handling")
---
 arch/metag/lib/usercopy.c | 72 +++++++++++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 24 deletions(-)
arch/metag/lib/usercopy.c +48 -24
index e09c95ba028c..2792fc621088 100644
@@ -259,27 +259,31 @@
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"22:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
-		"SUB	%3, %3, #32\n"					\
 		"23:\n"							\
-		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"SUB	%3, %3, #32\n"					\
 		"24:\n"							\
+		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"25:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"26:\n"							\
 		"SUB	%3, %3, #32\n"					\
 		"DCACHE	[%1+#-64], D0Ar6\n"				\
 		"BR	$Lloop"id"\n"					\
 									\
 		"MOV	RAPF, %1\n"					\
-		"25:\n"							\
+		"27:\n"							\
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"26:\n"							\
+		"28:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"29:\n"							\
 		"SUB	%3, %3, #32\n"					\
-		"27:\n"							\
+		"30:\n"							\
 		"MGETL	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"28:\n"							\
+		"31:\n"							\
 		"MSETL	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"32:\n"							\
 		"SUB	%0, %0, #8\n"					\
-		"29:\n"							\
+		"33:\n"							\
 		"SETL	[%0++], D0.7, D1.7\n"				\
 		"SUB	%3, %3, #32\n"					\
 		"1:"							\
@@ -311,7 +315,11 @@
 		"	.long 26b,3b\n"					\
 		"	.long 27b,3b\n"					\
 		"	.long 28b,3b\n"					\
-		"	.long 29b,4b\n"					\
+		"	.long 29b,3b\n"					\
+		"	.long 30b,3b\n"					\
+		"	.long 31b,3b\n"					\
+		"	.long 32b,3b\n"					\
+		"	.long 33b,4b\n"					\
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
@@ -402,47 +410,55 @@
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"22:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
-		"SUB	%3, %3, #16\n"					\
 		"23:\n"							\
-		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"24:\n"							\
-		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
 		"SUB	%3, %3, #16\n"					\
-		"25:\n"							\
+		"24:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"26:\n"							\
+		"25:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"26:\n"							\
 		"SUB	%3, %3, #16\n"					\
 		"27:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
 		"28:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"29:\n"							\
+		"SUB	%3, %3, #16\n"					\
+		"30:\n"							\
+		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
+		"31:\n"							\
+		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"32:\n"							\
 		"SUB	%3, %3, #16\n"					\
 		"DCACHE	[%1+#-64], D0Ar6\n"				\
 		"BR	$Lloop"id"\n"					\
 									\
 		"MOV	RAPF, %1\n"					\
-		"29:\n"							\
+		"33:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"30:\n"							\
+		"34:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"35:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"31:\n"							\
+		"36:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"32:\n"							\
+		"37:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"38:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"33:\n"							\
+		"39:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"34:\n"							\
+		"40:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"41:\n"							\
 		"SUB	%3, %3, #16\n"					\
-		"35:\n"							\
+		"42:\n"							\
 		"MGETD	D0FrT, D0.5, D0.6, D0.7, [%1++]\n"		\
-		"36:\n"							\
+		"43:\n"							\
 		"MSETD	[%0++], D0FrT, D0.5, D0.6, D0.7\n"		\
+		"44:\n"							\
 		"SUB	%0, %0, #4\n"					\
-		"37:\n"							\
+		"45:\n"							\
 		"SETD	[%0++], D0.7\n"					\
 		"SUB	%3, %3, #16\n"					\
 		"1:"							\
@@ -482,7 +498,15 @@
 		"	.long 34b,3b\n"					\
 		"	.long 35b,3b\n"					\
 		"	.long 36b,3b\n"					\
-		"	.long 37b,4b\n"					\
+		"	.long 37b,3b\n"					\
+		"	.long 38b,3b\n"					\
+		"	.long 39b,3b\n"					\
+		"	.long 40b,3b\n"					\
+		"	.long 41b,3b\n"					\
+		"	.long 42b,3b\n"					\
+		"	.long 43b,3b\n"					\
+		"	.long 44b,3b\n"					\
+		"	.long 45b,4b\n"					\
 		"	.previous\n"					\
 		: "=r" (to), "=r" (from), "=r" (ret), "=d" (n)		\
 		: "0" (to), "1" (from), "2" (ret), "3" (n)		\
Signature · 1 line
2.12.2
author
#15 lore raw

PATCH 15/86 powerpc: Don't try to fix up misaligned load-with-reservation instructions

In reply to Jiri Slaby

From: Paul Mackerras <[email protected]>

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

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

commit 48fe9e9488743eec9b7c1addd3c93f12f2123d54 upstream.

In the past, there was only one load-with-reservation instruction, lwarx, and if a program attempted a lwarx on a misaligned address, it would take an alignment interrupt and the kernel handler would emulate it as though it was lwzx, which was not really correct, but benign since it is loading the right amount of data, and the lwarx should be paired with a stwcx. to the same address, which would also cause an alignment interrupt which would result in a SIGBUS being delivered to the process.

We now have 5 different sizes of load-with-reservation instruction. Of those, lharx and ldarx cause an immediate SIGBUS by luck since their entries in aligninfo[] overlap instructions which were not fixed up, but lqarx overlaps with lhz and will be emulated as such. lbarx can never generate an alignment interrupt since it only operates on 1 byte.

To straighten this out and fix the lqarx case, this adds code to detect the l[hwdq]arx instructions and return without fixing them up, resulting in a SIGBUS being delivered to the process.

[js] include disassemble.h in 3.12

---
 arch/powerpc/kernel/align.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)
arch/powerpc/kernel/align.c +20 -8
index a27ccd5dc6b9..bbda9da6374e 100644
@@ -25,6 +25,7 @@
 #include <asm/cputable.h>
 #include <asm/emulated_ops.h>
 #include <asm/switch_to.h>
+#include <asm/disassemble.h>
 
 struct aligninfo {
 	unsigned char len;
@@ -768,14 +769,25 @@ int fix_alignment(struct pt_regs *regs)
 	nb = aligninfo[instr].len;
 	flags = aligninfo[instr].flags;
 
-	/* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
-	if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
-		nb = 8;
-		flags = LD+SW;
-	} else if (IS_XFORM(instruction) &&
-		   ((instruction >> 1) & 0x3ff) == 660) {
-		nb = 8;
-		flags = ST+SW;
+	/*
+	 * Handle some cases which give overlaps in the DSISR values.
+	 */
+	if (IS_XFORM(instruction)) {
+		switch (get_xop(instruction)) {
+		case 532:	/* ldbrx */
+			nb = 8;
+			flags = LD+SW;
+			break;
+		case 660:	/* stdbrx */
+			nb = 8;
+			flags = ST+SW;
+			break;
+		case 20:	/* lwarx */
+		case 84:	/* ldarx */
+		case 116:	/* lharx */
+		case 276:	/* lqarx */
+			return 0;	/* not emulated ever */
+		}
 	}
 
 	/* Byteswap little endian loads and stores */
Signature · 1 line
2.12.2
author
#16 lore raw

PATCH 16/86 s390/decompressor: fix initrd corruption caused by bss clear

In reply to Jiri Slaby

From: Marcelo Henrique Cerri <[email protected]>

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

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

commit d82c0d12c92705ef468683c9b7a8298dd61ed191 upstream.

Reorder the operations in decompress_kernel() to ensure initrd is moved to a safe location before the bss section is zeroed.

During decompression bss can overlap with the initrd and this can corrupt the initrd contents depending on the size of the compressed kernel (which affects where the initrd is placed by the bootloader) and the size of the bss section of the decompressor.

Also use the correct initrd size when checking for overlaps with parmblock.

Fixes 06c0dd72aea3 ([S390] fix boot failures with compressed kernels)
---
 arch/s390/boot/compressed/misc.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)
arch/s390/boot/compressed/misc.c +19 -16
index 57cbaff1f397..d73c8878b0c1 100644
@@ -142,31 +142,34 @@ static void check_ipl_parmblock(void *start, unsigned long size)
 
 unsigned long decompress_kernel(void)
 {
-	unsigned long output_addr;
-	unsigned char *output;
+	void *output, *kernel_end;
 
-	output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
-	check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
-	memset(&_bss, 0, &_ebss - &_bss);
-	free_mem_ptr = (unsigned long)&_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-	output = (unsigned char *) output_addr;
+	output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
+	kernel_end = output + SZ__bss_start;
+	check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/*
 	 * Move the initrd right behind the end of the decompressed
-	 * kernel image.
+	 * kernel image. This also prevents initrd corruption caused by
+	 * bss clearing since kernel_end will always be located behind the
+	 * current bss section..
 	 */
-	if (INITRD_START && INITRD_SIZE &&
-	    INITRD_START < (unsigned long) output + SZ__bss_start) {
-		check_ipl_parmblock(output + SZ__bss_start,
-				    INITRD_START + INITRD_SIZE);
-		memmove(output + SZ__bss_start,
-			(void *) INITRD_START, INITRD_SIZE);
-		INITRD_START = (unsigned long) output + SZ__bss_start;
+	if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
+		check_ipl_parmblock(kernel_end, INITRD_SIZE);
+		memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
+		INITRD_START = (unsigned long) kernel_end;
 	}
 #endif
 
+	/*
+	 * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be
+	 * initialized afterwards since they reside in bss.
+	 */
+	memset(&_bss, 0, &_ebss - &_bss);
+	free_mem_ptr = (unsigned long) &_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
 	puts("Uncompressing Linux... ");
 	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
 	puts("Ok, booting the kernel.\n");
Signature · 1 line
2.12.2
author
#17 lore raw

PATCH 17/86 mm/mempolicy.c: fix error handling in set_mempolicy and mbind.

In reply to Jiri Slaby

From: Chris Salls <[email protected]>

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

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

commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 upstream.

In the case that compat_get_bitmap fails we do not want to copy the bitmap to the user as it will contain uninitialized stack data and leak sensitive data.

---
 mm/mempolicy.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)
mm/mempolicy.c +8 -12
index 51cd7d066e0f..175830bd6e5a 100644
@@ -1587,7 +1587,6 @@ asmlinkage long compat_sys_get_mempolicy(int __user *policy,
 asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
 				     compat_ulong_t maxnode)
 {
-	long err = 0;
 	unsigned long __user *nm = NULL;
 	unsigned long nr_bits, alloc_size;
 	DECLARE_BITMAP(bm, MAX_NUMNODES);
@@ -1596,14 +1595,13 @@ asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
 	alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
 
 	if (nmask) {
-		err = compat_get_bitmap(bm, nmask, nr_bits);
+		if (compat_get_bitmap(bm, nmask, nr_bits))
+			return -EFAULT;
 		nm = compat_alloc_user_space(alloc_size);
-		err |= copy_to_user(nm, bm, alloc_size);
+		if (copy_to_user(nm, bm, alloc_size))
+			return -EFAULT;
 	}
 
-	if (err)
-		return -EFAULT;
-
 	return sys_set_mempolicy(mode, nm, nr_bits+1);
 }
 
@@ -1611,7 +1609,6 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
 			     compat_ulong_t mode, compat_ulong_t __user *nmask,
 			     compat_ulong_t maxnode, compat_ulong_t flags)
 {
-	long err = 0;
 	unsigned long __user *nm = NULL;
 	unsigned long nr_bits, alloc_size;
 	nodemask_t bm;
@@ -1620,14 +1617,13 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
 	alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
 
 	if (nmask) {
-		err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits);
+		if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits))
+			return -EFAULT;
 		nm = compat_alloc_user_space(alloc_size);
-		err |= copy_to_user(nm, nodes_addr(bm), alloc_size);
+		if (copy_to_user(nm, nodes_addr(bm), alloc_size))
+			return -EFAULT;
 	}
 
-	if (err)
-		return -EFAULT;
-
 	return sys_mbind(start, len, mode, nm, nr_bits+1, flags);
 }
 
Signature · 1 line
2.12.2
author
#18 lore raw

PATCH 18/86 usb: dwc3: gadget: delay unmap of bounced requests

In reply to Jiri Slaby

From: Janusz Dziedzic <[email protected]>

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

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

commit de288e36fe33f7e06fa272bc8e2f85aa386d99aa upstream.

In the case of bounced ep0 requests, we must delay DMA operation until after ->complete() otherwise we might overwrite contents of req->buf.

This caused problems with RNDIS gadget.

---
 drivers/usb/dwc3/gadget.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/usb/dwc3/gadget.c +17 -4
index f4a36f4669bb..b1b833843b9a 100644
@@ -221,6 +221,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 		int status)
 {
 	struct dwc3			*dwc = dep->dwc;
+	unsigned int			unmap_after_complete = false;
 	int				i;
 
 	if (req->queued) {
@@ -245,11 +246,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (req->request.status == -EINPROGRESS)
 		req->request.status = status;
 
-	if (dwc->ep0_bounced && dep->number <= 1)
+	/*
+	 * NOTICE we don't want to unmap before calling ->complete() if we're
+	 * dealing with a bounced ep0 request. If we unmap it here, we would end
+	 * up overwritting the contents of req->buf and this could confuse the
+	 * gadget driver.
+	 */
+	if (dwc->ep0_bounced && dep->number <= 1) {
 		dwc->ep0_bounced = false;
-
-	usb_gadget_unmap_request(&dwc->gadget, &req->request,
-			req->direction);
+		unmap_after_complete = true;
+	} else {
+		usb_gadget_unmap_request(&dwc->gadget,
+				&req->request, req->direction);
+	}
 
 	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
 			req, dep->name, req->request.actual,
@@ -258,6 +267,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	spin_unlock(&dwc->lock);
 	req->request.complete(&dep->endpoint, &req->request);
 	spin_lock(&dwc->lock);
+
+	if (unmap_after_complete)
+		usb_gadget_unmap_request(&dwc->gadget,
+				&req->request, req->direction);
 }
 
 static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
Signature · 1 line
2.12.2
author
#19 lore raw

PATCH 19/86 mtd: bcm47xxpart: fix parsing first block after aligned TRX

In reply to Jiri Slaby

From: Rafał Miłecki <[email protected]>

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

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

commit bd5d21310133921021d78995ad6346f908483124 upstream.

After parsing TRX we should skip to the first block placed behind it. Our code was working only with TRX with length not aligned to the blocksize. In other cases (length aligned) it was missing the block places right after TRX.

This fixes calculation and simplifies the comment.

---
 drivers/mtd/bcm47xxpart.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/mtd/bcm47xxpart.c +4 -6
index 9279a9174f84..04e2e4308890 100644
@@ -159,12 +159,10 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 
 			last_trx_part = curr_part - 1;
 
-			/*
-			 * We have whole TRX scanned, skip to the next part. Use
-			 * roundown (not roundup), as the loop will increase
-			 * offset in next step.
-			 */
-			offset = rounddown(offset + trx->length, blocksize);
+			/* Jump to the end of TRX */
+			offset = roundup(offset + trx->length, blocksize);
+			/* Next loop iteration will increase the offset */
+			offset -= blocksize;
 			continue;
 		}
 	}
Signature · 1 line
2.12.2
author
#20 lore raw

PATCH 20/86 net/packet: fix overflow in check for priv area size

In reply to Jiri Slaby

From: Andrey Konovalov <[email protected]>

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

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

commit 2b6867c2ce76c596676bec7d2d525af525fdc6e2 upstream.

Subtracting tp_sizeof_priv from tp_block_size and casting to int to check whether one is less then the other doesn't always work (both of them are unsigned ints).

Compare them as is instead.

Also cast tp_sizeof_priv to u64 before using BLK_PLUS_PRIV, as it can overflow inside BLK_PLUS_PRIV otherwise.

---
 net/packet/af_packet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/packet/af_packet.c +2 -2
index b56a9fdbf2a3..ed1fed3330af 100644
@@ -3653,8 +3653,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 		if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
 			goto out;
 		if (po->tp_version >= TPACKET_V3 &&
-		    (int)(req->tp_block_size -
-			  BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
+		    req->tp_block_size <=
+			  BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
 			goto out;
 		if (unlikely(req->tp_frame_size < po->tp_hdrlen +
 					po->tp_reserve))
Signature · 1 line
2.12.2
author
#21 lore raw

PATCH 21/86 usb: hub: Wait for connection to be reestablished after port reset

In reply to Jiri Slaby

From: Guenter Roeck <[email protected]>

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

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

commit 22547c4cc4fe20698a6a85a55b8788859134b8e4 upstream.

On a system with a defective USB device connected to an USB hub, an endless sequence of port connect events was observed. The sequence of events as observed is as follows:

- Port reports connected event (port status=USB_PORT_STAT_CONNECTION).
- Event handler debounces port and resets it by calling hub_port_reset().
- hub_port_reset() calls hub_port_wait_reset() to wait for the reset to complete.
- The reset completes, but USB_PORT_STAT_CONNECTION is not immediately set in the port status register.
- hub_port_wait_reset() returns -ENOTCONN.
- Port initialization sequence is aborted.
- A few milliseconds later, the port again reports a connected event, and the sequence repeats.

This continues either forever or, randomly, stops if the connection is already re-established when the port status is read. It results in a high rate of udev events. This in turn destabilizes userspace since the above sequence holds the device mutex pretty much continuously and prevents userspace from actually reading the device status.

To prevent the problem from happening, let's wait for the connection to be re-established after a port reset. If the device was actually disconnected, the code will still return an error, but it will do so only after the long reset timeout.

---
 drivers/usb/core/hub.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/usb/core/hub.c +9 -2
index 53aa23dee140..e56b36ff18c6 100644
@@ -2508,8 +2508,15 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 		if (ret < 0)
 			return ret;
 
-		/* The port state is unknown until the reset completes. */
-		if (!(portstatus & USB_PORT_STAT_RESET))
+		/*
+		 * The port state is unknown until the reset completes.
+		 *
+		 * On top of that, some chips may require additional time
+		 * to re-establish a connection after the reset is complete,
+		 * so also wait for the connection to be re-established.
+		 */
+		if (!(portstatus & USB_PORT_STAT_RESET) &&
+		    (portstatus & USB_PORT_STAT_CONNECTION))
 			break;
 
 		/* switch to the long delay after two short delay failures */
Signature · 1 line
2.12.2
author
#22 lore raw

PATCH 22/86 net/mlx4_en: Fix bad WQE issue

In reply to Jiri Slaby

From: Eugenia Emantayev <[email protected]>

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

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

commit 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc upstream.

Single send WQE in RX buffer should be stamped with software ownership in order to prevent the flow of QP in error in FW once UPDATE_QP is called.

Fixes 9f519f68cfff ('mlx4_en: Not using Shared Receive Queues')
---
 drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx4/en_rx.c +7 -1
index afe2efa69c86..4267de129197 100644
@@ -384,8 +384,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 		ring->cqn = priv->rx_cq[ring_ind].mcq.cqn;
 
 		ring->stride = stride;
-		if (ring->stride <= TXBB_SIZE)
+		if (ring->stride <= TXBB_SIZE) {
+			/* Stamp first unused send wqe */
+			__be32 *ptr = (__be32 *)ring->buf;
+			__be32 stamp = cpu_to_be32(1 << STAMP_SHIFT);
+			*ptr = stamp;
+			/* Move pointer to start of rx section */
 			ring->buf += TXBB_SIZE;
+		}
 
 		ring->log_stride = ffs(ring->stride) - 1;
 		ring->buf_size = ring->size * ring->stride;
Signature · 1 line
2.12.2
author
#23 lore raw

PATCH 23/86 net/mlx4_core: Fix racy CQ (Completion Queue) free

In reply to Jiri Slaby

From: Jack Morgenstein <[email protected]>

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

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

commit 291c566a28910614ce42d0ffe82196eddd6346f4 upstream.

In function mlx4_cq_completion() and mlx4_cq_event(), the radix_tree_lookup requires a rcu_read_lock.
This is mandatory: if another core frees the CQ, it could run the radix_tree_node_rcu_free() call_rcu() callback while its being used by the radix tree lookup function.

Additionally, in function mlx4_cq_event(), since we are adding the rcu lock around the radix-tree lookup, we no longer need to take the spinlock. Also, the synchronize_irq() call for the async event eliminates the need for incrementing the cq reference count in mlx4_cq_event().

Other changes:
1. In function mlx4_cq_free(), replace spin_lock_irq with spin_lock:
we no longer take this spinlock in the interrupt context. The spinlock here, therefore, simply protects against different threads simultaneously invoking mlx4_cq_free() for different cq's.

2. In function mlx4_cq_free(), we move the radix tree delete to before the synchronize_irq() calls. This guarantees that we will not access this cq during any subsequent interrupts, and therefore can safely free the CQ after the synchronize_irq calls. The rcu_read_lock in the interrupt handlers only needs to protect against corrupting the radix tree; the interrupt handlers may access the cq outside the rcu_read_lock due to the synchronize_irq calls which protect against premature freeing of the cq.

3. In function mlx4_cq_event(), we change the mlx_warn message to mlx4_dbg.

4. We leave the cq reference count mechanism in place, because it is still needed for the cq completion tasklet mechanism.

Fixes 6d90aa5cf17b ("net/mlx4_core: Make sure there are no pending async events when freeing CQ")
Fixes 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters")
---
 drivers/net/ethernet/mellanox/mlx4/cq.c | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
drivers/net/ethernet/mellanox/mlx4/cq.c +20 -18
index 004e4231af67..528597f65937 100644
@@ -57,13 +57,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn)
 {
 	struct mlx4_cq *cq;
 
+	rcu_read_lock();
 	cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
 			       cqn & (dev->caps.num_cqs - 1));
+	rcu_read_unlock();
+
 	if (!cq) {
 		mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
 		return;
 	}
 
+	/* Acessing the CQ outside of rcu_read_lock is safe, because
+	 * the CQ is freed only after interrupt handling is completed.
+	 */
 	++cq->arm_sn;
 
 	cq->comp(cq);
@@ -74,23 +80,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
 	struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
 	struct mlx4_cq *cq;
 
-	spin_lock(&cq_table->lock);
-
+	rcu_read_lock();
 	cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
-	if (cq)
-		atomic_inc(&cq->refcount);
-
-	spin_unlock(&cq_table->lock);
+	rcu_read_unlock();
 
 	if (!cq) {
-		mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+		mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
 		return;
 	}
 
+	/* Acessing the CQ outside of rcu_read_lock is safe, because
+	 * the CQ is freed only after interrupt handling is completed.
+	 */
 	cq->event(cq, event_type);
-
-	if (atomic_dec_and_test(&cq->refcount))
-		complete(&cq->free);
 }
 
 static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
@@ -261,9 +263,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
 	if (err)
 		return err;
 
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
 	if (err)
 		goto err_icm;
 
@@ -303,9 +305,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
 	return 0;
 
 err_radix:
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	radix_tree_delete(&cq_table->tree, cq->cqn);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
 
 err_icm:
 	mlx4_cq_free_icm(dev, cq->cqn);
@@ -324,11 +326,11 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
 	if (err)
 		mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
 
-	synchronize_irq(priv->eq_table.eq[cq->vector].irq);
-
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	radix_tree_delete(&cq_table->tree, cq->cqn);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
+
+	synchronize_irq(priv->eq_table.eq[cq->vector].irq);
 
 	if (atomic_dec_and_test(&cq->refcount))
 		complete(&cq->free);
Signature · 1 line
2.12.2
author
#24 lore raw

PATCH 24/86 Input: xpad - add support for Razer Wildcat gamepad

In reply to Jiri Slaby

From: Cameron Gutman <[email protected]>

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

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

commit 5376366886251e2f8f248704adb620a4bc4c0937 upstream.

---
 drivers/input/joystick/xpad.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/input/joystick/xpad.c +2 -0
index a711aab97ae7..e7ffb85f2f60 100644
@@ -189,6 +189,7 @@ static const struct xpad_device {
 	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
 	{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+	{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
 	{ 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
 	{ 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
 	{ 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
@@ -311,6 +312,7 @@ static struct usb_device_id xpad_table[] = {
 	XPAD_XBOX360_VENDOR(0x1689),		/* Razer Onza */
 	XPAD_XBOX360_VENDOR(0x24c6),		/* PowerA Controllers */
 	XPAD_XBOX360_VENDOR(0x1532),		/* Razer Sabertooth */
+	XPAD_XBOXONE_VENDOR(0x1532),		/* Razer Wildcat */
 	XPAD_XBOX360_VENDOR(0x15e4),		/* Numark X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x162e),		/* Joytech X-Box 360 controllers */
 	{ }
Signature · 1 line
2.12.2
author
#25 lore raw

PATCH 25/86 perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32()

In reply to Jiri Slaby

From: Peter Zijlstra <[email protected]>

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

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

commit f2200ac311302fcdca6556fd0c5127eab6c65a3e upstream.

When the perf_branch_entry::{in_tx,abort,cycles} fields were added, intel_pmu_lbr_read_32() wasn't updated to initialize them.

[js] there is no cycles in 3.12 yet

Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes 135c5612c460 ("perf/x86/intel: Support Haswell/v4 LBR format")
---
 arch/x86/kernel/cpu/perf_event_intel_lbr.c | 2 ++
 1 file changed, 2 insertions(+)
arch/x86/kernel/cpu/perf_event_intel_lbr.c +2 -0
index d5be06a5005e..ea28a92e563a 100644
@@ -268,6 +268,8 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
 		cpuc->lbr_entries[i].to		= msr_lastbranch.to;
 		cpuc->lbr_entries[i].mispred	= 0;
 		cpuc->lbr_entries[i].predicted	= 0;
+		cpuc->lbr_entries[i].in_tx	= 0;
+		cpuc->lbr_entries[i].abort	= 0;
 		cpuc->lbr_entries[i].reserved	= 0;
 	}
 	cpuc->lbr_stack.nr = i;
Signature · 1 line
2.12.2
author
#26 lore raw

PATCH 26/86 x86/vdso: Plug race between mapping and ELF header setup

In reply to Jiri Slaby

From: Thomas Gleixner <[email protected]>

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

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

commit 6fdc6dd90272ce7e75d744f71535cfbd8d77da81 upstream.

The vsyscall32 sysctl can racy against a concurrent fork when it switches from disabled to enabled:

    arch_setup_additional_pages()
	if (vdso32_enabled)
           --> No mapping
                                        sysctl.vsysscall32()
                                          --> vdso32_enabled = true
    create_elf_tables()
      ARCH_DLINFO_IA32
        if (vdso32_enabled) {
           --> Add VDSO entry with NULL pointer

Make ARCH_DLINFO_IA32 check whether the VDSO mapping has been set up for the newly forked process or not.

---
 arch/x86/include/asm/elf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/elf.h +1 -1
index 01f15b227d7e..2fa7f4f6ecb3 100644
@@ -272,7 +272,7 @@ struct task_struct;
 
 #define	ARCH_DLINFO_IA32(vdso_enabled)					\
 do {									\
-	if (vdso_enabled) {						\
+	if (VDSO_CURRENT_BASE) {					\
 		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
 		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
 	}								\
Signature · 1 line
2.12.2
author
#27 lore raw

PATCH 27/86 iscsi-target: Fix TMR reference leak during session shutdown

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

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

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

commit efb2ea770bb3b0f40007530bc8b0c22f36e1c5eb upstream.

This patch fixes a iscsi-target specific TMR reference leak during session shutdown, that could occur when a TMR was quiesced before the hand-off back to iscsi-target code via transport_cmd_check_stop_to_fabric().

The reference leak happens because iscsit_free_cmd() was incorrectly skipping the final target_put_sess_cmd() for TMRs when transport_generic_free_cmd() returned zero because the se_cmd->cmd_kref did not reach zero, due to the missing se_cmd assignment in original code.

The result was iscsi_cmd and it's associated se_cmd memory would be freed once se_sess->sess_cmd_map where released, but the associated se_tmr_req was leaked and remained part of se_device->dev_tmr_list.

This bug would manfiest itself as kernel paging request OOPsen in core_tmr_lun_reset(), when a left-over se_tmr_req attempted to dereference it's se_cmd pointer that had already been released during normal session shutdown.

To address this bug, go ahead and treat ISCSI_OP_SCSI_CMD and ISCSI_OP_SCSI_TMFUNC the same when there is an extra se_cmd->cmd_kref to drop in iscsit_free_cmd(), and use op_scsi to signal __iscsit_free_cmd() when the former needs to clear any further iscsi related I/O state.

---
 drivers/target/iscsi/iscsi_target_util.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/target/iscsi/iscsi_target_util.c +7 -5
index c5c98559f7f6..2ca23395ec15 100644
@@ -728,21 +728,23 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
 {
 	struct se_cmd *se_cmd = NULL;
 	int rc;
+	bool op_scsi = false;
 	/*
 	 * Determine if a struct se_cmd is associated with
 	 * this struct iscsi_cmd.
 	 */
 	switch (cmd->iscsi_opcode) {
 	case ISCSI_OP_SCSI_CMD:
-		se_cmd = &cmd->se_cmd;
-		__iscsit_free_cmd(cmd, true, shutdown);
+		op_scsi = true;
 		/*
 		 * Fallthrough
 		 */
 	case ISCSI_OP_SCSI_TMFUNC:
-		rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
-		if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
-			__iscsit_free_cmd(cmd, true, shutdown);
+		se_cmd = &cmd->se_cmd;
+		__iscsit_free_cmd(cmd, op_scsi, shutdown);
+		rc = transport_generic_free_cmd(se_cmd, shutdown);
+		if (!rc && shutdown && se_cmd->se_sess) {
+			__iscsit_free_cmd(cmd, op_scsi, shutdown);
 			target_put_sess_cmd(se_cmd->se_sess, se_cmd);
 		}
 		break;
Signature · 1 line
2.12.2
author
#28 lore raw

PATCH 28/86 iscsi-target: Drop work-around for legacy GlobalSAN initiator

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

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

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

commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46 upstream.

Once upon a time back in 2009, a work-around was added to support the GlobalSAN iSCSI initiator v3.3 for MacOSX, which during login did not propose nor respond to MaxBurstLength, FirstBurstLength, DefaultTime2Wait and DefaultTime2Retain keys.

The work-around in iscsi_check_proposer_for_optional_reply() allowed the missing keys to be proposed, but did not require waiting for a response before moving to full feature phase operation. This allowed GlobalSAN v3.3 to work out-of-the box, and for many years we didn't run into login interopt issues with any other initiators..

Until recently, when Martin tried a QLogic 57840S iSCSI Offload HBA on Windows 2016 which completed login, but subsequently failed with:

    Got unknown iSCSI OpCode: 0x43

The issue was QLogic MSFT side did not propose DefaultTime2Wait + DefaultTime2Retain, so LIO proposes them itself, and immediately transitions to full feature phase because of the GlobalSAN hack. However, the QLogic MSFT side still attempts to respond to DefaultTime2Retain + DefaultTime2Wait, even though LIO has set ISCSI_FLAG_LOGIN_NEXT_STAGE3 + ISCSI_FLAG_LOGIN_TRANSIT in last login response.

So while the QLogic MSFT side should have been proposing these two keys to start, it was doing the correct thing per RFC-3720 attempting to respond to proposed keys before transitioning to full feature phase.

All that said, recent versions of GlobalSAN iSCSI (v5.3.0.541) does correctly propose the four keys during login, making the original work-around moot.

So in order to allow QLogic MSFT to run unmodified as-is, go ahead and drop this long standing work-around.

---
 drivers/target/iscsi/iscsi_target_parameters.c | 16 ----------------
 1 file changed, 16 deletions(-)
drivers/target/iscsi/iscsi_target_parameters.c +0 -16
index 43b7e6a616b8..c9df3cd89a13 100644
@@ -804,22 +804,6 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
 		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
 			SET_PSTATE_REPLY_OPTIONAL(param);
 		/*
-		 * The GlobalSAN iSCSI Initiator for MacOSX does
-		 * not respond to MaxBurstLength, FirstBurstLength,
-		 * DefaultTime2Wait or DefaultTime2Retain parameter keys.
-		 * So, we set them to 'reply optional' here, and assume the
-		 * the defaults from iscsi_parameters.h if the initiator
-		 * is not RFC compliant and the keys are not negotiated.
-		 */
-		if (!strcmp(param->name, MAXBURSTLENGTH))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, FIRSTBURSTLENGTH))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, DEFAULTTIME2WAIT))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		if (!strcmp(param->name, DEFAULTTIME2RETAIN))
-			SET_PSTATE_REPLY_OPTIONAL(param);
-		/*
 		 * Required for gPXE iSCSI boot client
 		 */
 		if (!strcmp(param->name, MAXCONNECTIONS))
Signature · 1 line
2.12.2
author
#29 lore raw

PATCH 29/86 scsi: sr: Sanity check returned mode data

In reply to Jiri Slaby

From: "Martin K. Petersen" <[email protected]>

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

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

commit a00a7862513089f17209b732f230922f1942e0b9 upstream.

Kefeng Wang discovered that old versions of the QEMU CD driver would return mangled mode data causing us to walk off the end of the buffer in an attempt to parse it. Sanity check the returned mode sense data.

---
 drivers/scsi/sr.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/sr.c +4 -2
index 1ac9943cbb93..c1f23abd754a 100644
@@ -855,6 +855,7 @@ static void get_capabilities(struct scsi_cd *cd)
 	unsigned char *buffer;
 	struct scsi_mode_data data;
 	struct scsi_sense_hdr sshdr;
+	unsigned int ms_len = 128;
 	int rc, n;
 
 	static const char *loadmech[] =
@@ -881,10 +882,11 @@ static void get_capabilities(struct scsi_cd *cd)
 	scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
 
 	/* ask for mode page 0x2a */
-	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
+	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
 			     SR_TIMEOUT, 3, &data, NULL);
 
-	if (!scsi_status_is_good(rc)) {
+	if (!scsi_status_is_good(rc) || data.length > ms_len ||
+	    data.header_length + data.block_descriptor_length > data.length) {
 		/* failed, drive doesn't have capabilities mode page */
 		cd->cdi.speed = 1;
 		cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
Signature · 1 line
2.12.2
author
#30 lore raw

PATCH 30/86 scsi: sd: Fix capacity calculation with 32-bit sector_t

In reply to Jiri Slaby

From: "Martin K. Petersen" <[email protected]>

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

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

commit 7c856152cb92f8eee2df29ef325a1b1f43161aff upstream.

We previously made sure that the reported disk capacity was less than 0xffffffff blocks when the kernel was not compiled with large sector_t support (CONFIG_LBDAF). However, this check assumed that the capacity was reported in units of 512 bytes.

Add a sanity check function to ensure that we only enable disks if the entire reported capacity can be expressed in terms of sector_t.

---
 drivers/scsi/sd.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/scsi/sd.c +18 -2
index bf7ff64ac7eb..509b06aa3f37 100644
@@ -1929,6 +1929,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
 #define READ_CAPACITY_RETRIES_ON_RESET	10
 
+/*
+ * Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set
+ * and the reported logical block size is bigger than 512 bytes. Note
+ * that last_sector is a u64 and therefore logical_to_sectors() is not
+ * applicable.
+ */
+static bool sd_addressable_capacity(u64 lba, unsigned int sector_size)
+{
+	u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9);
+
+	if (sizeof(sector_t) == 4 && last_sector > U32_MAX)
+		return false;
+
+	return true;
+}
+
 static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 						unsigned char *buffer)
 {
@@ -1994,7 +2010,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 		return -ENODEV;
 	}
 
-	if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
+	if (!sd_addressable_capacity(lba, sector_size)) {
 		sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
 			"kernel compiled with support for large block "
 			"devices.\n");
@@ -2080,7 +2096,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
 		return sector_size;
 	}
 
-	if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
+	if (!sd_addressable_capacity(lba, sector_size)) {
 		sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
 			"kernel compiled with support for large block "
 			"devices.\n");
Signature · 1 line
2.12.2
author
#31 lore raw

PATCH 31/86 xen, fbfront: fix connecting to backend

In reply to Jiri Slaby

From: Juergen Gross <[email protected]>

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

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

commit 9121b15b5628b38b4695282dc18c553440e0f79b upstream.

Connecting to the backend isn't working reliably in xen-fbfront: in case XenbusStateInitWait of the backend has been missed the backend transition to XenbusStateConnected will trigger the connected state only without doing the actions required when the backend has connected.

---
 drivers/video/xen-fbfront.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/xen-fbfront.c +2 -2
index 4b2d3ab870f3..fc56d1ed11fc 100644
@@ -644,7 +644,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
 		break;
 
 	case XenbusStateInitWait:
-InitWait:
 		xenbus_switch_state(dev, XenbusStateConnected);
 		break;
 
@@ -655,7 +654,8 @@ InitWait:
 		 * get Connected twice here.
 		 */
 		if (dev->state != XenbusStateConnected)
-			goto InitWait; /* no InitWait seen yet, fudge it */
+			/* no InitWait seen yet, fudge it */
+			xenbus_switch_state(dev, XenbusStateConnected);
 
 		if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
 				 "request-update", "%d", &val) < 0)
Signature · 1 line
2.12.2
author
#32 lore raw

PATCH 32/86 char: Drop bogus dependency of DEVPORT on !M68K

In reply to Jiri Slaby

From: Geert Uytterhoeven <[email protected]>

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

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

commit 309124e2648d668a0c23539c5078815660a4a850 upstream.

According to full-history-linux commit d3794f4fa7c3edc3 ("[PATCH] M68k update (part 25)"), port operations are allowed on m68k if CONFIG_ISA is defined.

However, commit 153dcc54df826d2f ("[PATCH] mem driver: fix conditional on isa i/o support") accidentally changed an "||" into an "&&", disabling it completely on m68k. This logic was retained when introducing the DEVPORT symbol in commit 4f911d64e04a44c4 ("Make /dev/port conditional on config symbol").

Drop the bogus dependency on !M68K to fix this.

Fixes 153dcc54df826d2f ("[PATCH] mem driver: fix conditional on isa i/o support")
---
 drivers/char/Kconfig | 1 -
 1 file changed, 1 deletion(-)
drivers/char/Kconfig +0 -1
index 14219972c745..0070872c1441 100644
@@ -568,7 +568,6 @@ config TELCLOCK
 
 config DEVPORT
 	bool
-	depends on !M68K
 	depends on ISA || PCI
 	default y
 
Signature · 1 line
2.12.2
author
#33 lore raw

PATCH 33/86 char: lack of bool string made CONFIG_DEVPORT always on

In reply to Jiri Slaby

From: Max Bires <[email protected]>

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

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

commit f2cfa58b136e4b06a9b9db7af5ef62fbb5992f62 upstream.

Without a bool string present, using "# CONFIG_DEVPORT is not set" in defconfig files would not actually unset devport. This esnured that /dev/port was always on, but there are reasons a user may wish to disable it (smaller kernel, attack surface reduction) if it's not being used. Adding a message here in order to make this user visible.

---
 drivers/char/Kconfig | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/char/Kconfig +4 -1
index 0070872c1441..a961133e2aa2 100644
@@ -567,9 +567,12 @@ config TELCLOCK
 	  controlling the behavior of this hardware.
 
 config DEVPORT
-	bool
+	bool "/dev/port character device"
 	depends on ISA || PCI
 	default y
+	help
+	  Say Y here if you want to support the /dev/port device. The /dev/port
+	  device is similar to /dev/mem, but for I/O ports.
 
 source "drivers/s390/char/Kconfig"
 
Signature · 1 line
2.12.2
author
#34 lore raw

PATCH 34/86 zram: do not use copy_page with non-page aligned address

In reply to Jiri Slaby

From: Minchan Kim <[email protected]>

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

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

commit d72e9a7a93e4f8e9e52491921d99e0c8aa89eb4e upstream.

The copy_page is optimized memcpy for page-alinged address. If it is used with non-page aligned address, it can corrupt memory which means system corruption. With zram, it can happen with

1. 64K architecture
2. partial IO
3. slub debug

Partial IO need to allocate a page and zram allocates it via kmalloc. With slub debug, kmalloc(PAGE_SIZE) doesn't return page-size aligned address. And finally, copy_page(mem, cmem) corrupts memory.

So, this patch changes it to memcpy.

Actuaully, we don't need to change zram_bvec_write part because zsmalloc returns page-aligned address in case of PAGE_SIZE class but it's not good to rely on the internal of zsmalloc.

Note:
When this patch is merged to stable, clear_page should be fixed, too. Unfortunately, recent zram removes it by "same page merge" feature so it's hard to backport this patch to -stable tree.

I will handle it when I receive the mail from stable tree maintainer to merge this patch to backport.

Fixes 42e99bd ("zram: optimize memory operations with clear_page()/copy_page()")
Cc Sergey Senozhatsky <[email protected]>
---
 drivers/staging/zram/zram_drv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/zram/zram_drv.c +3 -3
index 162e01a27d40..f893a902a534 100644
@@ -321,13 +321,13 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
 	unsigned long handle = meta->table[index].handle;
 
 	if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) {
-		clear_page(mem);
+		memset(mem, 0, PAGE_SIZE);
 		return 0;
 	}
 
 	cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO);
 	if (meta->table[index].size == PAGE_SIZE)
-		copy_page(mem, cmem);
+		memcpy(mem, cmem, PAGE_SIZE);
 	else
 		ret = lzo1x_decompress_safe(cmem, meta->table[index].size,
 						mem, &clen);
@@ -482,7 +482,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 
 	if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
 		src = kmap_atomic(page);
-		copy_page(cmem, src);
+		memcpy(cmem, src, PAGE_SIZE);
 		kunmap_atomic(src);
 	} else {
 		memcpy(cmem, src, clen);
Signature · 1 line
2.12.2
author
#35 lore raw

PATCH 35/86 powerpc: Disable HFSCR[TM] if TM is not supported

In reply to Jiri Slaby

From: Benjamin Herrenschmidt <[email protected]>

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

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

commit 7ed23e1bae8bf7e37fd555066550a00b95a3a98b upstream.

On Power8 & Power9 the early CPU inititialisation in __init_HFSCR() turns on HFSCR[TM] (Hypervisor Facility Status and Control Register [Transactional Memory]), but that doesn't take into account that TM might be disabled by CPU features, or disabled by the kernel being built with CONFIG_PPC_TRANSACTIONAL_MEM=n.

So later in boot, when we have setup the CPU features, clear HSCR[TM] if the TM CPU feature has been disabled. We use CPU_FTR_TM_COMP to account for the CONFIG_PPC_TRANSACTIONAL_MEM=n case.

Without this a KVM guest might try use TM, even if told not to, and cause an oops in the host kernel. Typically the oops is seen in __kvmppc_vcore_entry() and may or may not be fatal to the host, but is always bad news.

In practice all shipping CPU revisions do support TM, and all host kernels we are aware of build with TM support enabled, so no one should actually be able to hit this in the wild.

Fixes 2a3563b023e5 ("powerpc: Setup in HFSCR for POWER8")
[mpe: Rewrite change log with input from Sam, add Fixes/stable]
[sb: Backported to linux-4.4.y: adjusted context]
---
 arch/powerpc/kernel/setup_64.c | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/powerpc/kernel/setup_64.c +9 -0
index 278ca93e1f28..c24af5669309 100644
@@ -143,6 +143,15 @@ static void check_smt_enabled(void)
 			of_node_put(dn);
 		}
 	}
+
+	/*
+	 * Fixup HFSCR:TM based on CPU features. The bit is set by our
+	 * early asm init because at that point we haven't updated our
+	 * CPU features from firmware and device-tree. Here we have,
+	 * so let's do it.
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP))
+		mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM);
 }
 
 /* Look for smt-enabled= cmdline option */
Signature · 1 line
2.12.2
author
#36 lore raw

PATCH 36/86 dvb-usb-v2: avoid use-after-free

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit 005145378c9ad7575a01b6ce1ba118fb427f583a upstream.

I ran into a stack frame size warning because of the on-stack copy of the USB device structure:

drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usbv2_disconnect':
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:1029:1: error: the frame size of 1104 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

Copying a device structure like this is wrong for a number of other reasons too aside from the possible stack overflow. One of them is that the dev_info() call will print the name of the device later, but AFAICT we have only copied a pointer to the name earlier and the actual name has been freed by the time it gets printed.

This removes the on-stack copy of the device and instead copies the device name using kstrdup(). I'm ignoring the possible failure here as both printk() and kfree() are able to deal with NULL pointers.

---
 drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +5 -4
index 8a054d66e708..6c8f83a0c0c7 100644
@@ -942,8 +942,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);
 void dvb_usbv2_disconnect(struct usb_interface *intf)
 {
 	struct dvb_usb_device *d = usb_get_intfdata(intf);
-	const char *name = d->name;
-	struct device dev = d->udev->dev;
+	const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL);
+	const char *drvname = d->name;
 	dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
 			intf->cur_altsetting->desc.bInterfaceNumber);
 
@@ -952,8 +952,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
 
 	dvb_usbv2_exit(d);
 
-	dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
-			KBUILD_MODNAME, name);
+	pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
+		KBUILD_MODNAME, drvname, devname);
+	kfree(devname);
 }
 EXPORT_SYMBOL(dvb_usbv2_disconnect);
 
Signature · 1 line
2.12.2
author
#37 lore raw

PATCH 37/86 ext4: fix inode checksum calculation problem if i_extra_size is small

In reply to Jiri Slaby

From: Daeho Jeong <[email protected]>

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

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

commit 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 upstream.

We've fixed the race condition problem in calculating ext4 checksum value in commit b47820edd163 ("ext4: avoid modifying checksum fields directly during checksum veficationon"). However, by this change, when calculating the checksum value of inode whose i_extra_size is less than 4, we couldn't calculate the checksum value in a proper way. This problem was found and reported by Nix, Thank you.

---
 fs/ext4/inode.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
fs/ext4/inode.c +2 -3
index 50fc2d1da9a9..9a3e7cffd6eb 100644
@@ -73,10 +73,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
 			csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
 					   csum_size);
 			offset += csum_size;
-			csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
-					   EXT4_INODE_SIZE(inode->i_sb) -
-					   offset);
 		}
+		csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
+				   EXT4_INODE_SIZE(inode->i_sb) - offset);
 	}
 
 	return csum;
Signature · 1 line
2.12.2
author
#38 lore raw

PATCH 38/86 platform/x86: acer-wmi: setup accelerometer when machine has appropriate notify event

In reply to Jiri Slaby

From: Chun-Yi Lee <[email protected]>

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

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

commit 98d610c3739ac354319a6590b915f4624d9151e6 upstream.

The accelerometer event relies on the ACERWMID_EVENT_GUID notify. So, this patch changes the codes to setup accelerometer input device when detected ACERWMID_EVENT_GUID. It avoids that the accel input device created on every Acer machines.

In addition, patch adds a clearly parsing logic of accelerometer hid to acer_wmi_get_handle_cb callback function. It is positive matching the "SENR" name with "BST0001" device to avoid non-supported hardware.

Cc Darren Hart <[email protected]>
[andy: slightly massage commit message]
Cc Ben Hutchings <[email protected]>
---
 drivers/platform/x86/acer-wmi.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
drivers/platform/x86/acer-wmi.c +18 -4
index 59a8d325a697..9e4f87004257 100644
@@ -1860,11 +1860,24 @@ static int acer_wmi_enable_lm(void)
 	return status;
 }
 
+#define ACER_WMID_ACCEL_HID	"BST0001"
+
 static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
 						void *ctx, void **retval)
 {
+	struct acpi_device *dev;
+
+	if (!strcmp(ctx, "SENR")) {
+		if (acpi_bus_get_device(ah, &dev))
+			return AE_OK;
+		if (!strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev)))
+			return AE_OK;
+	} else
+		return AE_OK;
+
 	*(acpi_handle *)retval = ah;
-	return AE_OK;
+
+	return AE_CTRL_TERMINATE;
 }
 
 static int __init acer_wmi_get_handle(const char *name, const char *prop,
@@ -1891,7 +1904,7 @@ static int __init acer_wmi_accel_setup(void)
 {
 	int err;
 
-	err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle);
+	err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle);
 	if (err)
 		return err;
 
@@ -2262,10 +2275,11 @@ static int __init acer_wmi_init(void)
 		err = acer_wmi_input_setup();
 		if (err)
 			return err;
+		err = acer_wmi_accel_setup();
+		if (err)
+			return err;
 	}
 
-	acer_wmi_accel_setup();
-
 	err = platform_driver_register(&acer_platform_driver);
 	if (err) {
 		pr_err("Unable to register platform driver\n");
Signature · 1 line
2.12.2
author
#39 lore raw

PATCH 39/86 mm: Tighten x86 /dev/mem with zeroing reads

In reply to Jiri Slaby

From: Kees Cook <[email protected]>

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

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

commit a4866aa812518ed1a37d8ea0c881dc946409de94 upstream.

Under CONFIG_STRICT_DEVMEM, reading System RAM through /dev/mem is disallowed. However, on x86, the first 1MB was always allowed for BIOS and similar things, regardless of it actually being System RAM. It was possible for heap to end up getting allocated in low 1MB RAM, and then read by things like x86info or dd, which would trip hardened usercopy:

usercopy: kernel memory exposure attempt detected from ffff880000090000 (dma-kmalloc-256) (4096 bytes)

This changes the x86 exception for the low 1MB by reading back zeros for System RAM areas instead of blindly allowing them. More work is needed to extend this to mmap, but currently mmap doesn't go through usercopy, so hardened usercopy won't Oops the kernel.

---
 arch/x86/mm/init.c | 41 +++++++++++++++++++--------
 drivers/char/mem.c | 82 ++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 82 insertions(+), 41 deletions(-)
arch/x86/mm/init.c +30 -11
index 04664cdb7fda..bee0b8b77beb 100644
@@ -475,21 +475,40 @@ void __init init_mem_mapping(void)
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address
  * is valid. The argument is a physical page number.
  *
- *
- * On x86, access has to be given to the first megabyte of ram because that area
- * contains bios code and data regions used by X and dosemu and similar apps.
- * Access has to be given to non-kernel-ram areas as well, these contain the PCI
- * mmio resources as well as potential bios/acpi data regions.
+ * On x86, access has to be given to the first megabyte of RAM because that
+ * area traditionally contains BIOS code and data regions used by X, dosemu,
+ * and similar apps. Since they map the entire memory range, the whole range
+ * must be allowed (for mapping), but any areas that would otherwise be
+ * disallowed are flagged as being "zero filled" instead of rejected.
+ * Access has to be given to non-kernel-ram areas as well, these contain the
+ * PCI mmio resources as well as potential bios/acpi data regions.
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-	if (pagenr < 256)
-		return 1;
-	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
+	if (page_is_ram(pagenr)) {
+		/*
+		 * For disallowed memory regions in the low 1MB range,
+		 * request that the page be shown as all zeros.
+		 */
+		if (pagenr < 256)
+			return 2;
+
+		return 0;
+	}
+
+	/*
+	 * This must follow RAM test, since System RAM is considered a
+	 * restricted resource under CONFIG_STRICT_IOMEM.
+	 */
+	if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) {
+		/* Low 1MB bypasses iomem restrictions. */
+		if (pagenr < 256)
+			return 1;
+
 		return 0;
-	if (!page_is_ram(pagenr))
-		return 1;
-	return 0;
+	}
+
+	return 1;
 }
 
 void free_init_pages(char *what, unsigned long begin, unsigned long end)
drivers/char/mem.c +52 -30

117 lines not on this page · raw message

Signature · 1 line
2.12.2
author
#40 lore raw

PATCH 40/86 virtio-console: avoid DMA from stack

In reply to Jiri Slaby

From: Omar Sandoval <[email protected]>

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

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

commit c4baad50297d84bde1a7ad45e50c73adae4a2192 upstream.

put_chars() stuffs the buffer it gets into an sg, but that buffer may be on the stack. This breaks with CONFIG_VMAP_STACK=y (for me, it manifested as printks getting turned into NUL bytes).

---
 drivers/char/virtio_console.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/char/virtio_console.c +10 -2
index 15a3ec940723..55d8b073cc61 100644
@@ -1130,6 +1130,8 @@ static int put_chars(u32 vtermno, const char *buf, int count)
 {
 	struct port *port;
 	struct scatterlist sg[1];
+	void *data;
+	int ret;
 
 	if (unlikely(early_put_chars))
 		return early_put_chars(vtermno, buf, count);
@@ -1138,8 +1140,14 @@ static int put_chars(u32 vtermno, const char *buf, int count)
 	if (!port)
 		return -EPIPE;
 
-	sg_init_one(sg, buf, count);
-	return __send_to_port(port, sg, 1, count, (void *)buf, false);
+	data = kmemdup(buf, count, GFP_ATOMIC);
+	if (!data)
+		return -ENOMEM;
+
+	sg_init_one(sg, data, count);
+	ret = __send_to_port(port, sg, 1, count, data, false);
+	kfree(data);
+	return ret;
 }
 
 /*
Signature · 1 line
2.12.2
author
#41 lore raw

PATCH 41/86 pegasus: Use heap buffers for all register access

In reply to Jiri Slaby

From: Ben Hutchings <[email protected]>

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

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

commit 5593523f968bc86d42a035c6df47d5e0979b5ace upstream.

Allocating USB buffers on the stack is not portable, and no longer works on x86_64 (with VMAP_STACK enabled as per default).

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")

References: https://bugs.debian.org/852556

---
 drivers/net/usb/pegasus.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)
drivers/net/usb/pegasus.c +25 -4
index 03e8a15d7deb..f32a57ed1d13 100644
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)
 
 static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmalloc(size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
-			      indx, data, size, 1000);
+			      indx, buf, size, 1000);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	else if (ret <= size)
+		memcpy(data, buf, ret);
+	kfree(buf);
 	return ret;
 }
 
-static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
+static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
+			 const void *data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmemdup(data, size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
-			      indx, data, size, 100);
+			      indx, buf, size, 100);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	kfree(buf);
 	return ret;
 }
 
 static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmemdup(&data, 1, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
-			      indx, &data, 1, 1000);
+			      indx, buf, 1, 1000);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	kfree(buf);
 	return ret;
 }
 
Signature · 1 line
2.12.2
author
#42 lore raw

PATCH 42/86 rtl8150: Use heap buffers for all register access

In reply to Jiri Slaby

From: Ben Hutchings <[email protected]>

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

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

commit 7926aff5c57b577ab0f43364ff0c59d968f6a414 upstream.

Allocating USB buffers on the stack is not portable, and no longer works on x86_64 (with VMAP_STACK enabled as per default).

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc Brad Spengler <[email protected]>
---
 drivers/net/usb/rtl8150.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)
drivers/net/usb/rtl8150.c +27 -7
index 6cbdac67f3a0..59d6a3a5830a 100644
@@ -156,16 +156,36 @@ static const char driver_name [] = "rtl8150";
 */
 static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
 {
-	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
-			       RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
-			       indx, 0, data, size, 500);
+	void *buf;
+	int ret;
+
+	buf = kmalloc(size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+			      RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
+			      indx, 0, buf, size, 500);
+	if (ret > 0 && ret <= size)
+		memcpy(data, buf, ret);
+	kfree(buf);
+	return ret;
 }
 
-static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
+static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
 {
-	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
-			       RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
-			       indx, 0, data, size, 500);
+	void *buf;
+	int ret;
+
+	buf = kmemdup(data, size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+			      RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
+			      indx, 0, buf, size, 500);
+	kfree(buf);
+	return ret;
 }
 
 static void async_set_reg_cb(struct urb *urb)
Signature · 1 line
2.12.2
author
#43 lore raw

PATCH 43/86 catc: Combine failure cleanup code in catc_probe()

In reply to Jiri Slaby

From: Ben Hutchings <[email protected]>

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

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

commit d41149145f98fe26dcd0bfd1d6cc095e6e041418 upstream.

---
 drivers/net/usb/catc.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)
drivers/net/usb/catc.c +17 -16
index 8d5cac2d8e33..bf6e083a9574 100644
@@ -779,7 +779,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 	struct net_device *netdev;
 	struct catc *catc;
 	u8 broadcast[6];
-	int i, pktsz;
+	int i, pktsz, ret;
 
 	if (usb_set_interface(usbdev,
 			intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -814,12 +814,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 	if ((!catc->ctrl_urb) || (!catc->tx_urb) || 
 	    (!catc->rx_urb) || (!catc->irq_urb)) {
 		dev_err(&intf->dev, "No free urbs available.\n");
-		usb_free_urb(catc->ctrl_urb);
-		usb_free_urb(catc->tx_urb);
-		usb_free_urb(catc->rx_urb);
-		usb_free_urb(catc->irq_urb);
-		free_netdev(netdev);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto fail_free;
 	}
 
 	/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
@@ -916,16 +912,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 	usb_set_intfdata(intf, catc);
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
-	if (register_netdev(netdev) != 0) {
-		usb_set_intfdata(intf, NULL);
-		usb_free_urb(catc->ctrl_urb);
-		usb_free_urb(catc->tx_urb);
-		usb_free_urb(catc->rx_urb);
-		usb_free_urb(catc->irq_urb);
-		free_netdev(netdev);
-		return -EIO;
-	}
+	ret = register_netdev(netdev);
+	if (ret)
+		goto fail_clear_intfdata;
+
 	return 0;
+
+fail_clear_intfdata:
+	usb_set_intfdata(intf, NULL);
+fail_free:
+	usb_free_urb(catc->ctrl_urb);
+	usb_free_urb(catc->tx_urb);
+	usb_free_urb(catc->rx_urb);
+	usb_free_urb(catc->irq_urb);
+	free_netdev(netdev);
+	return ret;
 }
 
 static void catc_disconnect(struct usb_interface *intf)
Signature · 1 line
2.12.2
author
#44 lore raw

PATCH 44/86 catc: Use heap buffer for memory size test

In reply to Jiri Slaby

From: Ben Hutchings <[email protected]>

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

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

commit 2d6a0e9de03ee658a9adc3bfb2f0ca55dff1e478 upstream.

Allocating USB buffers on the stack is not portable, and no longer works on x86_64 (with VMAP_STACK enabled as per default).

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc Brad Spengler <[email protected]>
---
 drivers/net/usb/catc.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/net/usb/catc.c +18 -7
index bf6e083a9574..57da4c10c695 100644
@@ -779,7 +779,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 	struct net_device *netdev;
 	struct catc *catc;
 	u8 broadcast[6];
-	int i, pktsz, ret;
+	int pktsz, ret;
 
 	if (usb_set_interface(usbdev,
 			intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -843,15 +843,24 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
                 catc->irq_buf, 2, catc_irq_done, catc, 1);
 
 	if (!catc->is_f5u011) {
+		u32 *buf;
+		int i;
+
 		dev_dbg(dev, "Checking memory size\n");
 
-		i = 0x12345678;
-		catc_write_mem(catc, 0x7a80, &i, 4);
-		i = 0x87654321;	
-		catc_write_mem(catc, 0xfa80, &i, 4);
-		catc_read_mem(catc, 0x7a80, &i, 4);
+		buf = kmalloc(4, GFP_KERNEL);
+		if (!buf) {
+			ret = -ENOMEM;
+			goto fail_free;
+		}
+
+		*buf = 0x12345678;
+		catc_write_mem(catc, 0x7a80, buf, 4);
+		*buf = 0x87654321;
+		catc_write_mem(catc, 0xfa80, buf, 4);
+		catc_read_mem(catc, 0x7a80, buf, 4);
 	  
-		switch (i) {
+		switch (*buf) {
 		case 0x12345678:
 			catc_set_reg(catc, TxBufCount, 8);
 			catc_set_reg(catc, RxBufCount, 32);
@@ -866,6 +875,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 			dev_dbg(dev, "32k Memory\n");
 			break;
 		}
+
+		kfree(buf);
 	  
 		dev_dbg(dev, "Getting MAC from SEEROM.\n");
 	  
Signature · 1 line
2.12.2
author
#45 lore raw

PATCH 45/86 net: ipv6: check route protocol when deleting routes

In reply to Jiri Slaby

From: Mantas M <[email protected]>

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

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

commit c2ed1880fd61a998e3ce40254a99a2ad000f1a7d upstream.

The protocol field is checked when deleting IPv4 routes, but ignored for IPv6, which causes problems with routing daemons accidentally deleting externally set routes (observed by multiple bird6 users).

This can be verified using ip -6 route del <prefix> proto something.

---
 net/ipv6/route.c | 2 ++
 1 file changed, 2 insertions(+)
net/ipv6/route.c +2 -0
index e19817a090c7..a4238c684a91 100644
@@ -1754,6 +1754,8 @@ static int ip6_route_del(struct fib6_config *cfg)
 				continue;
 			if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
 				continue;
+			if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol)
+				continue;
 			dst_hold(&rt->dst);
 			read_unlock_bh(&table->tb6_lock);
 
Signature · 1 line
2.12.2
author
#46 lore raw

PATCH 46/86 KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings

In reply to Jiri Slaby

From: David Howells <[email protected]>

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

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

commit ee8f844e3c5a73b999edf733df1c529d6503ec2f upstream.

This fixes CVE-2016-9604.

Keyrings whose name begin with a '.' are special internal keyrings and so userspace isn't allowed to create keyrings by this name to prevent shadowing. However, the patch that added the guard didn't fix KEYCTL_JOIN_SESSION_KEYRING. Not only can that create dot-named keyrings, it can also subscribe to them as a session keyring if they grant SEARCH permission to the user.

This, for example, allows a root process to set .builtin_trusted_keys as its session keyring, at which point it has full access because now the possessor permissions are added. This permits root to add extra public keys, thereby bypassing module verification.

This also affects kexec and IMA.

This can be tested by (as root):

keyctl session .builtin_trusted_keys
keyctl add user a a @s
keyctl list @s

which on my test box gives me:

	2 keys in keyring:
	180010936: ---lswrv     0     0 asymmetric: Build time autogenerated kernel key: ae3d4a31b82daa8e1a75b49dc2bba949fd992a05
	801382539: --alswrv     0     0 user: a

Fix this by rejecting names beginning with a '.' in the keyctl.

---
 security/keys/keyctl.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
security/keys/keyctl.c +7 -2
index 3242195bfa95..1324b2e10286 100644
@@ -271,7 +271,8 @@ error:
  * Create and join an anonymous session keyring or join a named session
  * keyring, creating it if necessary.  A named session keyring must have Search
  * permission for it to be joined.  Session keyrings without this permit will
- * be skipped over.
+ * be skipped over.  It is not permitted for userspace to create or join
+ * keyrings whose name begin with a dot.
  *
  * If successful, the ID of the joined session keyring will be returned.
  */
@@ -288,12 +289,16 @@ long keyctl_join_session_keyring(const char __user *_name)
 			ret = PTR_ERR(name);
 			goto error;
 		}
+
+		ret = -EPERM;
+		if (name[0] == '.')
+			goto error_name;
 	}
 
 	/* join the session */
 	ret = join_session_keyring(name);
+error_name:
 	kfree(name);
-
 error:
 	return ret;
 }
Signature · 1 line
2.12.2
author
#47 lore raw

PATCH 47/86 KEYS: Change the name of the dead type to ".dead" to prevent user access

In reply to Jiri Slaby

From: David Howells <[email protected]>

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

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

commit c1644fe041ebaf6519f6809146a77c3ead9193af upstream.

This fixes CVE-2017-6951.

Userspace should not be able to do things with the "dead" key type as it doesn't have some of the helper functions set upon it that the kernel needs. Attempting to use it may cause the kernel to crash.

Fix this by changing the name of the type to ".dead" so that it's rejected up front on userspace syscalls by key_get_type_from_user().

Though this doesn't seem to affect recent kernels, it does affect older ones, certainly those prior to:

	commit c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81
	Author: David Howells <[email protected]>
	Date:   Tue Sep 16 17:36:06 2014 +0100
	KEYS: Remove key_type::match in favour of overriding default by match_preparse

which went in before 3.18-rc1.

---
 security/keys/gc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
security/keys/gc.c +1 -1
index de34c290bd6f..2e01e23295aa 100644
@@ -46,7 +46,7 @@ static unsigned long key_gc_flags;
  * immediately unlinked.
  */
 struct key_type key_type_dead = {
-	.name = "dead",
+	.name = ".dead",
 };
 
 /*
Signature · 1 line
2.12.2
author
#48 lore raw

PATCH 48/86 KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings

In reply to Jiri Slaby

From: Eric Biggers <[email protected]>

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

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

commit c9f838d104fed6f2f61d68164712e3204bf5271b upstream.

This fixes CVE-2017-7472.

Running the following program as an unprivileged user exhausts kernel memory by leaking thread keyrings:

	#include <keyutils.h>

	int main()
	{
		for (;;)
			keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_THREAD_KEYRING);
	}

Fix it by only creating a new thread keyring if there wasn't one before. To make things more consistent, make install_thread_keyring_to_cred() and install_process_keyring_to_cred() both return 0 if the corresponding keyring is already present.

Fixes d84f4f992cbd ("CRED: Inaugurate COW credentials")
---
 security/keys/keyctl.c       | 11 ++++-------
 security/keys/process_keys.c | 44 +++++++++++++++++++++++++++-----------------
 2 files changed, 31 insertions(+), 24 deletions(-)
security/keys/keyctl.c +4 -7
index 1324b2e10286..066baa1926bb 100644
@@ -1245,8 +1245,8 @@ error:
  * Read or set the default keyring in which request_key() will cache keys and
  * return the old setting.
  *
- * If a process keyring is specified then this will be created if it doesn't
- * yet exist.  The old setting will be returned if successful.
+ * If a thread or process keyring is specified then it will be created if it
+ * doesn't yet exist.  The old setting will be returned if successful.
  */
 long keyctl_set_reqkey_keyring(int reqkey_defl)
 {
@@ -1271,11 +1271,8 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
 
 	case KEY_REQKEY_DEFL_PROCESS_KEYRING:
 		ret = install_process_keyring_to_cred(new);
-		if (ret < 0) {
-			if (ret != -EEXIST)
-				goto error;
-			ret = 0;
-		}
+		if (ret < 0)
+			goto error;
 		goto set;
 
 	case KEY_REQKEY_DEFL_DEFAULT:
security/keys/process_keys.c +27 -17

105 lines not on this page · raw message

Signature · 1 line
2.12.2
author
#49 lore raw

PATCH 49/86 tracing: Allocate the snapshot buffer before enabling probe

In reply to Jiri Slaby

From: "Steven Rostedt (VMware)" <[email protected]>

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

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

commit df62db5be2e5f070ecd1a5ece5945b590ee112e0 upstream.

Currently the snapshot trigger enables the probe and then allocates the snapshot. If the probe triggers before the allocation, it could cause the snapshot to fail and turn tracing off. It's best to allocate the snapshot buffer first, and then enable the trigger. If something goes wrong in the enabling of the trigger, the snapshot buffer is still allocated, but it can also be freed by the user by writting zero into the snapshot buffer file.

Also add a check of the return status of alloc_snapshot().

Fixes 77fd5c15e3 ("tracing: Add snapshot trigger to function probes")
---
 kernel/trace/trace.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
kernel/trace/trace.c +5 -3
index 174b9a6feea3..dbd488daec33 100644
@@ -5479,11 +5479,13 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash,
 		return ret;
 
  out_reg:
-	ret = register_ftrace_function_probe(glob, ops, count);
+	ret = alloc_snapshot(&global_trace);
+	if (ret < 0)
+		goto out;
 
-	if (ret >= 0)
-		alloc_snapshot(&global_trace);
+	ret = register_ftrace_function_probe(glob, ops, count);
 
+ out:
 	return ret < 0 ? ret : 0;
 }
 
Signature · 1 line
2.12.2
author
#50 lore raw

PATCH 50/86 ring-buffer: Have ring_buffer_iter_empty() return true when empty

In reply to Jiri Slaby

From: "Steven Rostedt (VMware)" <[email protected]>

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

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

commit 78f7a45dac2a2d2002f98a3a95f7979867868d73 upstream.

I noticed that reading the snapshot file when it is empty no longer gives a status. It suppose to show the status of the snapshot buffer as well as how to allocate and use it. For example:

Quoted 1 line
# cat snapshot

# tracer: nop
#
#
# * Snapshot is allocated *
#
# Snapshot commands:

 # echo 0 > snapshot : Clears and frees snapshot buffer
 # echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.
 #                      Takes a snapshot of the main buffer.
 # echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)
 #                      (Doesn't have to be '2' works with any number that
 #                       is not a '0' or '1')

But instead it just showed an empty buffer:

Quoted 1 line
# cat snapshot

# tracer: nop
#
# entries-in-buffer/entries-written: 0/0 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched

 #                            | / _---=> hardirq/softirq
 #                            || / _--=> preempt-depth
 #                            ||| /     delay
 #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
 #              | |       |   ||||       |         |

What happened was that it was using the ring_buffer_iter_empty() function to see if it was empty, and if it was, it showed the status. But that function was returning false when it was empty. The reason was that the iter header page was on the reader page, and the reader page was empty, but so was the buffer itself. The check only tested to see if the iter was on the commit page, but the commit page was no longer pointing to the reader page, but as all pages were empty, the buffer is also.

Fixes 651e22f2701b ("ring-buffer: Always reset iterator to reader page")
---
 kernel/trace/ring_buffer.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
kernel/trace/ring_buffer.c +14 -2
index 579821bd2484..c31467a6c853 100644
@@ -3387,11 +3387,23 @@ EXPORT_SYMBOL_GPL(ring_buffer_iter_reset);
 int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
+	struct buffer_page *reader;
+	struct buffer_page *head_page;
+	struct buffer_page *commit_page;
+	unsigned commit;
 
 	cpu_buffer = iter->cpu_buffer;
 
-	return iter->head_page == cpu_buffer->commit_page &&
-		iter->head == rb_commit_index(cpu_buffer);
+	/* Remember, trace recording is off when iterator is in use */
+	reader = cpu_buffer->reader_page;
+	head_page = cpu_buffer->head_page;
+	commit_page = cpu_buffer->commit_page;
+	commit = rb_page_commit(commit_page);
+
+	return ((iter->head_page == commit_page && iter->head == commit) ||
+		(iter->head_page == reader && commit_page == head_page &&
+		 head_page->read == commit &&
+		 iter->head == rb_page_commit(cpu_buffer->reader_page)));
 }
 EXPORT_SYMBOL_GPL(ring_buffer_iter_empty);
 
Signature · 1 line
2.12.2
author
#51 lore raw

PATCH 51/86 cifs: Do not send echoes before Negotiate is complete

In reply to Jiri Slaby

From: Sachin Prabhu <[email protected]>

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

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

commit 62a6cfddcc0a5313e7da3e8311ba16226fe0ac10 upstream.

commit 4fcd1813e640 ("Fix reconnect to not defer smb3 session reconnect long after socket reconnect") added support for Negotiate requests to be initiated by echo calls.

To avoid delays in calling echo after a reconnect, I added the patch introduced by the commit b8c600120fc8 ("Call echo service immediately after socket reconnect").

This has however caused a regression with cifs shares which do not have support for echo calls to trigger Negotiate requests. On connections which need to call Negotiation, the echo calls trigger an error which triggers a reconnect which in turn triggers another echo call. This results in a loop which is only broken when an operation is performed on the cifs share. For an idle share, it can DOS a server.

The patch uses the smb_operation can_echo() for cifs so that it is called only if connection has been already been setup.

kernel bz: 194531

---
 fs/cifs/smb1ops.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
fs/cifs/smb1ops.c +10 -0
index 09b0323a7727..a05375be8ac2 100644
@@ -953,6 +953,15 @@ cifs_dir_needs_close(struct cifsFileInfo *cfile)
 	return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
 }
 
+static bool
+cifs_can_echo(struct TCP_Server_Info *server)
+{
+	if (server->tcpStatus == CifsGood)
+		return true;
+
+	return false;
+}
+
 struct smb_version_operations smb1_operations = {
 	.send_cancel = send_nt_cancel,
 	.compare_fids = cifs_compare_fids,
@@ -986,6 +995,7 @@ struct smb_version_operations smb1_operations = {
 	.get_dfs_refer = CIFSGetDFSRefer,
 	.qfs_tcon = cifs_qfs_tcon,
 	.is_path_accessible = cifs_is_path_accessible,
+	.can_echo = cifs_can_echo,
 	.query_path_info = cifs_query_path_info,
 	.query_file_info = cifs_query_file_info,
 	.get_srv_inum = cifs_get_srv_inum,
Signature · 1 line
2.12.2
author
#52 lore raw

PATCH 52/86 CIFS: remove bad_network_name flag

In reply to Jiri Slaby

From: Germano Percossi <[email protected]>

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

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

commit a0918f1ce6a43ac980b42b300ec443c154970979 upstream.

STATUS_BAD_NETWORK_NAME can be received during node failover, causing the flag to be set and making the reconnect thread always unsuccessful, thereafter.

Once the only place where it is set is removed, the remaining bits are rendered moot.

Removing it does not prevent "mount" from failing when a non existent share is passed.

What happens when the share really ceases to exist while the share is mounted is undefined now as much as it was before.

---
 fs/cifs/cifsglob.h | 1 -
 fs/cifs/smb2pdu.c  | 5 -----
 2 files changed, 6 deletions(-)
fs/cifs/cifsglob.h +0 -1
index 4b87feaa507f..1472ee04cadd 100644
@@ -837,7 +837,6 @@ struct cifs_tcon {
 	bool need_reconnect:1; /* connection reset, tid now invalid */
 #ifdef CONFIG_CIFS_SMB2
 	bool print:1;		/* set if connection to printer share */
-	bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
 	__le32 capabilities;
 	__u32 share_flags;
 	__u32 maximal_access;
fs/cifs/smb2pdu.c +0 -5
index c7a400415d02..79db9c46ada9 100644
@@ -839,9 +839,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
 	else
 		return -EIO;
 
-	if (tcon && tcon->bad_network_name)
-		return -ENOENT;
-
 	unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
 	if (unc_path == NULL)
 		return -ENOMEM;
@@ -935,8 +932,6 @@ tcon_exit:
 tcon_error_exit:
 	if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
 		cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
-		if (tcon)
-			tcon->bad_network_name = true;
 	}
 	goto tcon_exit;
 }
Signature · 1 line
2.12.2
author
#53 lore raw

PATCH 53/86 Drivers: hv: don't leak memory in vmbus_establish_gpadl()

In reply to Jiri Slaby

From: Vitaly Kuznetsov <[email protected]>

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

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

commit 7cc80c98070ccc7940fc28811c92cca0a681015d upstream.

In some cases create_gpadl_header() allocates submessages but we never free them.

[sumits] Note for stable:
Upstream commit 4d63763296ab7865a98bc29cc7d77145815ef89f:
(Drivers: hv: get rid of redundant messagecount in create_gpadl_header()) changes the list usage to initialize list header in all cases; that patch isn't added to stable, so the current patch is modified a little bit from the upstream commit to check if the list is valid or not.

---
 drivers/hv/channel.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/hv/channel.c +8 -1
index 120237a90a86..8cddbd10dadb 100644
@@ -403,7 +403,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
 	struct vmbus_channel_gpadl_header *gpadlmsg;
 	struct vmbus_channel_gpadl_body *gpadl_body;
 	struct vmbus_channel_msginfo *msginfo = NULL;
-	struct vmbus_channel_msginfo *submsginfo;
+	struct vmbus_channel_msginfo *submsginfo, *tmp;
 	u32 msgcount;
 	struct list_head *curr;
 	u32 next_gpadl_handle;
@@ -465,6 +465,13 @@ cleanup:
 	list_del(&msginfo->msglistentry);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
+	if (msgcount > 1) {
+		list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist,
+			 msglistentry) {
+			kfree(submsginfo);
+		}
+	}
+
 	kfree(msginfo);
 	return ret;
 }
Signature · 1 line
2.12.2
author
#54 lore raw

PATCH 54/86 Drivers: hv: get rid of timeout in vmbus_open()

In reply to Jiri Slaby

From: Vitaly Kuznetsov <[email protected]>

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

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

commit 396e287fa2ff46e83ae016cdcb300c3faa3b02f6 upstream.

vmbus_teardown_gpadl() can result in infinite wait when it is called on 5 second timeout in vmbus_open(). The issue is caused by the fact that gpadl teardown operation won't ever succeed for an opened channel and the timeout isn't always enough. As a guest, we can always trust the host to respond to our request (and there is nothing we can do if it doesn't).

---
 drivers/hv/channel.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/hv/channel.c +2 -6
index 8cddbd10dadb..6f1731573097 100644
@@ -114,7 +114,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 	struct vmbus_channel_msginfo *open_info = NULL;
 	void *in, *out;
 	unsigned long flags;
-	int ret, t, err = 0;
+	int ret, err = 0;
 
 	spin_lock_irqsave(&newchannel->sc_lock, flags);
 	if (newchannel->state == CHANNEL_OPEN_STATE) {
@@ -213,11 +213,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 		goto error1;
 	}
 
-	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
-	if (t == 0) {
-		err = -ETIMEDOUT;
-		goto error1;
-	}
+	wait_for_completion(&open_info->waitevent);
 
 
 	if (open_info->response.open_result.status)
Signature · 1 line
2.12.2
author
#55 lore raw

PATCH 55/86 Input: elantech - add Fujitsu Lifebook E547 to force crc_enabled

In reply to Jiri Slaby

From: Thorsten Leemhuis <[email protected]>

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

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

commit 704de489e0e3640a2ee2d0daf173e9f7375582ba upstream.

Temporary got a Lifebook E547 into my hands and noticed the touchpad only works after running:

	echo "1" > /sys/devices/platform/i8042/serio2/crc_enabled

Add it to the list of machines that need this workaround.

---
 drivers/input/mouse/elantech.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/input/mouse/elantech.c +8 -0
index a25fc40522f3..05453836edc7 100644
@@ -1036,6 +1036,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
  * Asus UX32VD             0x361f02        00, 15, 0e      clickpad
  * Avatar AVIU-145A2       0x361f00        ?               clickpad
  * Fujitsu LIFEBOOK E544   0x470f00        d0, 12, 09      2 hw buttons
+ * Fujitsu LIFEBOOK E547   0x470f00        50, 12, 09      2 hw buttons
  * Fujitsu LIFEBOOK E554   0x570f01        40, 14, 0c      2 hw buttons
  * Gigabyte U2442          0x450f01        58, 17, 0c      2 hw buttons
  * Lenovo L430             0x350f02        b9, 15, 0c      2 hw buttons (*)
@@ -1403,6 +1404,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
 		},
 	},
 	{
+		/* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E547"),
+		},
+	},
+	{
 		/* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
Signature · 1 line
2.12.2
author
#56 lore raw

PATCH 56/86 ACPI / power: Avoid maybe-uninitialized warning

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit fe8c470ab87d90e4b5115902dd94eced7e3305c3 upstream.

gcc -O2 cannot always prove that the loop in acpi_power_get_inferred_state() is enterered at least once, so it assumes that cur_state might not get initialized:

drivers/acpi/power.c: In function 'acpi_power_get_inferred_state':
drivers/acpi/power.c:222:9: error: 'cur_state' may be used uninitialized in this function [-Werror=maybe-uninitialized]

This sets the variable to zero at the start of the loop, to ensure that there is well-defined behavior even for an empty list. This gets rid of the warning.

The warning first showed up when the -Os flag got removed in a bug fix patch in linux-4.11-rc5.

I would suggest merging this addon patch on top of that bug fix to avoid introducing a new warning in the stable kernels.

Fixes 61b79e16c68d (ACPI: Fix incompatibility with mcount-based function graph tracing)
---
 drivers/acpi/power.c | 1 +
 1 file changed, 1 insertion(+)
drivers/acpi/power.c +1 -0
index c2ad391d8041..4b35a115749c 100644
@@ -204,6 +204,7 @@ static int acpi_power_get_list_state(struct list_head *list, int *state)
 		return -EINVAL;
 
 	/* The state of the list is 'on' IFF all resources are 'on'. */
+	cur_state = 0;
 	list_for_each_entry(entry, list, node) {
 		struct acpi_power_resource *resource = entry->resource;
 		acpi_handle handle = resource->device.handle;
Signature · 1 line
2.12.2
author
#57 lore raw

PATCH 57/86 ubi/upd: Always flush after prepared for an update

In reply to Jiri Slaby

From: Sebastian Siewior <[email protected]>

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

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

commit 9cd9a21ce070be8a918ffd3381468315a7a76ba6 upstream.

In commit 6afaf8a484cb ("UBI: flush wl before clearing update marker") I managed to trigger and fix a similar bug. Now here is another version of which I assumed it wouldn't matter back then but it turns out UBI has a check for it and will error out like this:

|ubi0 warning: validate_vid_hdr: inconsistent used_ebs |ubi0 error: validate_vid_hdr: inconsistent VID header at PEB 592

All you need to trigger this is? "ubiupdatevol /dev/ubi0_0 file" + a powercut in the middle of the operation.
ubi_start_update() sets the update-marker and puts all EBs on the erase list. After that userland can proceed to write new data while the old EB aren't erased completely. A powercut at this point is usually not that much of a tragedy. UBI won't give read access to the static volume because it has the update marker. It will most likely set the corrupted flag because it misses some EBs.
So we are all good. Unless the size of the image that has been written differs from the old image in the magnitude of at least one EB. In that case UBI will find two different values for `used_ebs' and refuse to attach the image with the error message mentioned above.

So in order not to get in the situation, the patch will ensure that we wait until everything is removed before it tries to write any data. The alternative would be to detect such a case and remove all EBs at the attached time after we processed the volume-table and see the update-marker set. The patch looks bigger and I doubt it is worth it since usually the write() will wait from time to time for a new EB since usually there not that many spare EB that can be used.

---
 drivers/mtd/ubi/upd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mtd/ubi/upd.c +4 -4
index 0134ba32a057..39712560b4c1 100644
@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
 			return err;
 	}
 
-	if (bytes == 0) {
-		err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
-		if (err)
-			return err;
+	err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
+	if (err)
+		return err;
 
+	if (bytes == 0) {
 		err = clear_update_marker(ubi, vol, 0);
 		if (err)
 			return err;
Signature · 1 line
2.12.2
author
#58 lore raw

PATCH 58/86 x86/mce/AMD: Give a name to MCA bank 3 when accessed with legacy MSRs

In reply to Jiri Slaby

From: Yazen Ghannam <[email protected]>

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

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

commit 29f72ce3e4d18066ec75c79c857bee0618a3504b upstream.

MCA bank 3 is reserved on systems pre-Fam17h, so it didn't have a name. However, MCA bank 3 is defined on Fam17h systems and can be accessed using legacy MSRs. Without a name we get a stack trace on Fam17h systems when trying to register sysfs files for bank 3 on kernels that don't recognize Scalable MCA.

Call MCA bank 3 "decode_unit" since this is what it represents on Fam17h. This will allow kernels without SMCA support to see this bank on Fam17h+ and prevent the stack trace. This will not affect older systems since this bank is reserved on them, i.e. it'll be ignored.

Tested on AMD Fam15h and Fam17h systems.

  WARNING: CPU: 26 PID: 1 at lib/kobject.c:210 kobject_add_internal
  kobject: (ffff88085bb256c0): attempted to be registered with empty name!
  ...
  Call Trace:
   kobject_add_internal
   kobject_add
   kobject_create_and_add
   threshold_create_device
   threshold_init_device
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/mcheck/mce_amd.c +1 -1
index 603df4f74640..0c05ab602815 100644
@@ -51,7 +51,7 @@ static const char * const th_names[] = {
 	"load_store",
 	"insn_fetch",
 	"combined_unit",
-	"",
+	"decode_unit",
 	"northbridge",
 	"execution_unit",
 };
Signature · 1 line
2.12.2
author
#59 lore raw

PATCH 59/86 kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd

In reply to Jiri Slaby

From: Suzuki K Poulose <[email protected]>

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

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

commit 8b3405e345b5a098101b0c31b264c812bba045d9 upstream.

In kvm_free_stage2_pgd() we don't hold the kvm->mmu_lock while calling unmap_stage2_range() on the entire memory range for the guest. This could cause problems with other callers (e.g, munmap on a memslot) trying to unmap a range. And since we have to unmap the entire Guest memory range holding a spinlock, make sure we yield the lock if necessary, after we unmap each PUD range.

[skp] provided backport for 3.12

Fixes commit d5d8184d35c9 ("KVM: ARM: Memory virtualization setup")
Cc Paolo Bonzini <[email protected]>
Cc Marc Zyngier <[email protected]>
Cc Christoffer Dall <[email protected]>
Cc Mark Rutland <[email protected]>
[ Avoid vCPU starvation and lockup detector warnings ]
---
 arch/arm/kvm/mmu.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/arm/kvm/mmu.c +12 -0
index 683cac91a7f6..84f18dc83532 100644
@@ -181,6 +181,14 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
 	do {
 		next = kvm_pgd_addr_end(addr, end);
 		unmap_puds(kvm, pgd, addr, next);
+		/*
+		 * If we are dealing with a large range in
+		 * stage2 table, release the kvm->mmu_lock
+		 * to prevent starvation and lockup detector
+		 * warnings.
+		 */
+		if (kvm && (next != end))
+			cond_resched_lock(&kvm->mmu_lock);
 	} while (pgd++, addr = next, addr != end);
 }
 
@@ -525,6 +533,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
  */
 static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
 {
+	assert_spin_locked(&kvm->mmu_lock);
 	unmap_range(kvm, kvm->arch.pgd, start, size);
 }
 
@@ -609,7 +618,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm)
 	if (kvm->arch.pgd == NULL)
 		return;
 
+	spin_lock(&kvm->mmu_lock);
 	unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
+	spin_unlock(&kvm->mmu_lock);
+
 	free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER);
 	kvm->arch.pgd = NULL;
 }
Signature · 1 line
2.12.2
author
#60 lore raw

PATCH 60/86 block: fix del_gendisk() vs blkdev_ioctl crash

In reply to Jiri Slaby

From: Dan Williams <[email protected]>

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

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

commit ac34f15e0c6d2fd58480052b6985f6991fb53bcc upstream.

When tearing down a block device early in its lifetime, userspace may still be performing discovery actions like blkdev_ioctl() to re-read partitions.

The nvdimm_revalidate_disk() implementation depends on disk->driverfs_dev to be valid at entry. However, it is set to NULL in del_gendisk() and fatally this is happening *before* the disk device is deleted from userspace view.

There's no reason for del_gendisk() to clear ->driverfs_dev. That device is the parent of the disk. It is guaranteed to not be freed until the disk, as a child, drops its ->parent reference.

We could also fix this issue locally in nvdimm_revalidate_disk() by using disk_to_dev(disk)->parent, but lets fix it globally since ->driverfs_dev follows the lifetime of the parent. Longer term we should probably just add a @parent parameter to add_disk(), and stop carrying this pointer in the gendisk.

 BUG: unable to handle kernel NULL pointer dereference at           (null)
 IP: [<ffffffffa00340a8>] nvdimm_revalidate_disk+0x18/0x90 [libnvdimm]
 CPU: 2 PID: 538 Comm: systemd-udevd Tainted: G           O    4.4.0-rc5 #2257
 [..]
 Call Trace:
  [<ffffffff8143e5c7>] rescan_partitions+0x87/0x2c0
  [<ffffffff810f37f9>] ? __lock_is_held+0x49/0x70
  [<ffffffff81438c62>] __blkdev_reread_part+0x72/0xb0
  [<ffffffff81438cc5>] blkdev_reread_part+0x25/0x40
  [<ffffffff8143982d>] blkdev_ioctl+0x4fd/0x9c0
  [<ffffffff811246c9>] ? current_kernel_time64+0x69/0xd0
  [<ffffffff812916dd>] block_ioctl+0x3d/0x50
  [<ffffffff81264c38>] do_vfs_ioctl+0x308/0x560
  [<ffffffff8115dbd1>] ? __audit_syscall_entry+0xb1/0x100
  [<ffffffff810031d6>] ? do_audit_syscall_entry+0x66/0x70
  [<ffffffff81264f09>] SyS_ioctl+0x79/0x90
  [<ffffffff81902672>] entry_SYSCALL_64_fastpath+0x12/0x76
---
 block/genhd.c | 1 -
 1 file changed, 1 deletion(-)
block/genhd.c +0 -1
index 38d4ba122a43..037cf3e8f1bd 100644
@@ -662,7 +662,6 @@ void del_gendisk(struct gendisk *disk)
 
 	kobject_put(disk->part0.holder_dir);
 	kobject_put(disk->slave_dir);
-	disk->driverfs_dev = NULL;
 	if (!sysfs_deprecated)
 		sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
 	pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
Signature · 1 line
2.12.2
author
#61 lore raw

PATCH 61/86 powerpc: Reject binutils 2.24 when building little endian

In reply to Jiri Slaby

From: Michael Ellerman <[email protected]>

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

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

commit 60e065f70bdb0b0e916389024922ad40f3270c96 upstream.

There is a bug in binutils 2.24 which causes miscompilation if we're building little endian and using weak symbols (which the kernel does).

It is fixed in binutils commit 57fa7b8c7e59 "Correct elf_merge_st_other arguments for weak symbols", which is in binutils 2.25 and has been backported to the binutils 2.24 branch and has been picked up by most distros it seems.

However if we're running stock 2.24 (no extra version) then the bug is present, so check for that and bail.

---
 arch/powerpc/Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)
arch/powerpc/Makefile +8 -0
index 994337bb529c..f45f740d5ccc 100644
@@ -289,6 +289,14 @@ checkbin:
 		echo 'disable kernel modules' ; \
 		false ; \
 	fi
+	@if test "x${CONFIG_CPU_LITTLE_ENDIAN}" = "xy" \
+	    && $(LD) --version | head -1 | grep ' 2\.24$$' >/dev/null ; then \
+		echo -n '*** binutils 2.24 miscompiles weak symbols ' ; \
+		echo 'in some circumstances.' ; \
+		echo -n '*** Please use a different binutils version.' ; \
+		false ; \
+	fi
+
 
 CLEAN_FILES += $(TOUT)
 
Signature · 1 line
2.12.2
author
#62 lore raw

PATCH 62/86 ping: implement proper locking

In reply to Jiri Slaby

From: Eric Dumazet <[email protected]>

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

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

commit 43a6684519ab0a6c52024b5e25322476cabad893 upstream.

We got a report of yet another bug in ping

http://www.openwall.com/lists/oss-security/2017/03/24/6

->disconnect() is not called with socket lock held.

Fix this by acquiring ping rwlock earlier.

Thanks to Daniel, Alexander and Andrey for letting us know this problem.

Fixes c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind")
---
 net/ipv4/ping.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
net/ipv4/ping.c +3 -2
index 6be49858c86f..3ec2f46cf8fc 100644
@@ -150,17 +150,18 @@ void ping_hash(struct sock *sk)
 void ping_unhash(struct sock *sk)
 {
 	struct inet_sock *isk = inet_sk(sk);
+
 	pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+	write_lock_bh(&ping_table.lock);
 	if (sk_hashed(sk)) {
-		write_lock_bh(&ping_table.lock);
 		hlist_nulls_del(&sk->sk_nulls_node);
 		sk_nulls_node_init(&sk->sk_nulls_node);
 		sock_put(sk);
 		isk->inet_num = 0;
 		isk->inet_sport = 0;
 		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
-		write_unlock_bh(&ping_table.lock);
 	}
+	write_unlock_bh(&ping_table.lock);
 }
 EXPORT_SYMBOL_GPL(ping_unhash);
 
Signature · 1 line
2.12.2
author
#63 lore raw

PATCH 63/86 net/packet: fix overflow in check for tp_frame_nr

In reply to Jiri Slaby

From: Andrey Konovalov <[email protected]>

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

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

commit 8f8d28e4d6d815a391285e121c3a53a0b6cb9e7b upstream.

When calculating rb->frames_per_block * req->tp_block_nr the result can overflow.

Add a check that tp_block_size * tp_block_nr <= UINT_MAX.

Since frames_per_block <= tp_block_size, the expression would never overflow.

---
 net/packet/af_packet.c | 2 ++
 1 file changed, 2 insertions(+)
net/packet/af_packet.c +2 -0
index ed1fed3330af..d6087b4359cc 100644
@@ -3665,6 +3665,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 		rb->frames_per_block = req->tp_block_size/req->tp_frame_size;
 		if (unlikely(rb->frames_per_block <= 0))
 			goto out;
+		if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr))
+			goto out;
 		if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
 					req->tp_frame_nr))
 			goto out;
Signature · 1 line
2.12.2
author
#64 lore raw

PATCH 64/86 net/packet: fix overflow in check for tp_reserve

In reply to Jiri Slaby

From: Andrey Konovalov <[email protected]>

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

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

commit bcc5364bdcfe131e6379363f089e7b4108d35b70 upstream.

When calculating po->tp_hdrlen + po->tp_reserve the result can overflow.

Fix by checking that tp_reserve <= INT_MAX on assign.

---
 net/packet/af_packet.c | 2 ++
 1 file changed, 2 insertions(+)
net/packet/af_packet.c +2 -0
index d6087b4359cc..2455f1b08ac3 100644
@@ -3167,6 +3167,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
+		if (val > INT_MAX)
+			return -EINVAL;
 		po->tp_reserve = val;
 		return 0;
 	}
Signature · 1 line
2.12.2
author
#65 lore raw

PATCH 65/86 netfilter: arp_tables: fix invoking 32bit "iptable -P INPUT ACCEPT" failed in 64bit kernel

In reply to Jiri Slaby

From: Hongxu Jia <[email protected]>

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

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

commit 17a49cd549d9dc8707dc9262210166455c612dde upstream.

Since 09d9686047db ("netfilter: x_tables: do compat validation via translate_table"), it used compatr structure to assign newinfo structure. In translate_compat_table of ip_tables.c and ip6_tables.c, it used compatr->hook_entry to replace info->hook_entry and compatr->underflow to replace info->underflow, but not do the same replacement in arp_tables.c.

It caused invoking 32-bit "arptbale -P INPUT ACCEPT" failed in 64bit kernel.
--------------------------------------

root@qemux86-64:~# arptables -P INPUT ACCEPT
root@qemux86-64:~# arptables -P INPUT ACCEPT
ERROR: Policy for `INPUT' offset 448 != underflow 0
arptables: Incompatible with this kernel
--------------------------------------
Fixes 09d9686047db ("netfilter: x_tables: do compat validation via translate_table")
---
 net/ipv4/netfilter/arp_tables.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv4/netfilter/arp_tables.c +2 -2
index ab16b5c195da..3e3b3f75b3a0 100644
@@ -1328,8 +1328,8 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 
 	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];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries[raw_smp_processor_id()];
 	pos = entry1;
Signature · 1 line
2.12.2
author
#66 lore raw

PATCH 66/86 tty: nozomi: avoid a harmless gcc warning

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit a4f642a8a3c2838ad09fe8313d45db46600e1478 upstream.

The nozomi wireless data driver has its own helper function to transfer data from a FIFO, doing an extra byte swap on big-endian architectures, presumably to bring the data back into byte-serial order after readw() or readl() perform their implicit byteswap.

This helper function is used in the receive_data() function to first read the length into a 32-bit variable, which causes a compile-time warning:

drivers/tty/nozomi.c: In function 'receive_data':
drivers/tty/nozomi.c:857:9: warning: 'size' may be used uninitialized in this function [-Wmaybe-uninitialized]

The problem is that gcc is unsure whether the data was actually read or not. We know that it is at this point, so we can replace it with a single readl() to shut up that warning.

I am leaving the byteswap in there, to preserve the existing behavior, even though this seems fishy: Reading the length of the data into a cpu-endian variable should normally not use a second byteswap on big-endian systems, unless the hardware is aware of the CPU endianess.

There appears to be a lot more confusion about endianess in this driver, so it probably has not worked on big-endian systems in a long time, if ever, and I have no way to test it. It's well possible that this driver has not been used by anyone in a while, the last patch that looks like it was tested on the hardware is from 2008.

---
 drivers/tty/nozomi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/nozomi.c +1 -1
index d6080c3831ef..ce2e5d508fe7 100644
@@ -823,7 +823,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
 	struct tty_struct *tty = tty_port_tty_get(&port->port);
 	int i, ret;
 
-	read_mem32((u32 *) &size, addr, 4);
+	size = __le32_to_cpu(readl(addr));
 	/*  DBG1( "%d bytes port: %d", size, index); */
 
 	if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
Signature · 1 line
2.12.2
author
#67 lore raw

PATCH 67/86 hostap: avoid uninitialized variable use in hfa384x_get_rid

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit 48dc5fb3ba53b20418de8514700f63d88c5de3a3 upstream.

The driver reads a value from hfa384x_from_bap(), which may fail, and then assigns the value to a local variable. gcc detects that in in the failure case, the 'rlen' variable now contains uninitialized data:

In file included from ../drivers/net/wireless/intersil/hostap/hostap_pci.c:220:0:
drivers/net/wireless/intersil/hostap/hostap_hw.c: In function 'hfa384x_get_rid':
drivers/net/wireless/intersil/hostap/hostap_hw.c:842:5: warning: 'rec' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (le16_to_cpu(rec.len) == 0) {

This restructures the function as suggested by Russell King, to make it more readable and get more reliable error handling, by handling each failure mode using a goto.

---
 drivers/net/wireless/hostap/hostap_hw.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/net/wireless/hostap/hostap_hw.c +10 -5
index c275dc1623fe..cd8c35787564 100644
@@ -836,25 +836,30 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
 	spin_lock_bh(&local->baplock);
 
 	res = hfa384x_setup_bap(dev, BAP0, rid, 0);
-	if (!res)
-		res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
+	if (res)
+		goto unlock;
+
+	res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
+	if (res)
+		goto unlock;
 
 	if (le16_to_cpu(rec.len) == 0) {
 		/* RID not available */
 		res = -ENODATA;
+		goto unlock;
 	}
 
 	rlen = (le16_to_cpu(rec.len) - 1) * 2;
-	if (!res && exact_len && rlen != len) {
+	if (exact_len && rlen != len) {
 		printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
 		       "rid=0x%04x, len=%d (expected %d)\n",
 		       dev->name, rid, rlen, len);
 		res = -ENODATA;
 	}
 
-	if (!res)
-		res = hfa384x_from_bap(dev, BAP0, buf, len);
+	res = hfa384x_from_bap(dev, BAP0, buf, len);
 
+unlock:
 	spin_unlock_bh(&local->baplock);
 	mutex_unlock(&local->rid_bap_mtx);
 
Signature · 1 line
2.12.2
author
#68 lore raw

PATCH 68/86 gfs2: avoid uninitialized variable warning

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit 67893f12e5374bbcaaffbc6e570acbc2714ea884 upstream.

We get a bogus warning about a potential uninitialized variable use in gfs2, because the compiler does not figure out that we never use the leaf number if get_leaf_nr() returns an error:

fs/gfs2/dir.c: In function 'get_first_leaf':
fs/gfs2/dir.c:802:9: warning: 'leaf_no' may be used uninitialized in this function [-Wmaybe-uninitialized] fs/gfs2/dir.c: In function 'dir_split_leaf':
fs/gfs2/dir.c:1021:8: warning: 'leaf_no' may be used uninitialized in this function [-Wmaybe-uninitialized]

Changing the 'if (!error)' to 'if (!IS_ERR_VALUE(error))' is sufficient to let gcc understand that this is exactly the same condition as in IS_ERR() so it can optimize the code path enough to understand it.

---
 fs/gfs2/dir.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/gfs2/dir.c +2 -2
index 2e5fc268d324..bdef6fef651c 100644
@@ -763,7 +763,7 @@ static int get_first_leaf(struct gfs2_inode *dip, u32 index,
 	int error;
 
 	error = get_leaf_nr(dip, index, &leaf_no);
-	if (!error)
+	if (!IS_ERR_VALUE(error))
 		error = get_leaf(dip, leaf_no, bh_out);
 
 	return error;
@@ -974,7 +974,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
 
 	index = name->hash >> (32 - dip->i_depth);
 	error = get_leaf_nr(dip, index, &leaf_no);
-	if (error)
+	if (IS_ERR_VALUE(error))
 		return error;
 
 	/*  Get the old leaf block  */
Signature · 1 line
2.12.2
author
#69 lore raw

PATCH 69/86 net: neigh: guard against NULL solicit() method

In reply to Jiri Slaby

From: Eric Dumazet <[email protected]>

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

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

[ Upstream commit 48481c8fa16410ffa45939b13b6c53c2ca609e5f ]

Dmitry posted a nice reproducer of a bug triggering in neigh_probe() when dereferencing a NULL neigh->ops->solicit method.

This can happen for arp_direct_ops/ndisc_direct_ops and similar, which can be used for NUD_NOARP neighbours (created when dev->header_ops is NULL). Admin can then force changing nud_state to some other state that would fire neigh timer.

---
 net/core/neighbour.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/neighbour.c +2 -1
index 7957daa334cc..3a6a4f11e876 100644
@@ -872,7 +872,8 @@ static void neigh_probe(struct neighbour *neigh)
 	if (skb)
 		skb = skb_copy(skb, GFP_ATOMIC);
 	write_unlock(&neigh->lock);
-	neigh->ops->solicit(neigh, skb);
+	if (neigh->ops->solicit)
+		neigh->ops->solicit(neigh, skb);
 	atomic_inc(&neigh->probes);
 	kfree_skb(skb);
 }
Signature · 1 line
2.12.2
author
#70 lore raw

PATCH 70/86 net: phy: handle state correctly in phy_stop_machine

In reply to Jiri Slaby

From: Nathan Sullivan <[email protected]>

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

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

[ Upstream commit 49d52e8108a21749dc2114b924c907db43358984 ]

If the PHY is halted on stop, then do not set the state to PHY_UP. This ensures the phy will be restarted later in phy_start when the machine is started again.

Fixes 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details.")
---
 drivers/net/phy/phy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/phy.c +1 -1
index 0bc73f2c24ba..eca07101dc0c 100644
@@ -473,7 +473,7 @@ void phy_stop_machine(struct phy_device *phydev)
 	cancel_delayed_work_sync(&phydev->state_queue);
 
 	mutex_lock(&phydev->lock);
-	if (phydev->state > PHY_UP)
+	if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
 		phydev->state = PHY_UP;
 	mutex_unlock(&phydev->lock);
 
Signature · 1 line
2.12.2
author
#71 lore raw

PATCH 71/86 l2tp: take reference on sessions being dumped

In reply to Jiri Slaby

From: Guillaume Nault <[email protected]>

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

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

[ Upstream commit e08293a4ccbcc993ded0fdc46f1e57926b833d63 ]

Take a reference on the sessions returned by l2tp_session_find_nth() (and rename it l2tp_session_get_nth() to reflect this change), so that caller is assured that the session isn't going to disappear while processing it.

For procfs and debugfs handlers, the session is held in the .start() callback and dropped in .show(). Given that pppol2tp_seq_session_show() dereferences the associated PPPoL2TP socket and that l2tp_dfs_seq_session_show() might call pppol2tp_show(), we also need to call the session's .ref() callback to prevent the socket from going away from under us.

Fixes fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
Fixes 0ad6614048cf ("l2tp: Add debugfs files for dumping l2tp debug info")
Fixes 309795f4bec2 ("l2tp: Add netlink control API for L2TP")
---
 net/l2tp/l2tp_core.c    |  8 ++++++--
 net/l2tp/l2tp_core.h    |  3 ++-
 net/l2tp/l2tp_debugfs.c | 10 +++++++---
 net/l2tp/l2tp_netlink.c |  7 +++++--
 net/l2tp/l2tp_ppp.c     | 10 +++++++---
 5 files changed, 27 insertions(+), 11 deletions(-)
net/l2tp/l2tp_core.c +6 -2
index 6639bc27edb9..d5c09cb249ea 100644
@@ -280,7 +280,8 @@ struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunn
 }
 EXPORT_SYMBOL_GPL(l2tp_session_find);
 
-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
+struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+					  bool do_ref)
 {
 	int hash;
 	struct l2tp_session *session;
@@ -290,6 +291,9 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
 	for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
 		hlist_for_each_entry(session, &tunnel->session_hlist[hash], hlist) {
 			if (++count > nth) {
+				l2tp_session_inc_refcount(session);
+				if (do_ref && session->ref)
+					session->ref(session);
 				read_unlock_bh(&tunnel->hlist_lock);
 				return session;
 			}
@@ -300,7 +304,7 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
 
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_find_nth);
+EXPORT_SYMBOL_GPL(l2tp_session_get_nth);
 
 /* Lookup a session by interface name.
  * This is very inefficient but is only used by management interfaces.
net/l2tp/l2tp_core.h +2 -1
index f8f1089ee8f2..bf8ad2f233fc 100644
@@ -241,7 +241,8 @@ out:
 extern struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel);
 extern void l2tp_tunnel_sock_put(struct sock *sk);
 extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
-extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
+extern struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
+						 bool do_ref);
 extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
 extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
 extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
net/l2tp/l2tp_debugfs.c +7 -3
index 072d7202e182..c6bd783cfb1b 100644
@@ -53,7 +53,7 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd)
 
 static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -237,10 +237,14 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v)
 	}
 
 	/* Show the tunnel or session context */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		l2tp_dfs_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		l2tp_dfs_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
net/l2tp/l2tp_netlink.c +5 -2
index 0825ff26e113..490024eaece8 100644
@@ -719,7 +719,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
 				goto out;
 		}
 
-		session = l2tp_session_find_nth(tunnel, si);
+		session = l2tp_session_get_nth(tunnel, si, false);
 		if (session == NULL) {
 			ti++;
 			tunnel = NULL;
@@ -729,8 +729,11 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
 
 		if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid,
 					 cb->nlh->nlmsg_seq, NLM_F_MULTI,
-					 session) <= 0)
+					 session) <= 0) {
+			l2tp_session_dec_refcount(session);
 			break;
+		}
+		l2tp_session_dec_refcount(session);
 
 		si++;
 	}
net/l2tp/l2tp_ppp.c +7 -3
index c3ae2411650c..c06c7ed47b69 100644
@@ -1576,7 +1576,7 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
 
 static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
 {
-	pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx);
+	pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true);
 	pd->session_idx++;
 
 	if (pd->session == NULL) {
@@ -1703,10 +1703,14 @@ static int pppol2tp_seq_show(struct seq_file *m, void *v)
 
 	/* Show the tunnel or session context.
 	 */
-	if (pd->session == NULL)
+	if (!pd->session) {
 		pppol2tp_seq_tunnel_show(m, pd->tunnel);
-	else
+	} else {
 		pppol2tp_seq_session_show(m, pd->session);
+		if (pd->session->deref)
+			pd->session->deref(pd->session);
+		l2tp_session_dec_refcount(pd->session);
+	}
 
 out:
 	return 0;
Signature · 1 line
2.12.2
author
#72 lore raw

PATCH 72/86 net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given

In reply to Jiri Slaby

From: Florian Larysch <[email protected]>

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

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

[ Upstream commit a8801799c6975601fd58ae62f48964caec2eb83f ]

inet_rtm_getroute synthesizes a skeletal ICMP skb, which is passed to ip_route_input when iif is given. If a multipath route is present for the designated destination, ip_multipath_icmp_hash ends up being called, which uses the source/destination addresses within the skb to calculate a hash. However, those are not set in the synthetic skb, causing it to return an arbitrary and incorrect result.

Instead, use UDP, which gets no such special treatment.

---
 net/ipv4/route.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/route.c +1 -1
index 1b180691086c..778b3e9316db 100644
@@ -2492,7 +2492,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	skb_reset_network_header(skb);
 
 	/* Bugfix: need to give ip_route_input enough of an IP header to not gag. */
-	ip_hdr(skb)->protocol = IPPROTO_ICMP;
+	ip_hdr(skb)->protocol = IPPROTO_UDP;
 	skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
 
 	src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
Signature · 1 line
2.12.2
#73 lore raw

Re: [PATCH 3.12 72/86] net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given

Hi,

applying this to 3.12 is unnecessary, as it works around a problem which was only introduced in 4.4 by

79a131592dbb ipv4: ICMP packet inspection for multipath

Florian

author
#74 lore raw

Re: [PATCH 3.12 72/86] net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given

Quoted 6 lines · Florian Larysch

Hi,

applying this to 3.12 is unnecessary, as it works around a problem which was only introduced in 4.4 by

79a131592dbb ipv4: ICMP packet inspection for multipath

Dropped, thanks!

Signature · 2 lines
js
suse labs
author
#75 lore raw

PATCH 73/86 sctp: listen on the sock only when it's state is listening or closed

In reply to Jiri Slaby

From: Xin Long <[email protected]>

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

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

[ Upstream commit 34b2789f1d9bf8dcca9b5cb553d076ca2cd898ee ]

Now sctp doesn't check sock's state before listening on it. It could even cause changing a sock with any state to become a listening sock when doing sctp_listen.

This patch is to fix it by checking sock's state in sctp_listen, so that it will listen on the sock with right state.

---
 net/sctp/socket.c | 3 +++
 1 file changed, 3 insertions(+)
net/sctp/socket.c +3 -0
index 0059ce3fb747..16f03f76ff8f 100644
@@ -6169,6 +6169,9 @@ int sctp_inet_listen(struct socket *sock, int backlog)
 	if (sock->state != SS_UNCONNECTED)
 		goto out;
 
+	if (!sctp_sstate(sk, LISTENING) && !sctp_sstate(sk, CLOSED))
+		goto out;
+
 	/* If backlog is zero, disable listening. */
 	if (!backlog) {
 		if (sctp_sstate(sk, CLOSED))
Signature · 1 line
2.12.2
author
#76 lore raw

PATCH 74/86 ip6mr: fix notification device destruction

In reply to Jiri Slaby

From: Nikolay Aleksandrov <[email protected]>

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

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

[ Upstream commit 723b929ca0f79c0796f160c2eeda4597ee98d2b8 ]

Andrey Konovalov reported a BUG caused by the ip6mr code which is caused because we call unregister_netdevice_many for a device that is already being destroyed. In IPv4's ipmr that has been resolved by two commits long time ago by introducing the "notify" parameter to the delete function and avoiding the unregister when called from a notifier, so let's do the same for ip6mr.

The trace from Andrey:

------------[ cut here ]------------
kernel BUG at net/core/dev.c:6813!
invalid opcode: 0000 [#1] SMP KASAN
Modules linked in:
CPU: 1 PID: 1165 Comm: kworker/u4:3 Not tainted 4.11.0-rc7+ #251
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs
01/01/2011
Workqueue: netns cleanup_net
task: ffff880069208000 task.stack: ffff8800692d8000
RIP: 0010:rollback_registered_many+0x348/0xeb0 net/core/dev.c:6813
RSP: 0018:ffff8800692de7f0 EFLAGS: 00010297
RAX: ffff880069208000 RBX: 0000000000000002 RCX: 0000000000000001
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88006af90569
RBP: ffff8800692de9f0 R08: ffff8800692dec60 R09: 0000000000000000
R10: 0000000000000006 R11: 0000000000000000 R12: ffff88006af90070
R13: ffff8800692debf0 R14: dffffc0000000000 R15: ffff88006af90000
FS:  0000000000000000(0000) GS:ffff88006cb00000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fe7e897d870 CR3: 00000000657e7000 CR4: 00000000000006e0
Call Trace:
 unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881
 unregister_netdevice_many+0xc8/0x120 net/core/dev.c:7880
 ip6mr_device_event+0x362/0x3f0 net/ipv6/ip6mr.c:1346
 notifier_call_chain+0x145/0x2f0 kernel/notifier.c:93
 __raw_notifier_call_chain kernel/notifier.c:394
 raw_notifier_call_chain+0x2d/0x40 kernel/notifier.c:401
 call_netdevice_notifiers_info+0x51/0x90 net/core/dev.c:1647
 call_netdevice_notifiers net/core/dev.c:1663
 rollback_registered_many+0x919/0xeb0 net/core/dev.c:6841
 unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881
 unregister_netdevice_many net/core/dev.c:7880
 default_device_exit_batch+0x4fa/0x640 net/core/dev.c:8333
 ops_exit_list.isra.4+0x100/0x150 net/core/net_namespace.c:144
 cleanup_net+0x5a8/0xb40 net/core/net_namespace.c:463
 process_one_work+0xc04/0x1c10 kernel/workqueue.c:2097
 worker_thread+0x223/0x19c0 kernel/workqueue.c:2231
 kthread+0x35e/0x430 kernel/kthread.c:231
 ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430
Code: 3c 32 00 0f 85 70 0b 00 00 48 b8 00 02 00 00 00 00 ad de 49 89
47 78 e9 93 fe ff ff 49 8d 57 70 49 8d 5f 78 eb 9e e8 88 7a 14 fe <0f>
0b 48 8b 9d 28 fe ff ff e8 7a 7a 14 fe 48 b8 00 00 00 00 00
RIP: rollback_registered_many+0x348/0xeb0 RSP: ffff8800692de7f0
---[ end trace e0b29c57e9b3292c ]---
---
 net/ipv6/ip6mr.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
net/ipv6/ip6mr.c +6 -7
index 56aa540d77f6..2dcb19cb8f61 100644
@@ -776,7 +776,8 @@ failure:
  *	Delete a VIF entry
  */
 
-static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
+static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
+		       struct list_head *head)
 {
 	struct mif_device *v;
 	struct net_device *dev;
@@ -822,7 +823,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
 					     dev->ifindex, &in6_dev->cnf);
 	}
 
-	if (v->flags & MIFF_REGISTER)
+	if ((v->flags & MIFF_REGISTER) && !notify)
 		unregister_netdevice_queue(dev, head);
 
 	dev_put(dev);
@@ -1332,7 +1333,6 @@ static int ip6mr_device_event(struct notifier_block *this,
 	struct mr6_table *mrt;
 	struct mif_device *v;
 	int ct;
-	LIST_HEAD(list);
 
 	if (event != NETDEV_UNREGISTER)
 		return NOTIFY_DONE;
@@ -1341,10 +1341,9 @@ static int ip6mr_device_event(struct notifier_block *this,
 		v = &mrt->vif6_table[0];
 		for (ct = 0; ct < mrt->maxvif; ct++, v++) {
 			if (v->dev == dev)
-				mif6_delete(mrt, ct, &list);
+				mif6_delete(mrt, ct, 1, NULL);
 		}
 	}
-	unregister_netdevice_many(&list);
 
 	return NOTIFY_DONE;
 }
@@ -1549,7 +1548,7 @@ static void mroute_clean_tables(struct mr6_table *mrt, bool all)
 	for (i = 0; i < mrt->maxvif; i++) {
 		if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
 			continue;
-		mif6_delete(mrt, i, &list);
+		mif6_delete(mrt, i, 0, &list);
 	}
 	unregister_netdevice_many(&list);
 
@@ -1702,7 +1701,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
 		if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
 			return -EFAULT;
 		rtnl_lock();
-		ret = mif6_delete(mrt, mifi, NULL);
+		ret = mif6_delete(mrt, mifi, 0, NULL);
 		rtnl_unlock();
 		return ret;
 
Signature · 1 line
2.12.2
author
#77 lore raw

PATCH 75/86 ipv6: check raw payload size correctly in ioctl

In reply to Jiri Slaby

From: Jamie Bainbridge <[email protected]>

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

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

[ Upstream commit 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 ]

In situations where an skb is paged, the transport header pointer and tail pointer can be the same because the skb contents are in frags.

This results in ioctl(SIOCINQ/FIONREAD) incorrectly returning a length of 0 when the length to receive is actually greater than zero.

skb->len is already correctly set in ip6_input_finish() with pskb_pull(), so use skb->len as it always returns the correct result for both linear and paged data.

---
 net/ipv6/raw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
net/ipv6/raw.c +1 -2
index c2afb29dc1d7..581662201ba9 100644
@@ -1145,8 +1145,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
 		spin_lock_bh(&sk->sk_receive_queue.lock);
 		skb = skb_peek(&sk->sk_receive_queue);
 		if (skb != NULL)
-			amount = skb_tail_pointer(skb) -
-				skb_transport_header(skb);
+			amount = skb->len;
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
 		return put_user(amount, (int __user *)arg);
 	}
Signature · 1 line
2.12.2
author
#78 lore raw

PATCH 76/86 ext4: check if in-inode xattr is corrupted in ext4_expand_extra_isize_ea()

In reply to Jiri Slaby

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

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

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

commit 9e92f48c34eb2b9af9d12f892e2fe1fce5e8ce35 upstream.

We aren't checking to see if the in-inode extended attribute is corrupted before we try to expand the inode's extra isize fields.

This can lead to potential crashes caused by the BUG_ON() check in ext4_xattr_shift_entries().

[js] use EIO instead of undefined EFSCORRUPTED in 3.12

---
 fs/ext4/xattr.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)
fs/ext4/xattr.c +28 -4
index e5835f6e1466..4e7384b7608e 100644
@@ -233,6 +233,27 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
 	return error;
 }
 
+static int
+__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+			 void *end, const char *function, unsigned int line)
+{
+	struct ext4_xattr_entry *entry = IFIRST(header);
+	int error = -EIO;
+
+	if (((void *) header >= end) ||
+	    (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC)))
+		goto errout;
+	error = ext4_xattr_check_names(entry, end, entry);
+errout:
+	if (error)
+		__ext4_error_inode(inode, function, line, 0,
+				   "corrupted in-inode xattr");
+	return error;
+}
+
+#define xattr_check_inode(inode, header, end) \
+	__xattr_check_inode((inode), (header), (end), __func__, __LINE__)
+
 static inline int
 ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
 {
@@ -343,7 +364,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
 	header = IHDR(inode, raw_inode);
 	entry = IFIRST(header);
 	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-	error = ext4_xattr_check_names(entry, end, entry);
+	error = xattr_check_inode(inode, header, end);
 	if (error)
 		goto cleanup;
 	error = ext4_xattr_find_entry(&entry, name_index, name,
@@ -471,7 +492,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
 	raw_inode = ext4_raw_inode(&iloc);
 	header = IHDR(inode, raw_inode);
 	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-	error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header));
+	error = xattr_check_inode(inode, header, end);
 	if (error)
 		goto cleanup;
 	error = ext4_xattr_list_entries(dentry, IFIRST(header),
@@ -986,8 +1007,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
 	is->s.here = is->s.first;
 	is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
 	if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
-		error = ext4_xattr_check_names(IFIRST(header), is->s.end,
-					       IFIRST(header));
+		error = xattr_check_inode(inode, header, is->s.end);
 		if (error)
 			return error;
 		/* Find the named attribute. */
@@ -1284,6 +1304,10 @@ retry:
 	last = entry;
 	total_ino = sizeof(struct ext4_xattr_ibody_header);
 
+	error = xattr_check_inode(inode, header, end);
+	if (error)
+		goto cleanup;
+
 	free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
 	if (free >= new_extra_isize) {
 		entry = IFIRST(header);
Signature · 1 line
2.12.2
author
#79 lore raw

PATCH 77/86 md:raid1: fix a dead loop when read from a WriteMostly disk

In reply to Jiri Slaby

From: Wei Fang <[email protected]>

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

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

commit 816b0acf3deb6d6be5d0519b286fdd4bafade905 upstream.

If first_bad == this_sector when we get the WriteMostly disk in read_balance(), valid disk will be returned with zero max_sectors. It'll lead to a dead loop in make_request(), and OOM will happen because of endless allocation of struct bio.

Since we can't get data from this disk in this case, so continue for another disk.

---
 drivers/md/raid1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/raid1.c +1 -1
index 479828ad2021..e5f8fd19e47d 100644
@@ -560,7 +560,7 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
 			if (best_dist_disk < 0) {
 				if (is_badblock(rdev, this_sector, sectors,
 						&first_bad, &bad_sectors)) {
-					if (first_bad < this_sector)
+					if (first_bad <= this_sector)
 						/* Cannot use this */
 						continue;
 					best_good_sectors = first_bad - this_sector;
Signature · 1 line
2.12.2
author
#80 lore raw

PATCH 78/86 MIPS: Fix crash registers on non-crashing CPUs

In reply to Jiri Slaby

From: Corey Minyard <[email protected]>

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

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

commit c80e1b62ffca52e2d1d865ee58bc79c4c0c55005 upstream.

As part of handling a crash on an SMP system, an IPI is send to all other CPUs to save their current registers and stop. It was using task_pt_regs(current) to get the registers, but that will only be accurate if the CPU was interrupted running in userland. Instead allow the architecture to pass in the registers (all pass NULL now, but allow for the future) and then use get_irq_regs() which should be accurate as we are in an interrupt. Fall back to task_pt_regs(current) if nothing else is available.

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

---
 arch/mips/kernel/crash.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
arch/mips/kernel/crash.c +13 -3
index 93aa302948d7..c68312947ed9 100644
@@ -15,12 +15,22 @@ static int crashing_cpu = -1;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
 
 #ifdef CONFIG_SMP
-static void crash_shutdown_secondary(void *ignore)
+static void crash_shutdown_secondary(void *passed_regs)
 {
-	struct pt_regs *regs;
+	struct pt_regs *regs = passed_regs;
 	int cpu = smp_processor_id();
 
-	regs = task_pt_regs(current);
+	/*
+	 * If we are passed registers, use those.  Otherwise get the
+	 * regs from the last interrupt, which should be correct, as
+	 * we are in an interrupt.  But if the regs are not there,
+	 * pull them from the top of the stack.  They are probably
+	 * wrong, but we need something to keep from crashing again.
+	 */
+	if (!regs)
+		regs = get_irq_regs();
+	if (!regs)
+		regs = task_pt_regs(current);
 
 	if (!cpu_online(cpu))
 		return;
Signature · 1 line
2.12.2
author
#81 lore raw

PATCH 79/86 RDS: Fix the atomicity for congestion map update

In reply to Jiri Slaby

From: "[email protected]" <[email protected]>

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

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

commit e47db94e10447fc467777a40302f2b393e9af2fa upstream.

Two different threads with different rds sockets may be in rds_recv_rcvbuf_delta() via receive path. If their ports both map to the same word in the congestion map, then using non-atomic ops to update it could cause the map to be incorrect. Lets use atomics to avoid such an issue.

Full credit to Wengang <[email protected]> for finding the issue, analysing it and also pointing out to offending code with spin lock based fix.

---
 net/rds/cong.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/rds/cong.c +2 -2
index e5b65acd650b..cec4c4e6d905 100644
@@ -285,7 +285,7 @@ void rds_cong_set_bit(struct rds_cong_map *map, __be16 port)
 	i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
 	off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
 
-	__set_bit_le(off, (void *)map->m_page_addrs[i]);
+	set_bit_le(off, (void *)map->m_page_addrs[i]);
 }
 
 void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
@@ -299,7 +299,7 @@ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
 	i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
 	off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
 
-	__clear_bit_le(off, (void *)map->m_page_addrs[i]);
+	clear_bit_le(off, (void *)map->m_page_addrs[i]);
 }
 
 static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)
Signature · 1 line
2.12.2
author
#82 lore raw

PATCH 80/86 xen/x86: don't lose event interrupts

In reply to Jiri Slaby

From: Stefano Stabellini <[email protected]>

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

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

commit c06b6d70feb32d28f04ba37aa3df17973fd37b6b upstream.

On slow platforms with unreliable TSC, such as QEMU emulated machines, it is possible for the kernel to request the next event in the past. In that case, in the current implementation of xen_vcpuop_clockevent, we simply return -ETIME. To be precise the Xen returns -ETIME and we pass it on. However the result of this is a missed event, which simply causes the kernel to hang.

Instead it is better to always ask the hypervisor for a timer event, even if the timeout is in the past. That way there are no lost interrupts and the kernel survives. To do that, remove the VCPU_SSHOTTMR_future flag.

---
 arch/x86/xen/time.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/xen/time.c +3 -3
index 90bfa524b11c..86dc28ce11ab 100644
@@ -362,11 +362,11 @@ static int xen_vcpuop_set_next_event(unsigned long delta,
 	WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
 
 	single.timeout_abs_ns = get_abs_timeout(delta);
-	single.flags = VCPU_SSHOTTMR_future;
+	/* Get an event anyway, even if the timeout is already expired */
+	single.flags = 0;
 
 	ret = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &single);
-
-	BUG_ON(ret != 0 && ret != -ETIME);
+	BUG_ON(ret != 0);
 
 	return ret;
 }
Signature · 1 line
2.12.2
author
#83 lore raw

PATCH 81/86 ALSA: seq: Don't break snd_use_lock_sync() loop by timeout

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

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

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

commit 4e7655fd4f47c23e5249ea260dc802f909a64611 upstream.

The snd_use_lock_sync() (thus its implementation snd_use_lock_sync_helper()) has the 5 seconds timeout to break out of the sync loop. It was introduced from the beginning, just to be "safer", in terms of avoiding the stupid bugs.

However, as Ben Hutchings suggested, this timeout rather introduces a potential leak or use-after-free that was apparently fixed by the commit 2d7d54002e39 ("ALSA: seq: Fix race during FIFO resize"):
for example, snd_seq_fifo_event_in() -> snd_seq_event_dup() -> copy_from_user() could block for a long time, and snd_use_lock_sync() goes timeout and still leaves the cell at releasing the pool.

For fixing such a problem, we remove the break by the timeout while still keeping the warning.

---
 sound/core/seq/seq_lock.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
sound/core/seq/seq_lock.c +3 -6
index 2cfe50c71a9d..8a6b7baafa35 100644
@@ -28,19 +28,16 @@
 /* wait until all locks are released */
 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 {
-	int max_count = 5 * HZ;
+	int warn_count = 5 * HZ;
 
 	if (atomic_read(lockp) < 0) {
 		printk(KERN_WARNING "seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
 		return;
 	}
 	while (atomic_read(lockp) > 0) {
-		if (max_count == 0) {
-			snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
-			break;
-		}
+		if (warn_count-- == 0)
+			pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 		schedule_timeout_uninterruptible(1);
-		max_count--;
 	}
 }
 
Signature · 1 line
2.12.2
author
#84 lore raw

PATCH 82/86 MIPS: KGDB: Use kernel context for sleeping threads

In reply to Jiri Slaby

From: James Hogan <[email protected]>

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

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

commit 162b270c664dca2e0944308e92f9fcc887151a72 upstream.

KGDB is a kernel debug stub and it can't be used to debug userland as it can only safely access kernel memory.

On MIPS however KGDB has always got the register state of sleeping processes from the userland register context at the beginning of the kernel stack. This is meaningless for kernel threads (which never enter userland), and for user threads it prevents the user seeing what it is doing while in the kernel:

(gdb) info threads
Id Target Id Frame
...

  3    Thread 2 (kthreadd) 0x0000000000000000 in ?? ()
  2    Thread 1 (init)   0x000000007705c4b4 in ?? ()
  1    Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201

Get the register state instead from the (partial) kernel register context stored in the task's thread_struct for resume() to restore. All threads now correctly appear to be in context_switch():

(gdb) info threads
Id Target Id Frame
...

  3    Thread 2 (kthreadd) context_switch (rq=<optimized out>, cookie=..., next=<optimized out>, prev=0x0) at kernel/sched/core.c:2903
  2    Thread 1 (init)   context_switch (rq=<optimized out>, cookie=..., next=<optimized out>, prev=0x0) at kernel/sched/core.c:2903
  1    Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201

Call clobbered registers which aren't saved and exception registers (BadVAddr & Cause) which can't be easily determined without stack unwinding are reported as 0. The PC is taken from the return address, such that the state presented matches that found immediately after returning from resume().

Fixes 8854700115ec ("[MIPS] kgdb: add arch support for the kernel's kgdb core")
Cc Jason Wessel <[email protected]>

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

---
 arch/mips/kernel/kgdb.c | 48 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 15 deletions(-)
arch/mips/kernel/kgdb.c +33 -15
index fcaac2f132f0..910db386d9ef 100644
@@ -236,9 +236,6 @@ static int compute_signal(int tt)
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
 	int reg;
-	struct thread_info *ti = task_thread_info(p);
-	unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
-	struct pt_regs *regs = (struct pt_regs *)ksp - 1;
 #if (KGDB_GDB_REG_SIZE == 32)
 	u32 *ptr = (u32 *)gdb_regs;
 #else
@@ -246,25 +243,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 #endif
 
 	for (reg = 0; reg < 16; reg++)
-		*(ptr++) = regs->regs[reg];
+		*(ptr++) = 0;
 
 	/* S0 - S7 */
-	for (reg = 16; reg < 24; reg++)
-		*(ptr++) = regs->regs[reg];
+	*(ptr++) = p->thread.reg16;
+	*(ptr++) = p->thread.reg17;
+	*(ptr++) = p->thread.reg18;
+	*(ptr++) = p->thread.reg19;
+	*(ptr++) = p->thread.reg20;
+	*(ptr++) = p->thread.reg21;
+	*(ptr++) = p->thread.reg22;
+	*(ptr++) = p->thread.reg23;
 
 	for (reg = 24; reg < 28; reg++)
 		*(ptr++) = 0;
 
 	/* GP, SP, FP, RA */
-	for (reg = 28; reg < 32; reg++)
-		*(ptr++) = regs->regs[reg];
-
-	*(ptr++) = regs->cp0_status;
-	*(ptr++) = regs->lo;
-	*(ptr++) = regs->hi;
-	*(ptr++) = regs->cp0_badvaddr;
-	*(ptr++) = regs->cp0_cause;
-	*(ptr++) = regs->cp0_epc;
+	*(ptr++) = (long)p;
+	*(ptr++) = p->thread.reg29;
+	*(ptr++) = p->thread.reg30;
+	*(ptr++) = p->thread.reg31;
+
+	*(ptr++) = p->thread.cp0_status;
+
+	/* lo, hi */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * BadVAddr, Cause
+	 * Ideally these would come from the last exception frame up the stack
+	 * but that requires unwinding, otherwise we can't know much for sure.
+	 */
+	*(ptr++) = 0;
+	*(ptr++) = 0;
+
+	/*
+	 * PC
+	 * use return address (RA), i.e. the moment after return from resume()
+	 */
+	*(ptr++) = p->thread.reg31;
 }
 
 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
Signature · 1 line
2.12.2
author
#85 lore raw

PATCH 83/86 p9_client_readdir() fix

In reply to Jiri Slaby

From: Al Viro <[email protected]>

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

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

commit 71d6ad08379304128e4bdfaf0b4185d54375423e upstream.

Don't assume that server is sane and won't return more data than asked for.

---
 net/9p/client.c | 4 ++++
 1 file changed, 4 insertions(+)
net/9p/client.c +4 -0
index ae4778c84559..bde453ae5e2e 100644
@@ -2099,6 +2099,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
 		trace_9p_protocol_dump(clnt, req->rc);
 		goto free_and_error;
 	}
+	if (rsize < count) {
+		pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
+		count = rsize;
+	}
 
 	p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
 
Signature · 1 line
2.12.2
author
#86 lore raw

PATCH 84/86 Input: i8042 - add Clevo P650RS to the i8042 reset list

In reply to Jiri Slaby

From: Dmitry Torokhov <[email protected]>

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

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

commit 7c5bb4ac2b76d2a09256aec8a7d584bf3e2b0466 upstream.

Clevo P650RS and other similar devices require i8042 to be reset in order to detect Synaptics touchpad.

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

---
 drivers/input/serio/i8042-x86ia64io.h | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
index 9a2d2159bf0c..04a2593f0a9a 100644
@@ -594,6 +594,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
 		},
 	},
+	{
+		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+		},
+	},
 	{ }
 };
 
Signature · 1 line
2.12.2
author
#87 lore raw

PATCH 85/86 nfsd: check for oversized NFSv2/v3 arguments

In reply to Jiri Slaby

From: "J. Bruce Fields" <[email protected]>

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

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

commit e6838a29ecb484c97e4efef9429643b9851fba6e upstream.

A client can append random data to the end of an NFSv2 or NFSv3 RPC call without our complaining; we'll just stop parsing at the end of the expected data and ignore the rest.

Encoded arguments and replies are stored together in an array of pages, and if a call is too large it could leave inadequate space for the reply. This is normally OK because NFS RPC's typically have either short arguments and long replies (like READ) or long arguments and short replies (like WRITE). But a client that sends an incorrectly long reply can violate those assumptions. This was observed to cause crashes.

Also, several operations increment rq_next_page in the decode routine before checking the argument size, which can leave rq_next_page pointing well past the end of the page array, causing trouble later in svc_free_pages.

So, following a suggestion from Neil Brown, add a central check to enforce our expectation that no NFSv2/v3 call has both a large call and a large reply.

As followup we may also want to rewrite the encoding routines to check more carefully that they aren't running off the end of the page array.

We may also consider rejecting calls that have any extra garbage appended. That would be safer, and within our rights by spec, but given the age of our server and the NFS protocol, and the fact that we've never enforced this before, we may need to balance that against the possibility of breaking some oddball client.

---
 fs/nfsd/nfssvc.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
fs/nfsd/nfssvc.c +36 -0
index 4942f4370f60..a0903991a0fd 100644
@@ -628,6 +628,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
 	return nfserr;
 }
 
+/*
+ * A write procedure can have a large argument, and a read procedure can
+ * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
+ * reply that can both be larger than a page.  The xdr code has taken
+ * advantage of this assumption to be a sloppy about bounds checking in
+ * some cases.  Pending a rewrite of the NFSv2/v3 xdr code to fix that
+ * problem, we enforce these assumptions here:
+ */
+static bool nfs_request_too_big(struct svc_rqst *rqstp,
+				struct svc_procedure *proc)
+{
+	/*
+	 * The ACL code has more careful bounds-checking and is not
+	 * susceptible to this problem:
+	 */
+	if (rqstp->rq_prog != NFS_PROGRAM)
+		return false;
+	/*
+	 * Ditto NFSv4 (which can in theory have argument and reply both
+	 * more than a page):
+	 */
+	if (rqstp->rq_vers >= 4)
+		return false;
+	/* The reply will be small, we're OK: */
+	if (proc->pc_xdrressize > 0 &&
+	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
+		return false;
+
+	return rqstp->rq_arg.len > PAGE_SIZE;
+}
+
 int
 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 {
@@ -640,6 +671,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 				rqstp->rq_vers, rqstp->rq_proc);
 	proc = rqstp->rq_procinfo;
 
+	if (nfs_request_too_big(rqstp, proc)) {
+		dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
+		*statp = rpc_garbage_args;
+		return 1;
+	}
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
 	 * (necessary in the NFSv4.0 compound case)
Signature · 1 line
2.12.2
author
#88 lore raw

PATCH 86/86 ftrace/x86: Fix triple fault with graph tracing and suspend-to-ram

In reply to Jiri Slaby

From: Josh Poimboeuf <[email protected]>

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

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

commit 34a477e5297cbaa6ecc6e17c042a866e1cbe80d6 upstream.

On x86-32, with CONFIG_FIRMWARE and multiple CPUs, if you enable function graph tracing and then suspend to RAM, it will triple fault and reboot when it resumes.

The first fault happens when booting a secondary CPU:

startup_32_smp()
load_ucode_ap()
prepare_ftrace_return()
ftrace_graph_is_dead()
(accesses 'kill_ftrace_graph')

The early head_32.S code calls into load_ucode_ap(), which has an an ftrace hook, so it calls prepare_ftrace_return(), which calls ftrace_graph_is_dead(), which tries to access the global 'kill_ftrace_graph' variable with a virtual address, causing a fault because the CPU is still in real mode.

The fix is to add a check in prepare_ftrace_return() to make sure it's running in protected mode before continuing. The check makes sure the stack pointer is a virtual kernel address. It's a bit of a hack, but it's not very intrusive and it works well enough.

For reference, here are a few other (more difficult) ways this could have potentially been fixed:

- Move startup_32_smp()'s call to load_ucode_ap() down to *after* paging is enabled. (No idea what that would break.)

- Track down load_ucode_ap()'s entire callee tree and mark all the functions 'notrace'. (Probably not realistic.)

- Pause graph tracing in ftrace_suspend_notifier_call() or bringup_cpu() or __cpu_up(), and ensure that the pause facility can be queried from real mode.

---
 arch/x86/kernel/ftrace.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/x86/kernel/ftrace.c +12 -0
index f8ab203fb676..b8162154e615 100644
@@ -735,6 +735,18 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 	unsigned long return_hooker = (unsigned long)
 				&return_to_handler;
 
+	/*
+	 * When resuming from suspend-to-ram, this function can be indirectly
+	 * called from early CPU startup code while the CPU is in real mode,
+	 * which would fail miserably.  Make sure the stack pointer is a
+	 * virtual address.
+	 *
+	 * This check isn't as accurate as virt_addr_valid(), but it should be
+	 * good enough for this purpose, and it's fast.
+	 */
+	if (unlikely((long)__builtin_frame_address(0) >= 0))
+		return;
+
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
 		return;
 
Signature · 1 line
2.12.2
author
#89 lore raw
In reply to Jiri Slaby
Quoted 4 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.74 release. There are 86 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.

Note that if nothing really bad happens, this will be very likely the last 3.12 stable kernel.

Quoted 8 lines

Responses should be made by Mon May 8 11:03:52 CEST 2017. 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.74-rc1.xz

and the diffstat can be found below.

thanks,

Signature · 2 lines
js
suse labs
#90 lore raw
In reply to Jiri Slaby
Quoted 8 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.74 release. There are 86 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 May 8 11:03:52 CEST 2017. Anything received after that time might be too late.

Build results:

	total: 125 pass: 125 fail: 0
Qemu test results:
	total: 93 pass: 93 fail: 0

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

Guenter

author
#91 lore raw
Quoted 15 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.74 release. There are 86 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 May 8 11:03:52 CEST 2017. Anything received after that time might be too late.

Build results:

	total: 125 pass: 125 fail: 0
Qemu test results:
	total: 93 pass: 93 fail: 0

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

Quoted 1 line · Shuah Khan

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

Thank you both for all the test during all the releases. Hopefully this was the last 3.12, so I won't bother you more with this line.

thanks,

Signature · 2 lines
js
suse labs
#92 lore raw
In reply to Jiri Slaby
Quoted 8 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.74 release. There are 86 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 May 8 11:03:52 CEST 2017. Anything received after that time might be too late.

Quoted 7 lines

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

	http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.74-rc1.xz

and the diffstat can be found below.

thanks,
js

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

thanks,
-- Shuah