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


Groups > linux.kernel > #1600474 > unrolled thread

[PATCH 3.12 00/60] 3.12.72-stable review

Started byJiri Slaby <jslaby@suse.cz>
First post2017-03-14 15:30 +0100
Last post2017-03-14 15:30 +0100
Articles 2 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 3.12 00/60] 3.12.72-stable review Jiri Slaby <jslaby@suse.cz> - 2017-03-14 15:30 +0100
    [PATCH 3.12 01/60] md linear: fix a race between linear_add() and linear_congested() Jiri Slaby <jslaby@suse.cz> - 2017-03-14 15:30 +0100

#1600474 — [PATCH 3.12 00/60] 3.12.72-stable review

FromJiri Slaby <jslaby@suse.cz>
Date2017-03-14 15:30 +0100
Subject[PATCH 3.12 00/60] 3.12.72-stable review
Message-ID<tkUGu-Hf-33@gated-at.bofh.it>
This is the start of the stable review cycle for the 3.12.72 release.
There are 60 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 Thu Mar 16 14:14:28 CET 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.72-rc1.xz
and the diffstat can be found below.

thanks,
js

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


Alexander Popov (1):
  tty: n_hdlc: get rid of racy n_hdlc.tbuf

Arnaldo Carvalho de Melo (1):
  perf trace: Use the syscall raw_syscalls:sys_enter timestamp

Arnd Bergmann (1):
  staging: rtl: fix possible NULL pointer dereference

Chao Peng (1):
  KVM: VMX: use correct vmcs_read/write for guest segment selector/base

Christian Lamparter (1):
  ath9k: use correct OTP register offsets for the AR9340 and AR9550

Davidlohr Bueso (1):
  ipc/shm: Fix shmat mmap nil-page protection

Dmitry Tunin (1):
  Bluetooth: Add another AR3012 04ca:3018 device

Felix Fietkau (1):
  ath5k: drop bogus warning on drv_set_key with unsupported cipher

Feras Daoud (1):
  IB/ipoib: Fix deadlock between rmmod and set_mode

Guennadi Liakhovetski (1):
  uvcvideo: Fix a wrong macro

Hannes Reinecke (1):
  sd: get disk reference in sd_check_events()

Ian Abbott (1):
  serial: 8250_pci: Add MKS Tenta SCOM-0800 and SCOM-0801 cards

J. Bruce Fields (1):
  NFSv4: fix getacl head length estimation

James Cowgill (1):
  MIPS: OCTEON: Fix copy_from_user fault handling for large buffers

James Smart (1):
  scsi: lpfc: Correct WQ creation for pagesize

Jan Kara (1):
  ext4: trim allocation requests to group size

Jaroslav Kysela (1):
  ALSA: hda - fix Lewisburg audio issue

Jason Gunthorpe (1):
  RDMA/core: Fix incorrect structure packing for booleans

Jiri Slaby (1):
  TTY: n_hdlc, fix lockdep false positive

Julian Wiedmann (1):
  s390/qdio: clear DSCI prior to scanning multiple input queues

K. Y. Srinivasan (1):
  drivers: hv: Turn off write permission on the hypercall page

Long Li (3):
  scsi: storvsc: use tagged SRB requests if supported by the device
  scsi: storvsc: properly handle SRB_ERROR when sense message is present
  scsi: storvsc: properly set residual data length on errors

Marc Kleine-Budde (1):
  can: usb_8dev: Fix memory leak of priv->cmd_msg_buffer

Marcelo Ricardo Leitner (1):
  sctp: deny peeloff operation on asocs with threads sleeping on it

Martin Schwidefsky (1):
  s390: TASK_SIZE for kernel threads

Mathias Svensson (1):
  samples/seccomp: fix 64-bit comparison macros

Matt Chen (1):
  mac80211: flush delayed work when entering suspend

Max Filippov (1):
  xtensa: move parse_tag_fdt out of #ifdef CONFIG_BLK_DEV_INITRD

Michel Dänzer (1):
  drm/ttm: Make sure BOs being swapped out are cacheable

Miklos Szeredi (1):
  fuse: add missing FR_FORCE

OGAWA Hirofumi (1):
  fat: fix using uninitialized fields of fat_inode/fsinfo_inode

Paul Burton (6):
  MIPS: Clear ISA bit correctly in get_frame_info()
  MIPS: Prevent unaligned accesses during stack unwinding
  MIPS: Fix get_frame_info() handling of microMIPS function size
  MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions
  MIPS: Calculate microMIPS ra properly when unwinding the stack
  MIPS: Handle microMIPS jumps in the same way as MIPS32/MIPS64 jumps

Rafał Miłecki (1):
  bcma: use (get|put)_device when probing/removing device driver

Raghava Aditya Renukunta (1):
  scsi: aacraid: Reorder Adapter status check

Ralf Baechle (3):
  MIPS: Fix special case in 64 bit IP checksumming.
  MIPS: IP22: Reformat inline assembler code to modern standards.
  MIPS: IP22: Fix build error due to binutils 2.25 uselessnes.

Ravi Bangoria (1):
  powerpc/xmon: Fix data-breakpoint

Shmulik Ladkani (1):
  net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID
    frames

Steve Wise (1):
  rdma_cm: fail iwarp accepts w/o connection params

Steven Rostedt (VMware) (1):
  ktest: Fix child exit code processing

Takashi Iwai (2):
  ALSA: timer: Reject user params with too small ticks
  ALSA: seq: Fix link corruption by event error handling

Theodore Ts'o (3):
  jbd2: don't leak modified metadata buffers on an aborted journal
  ext4: preserve the needs_recovery flag when the journal is aborted
  ext4: return EROFS if device is r/o and journal replay is needed

Trond Myklebust (2):
  NFSv4: Fix memory and state leak in _nfs4_open_and_get_state
  nlm: Ensure callback code also checks that the files match

Vinayak Menon (1):
  mm: vmpressure: fix sending wrong events on underflow

Vitaly Kuznetsov (1):
  hv: allocate synic pages for all present CPUs

Weston Andros Adamson (1):
  NFSv4: fix getacl ERANGE for some ACL buffer sizes

Y.C. Chen (1):
  drm/ast: Fix test for VGA enabled

colyli@suse.de (1):
  md linear: fix a race between linear_add() and linear_congested()

 arch/mips/cavium-octeon/octeon-memcpy.S        |  20 ++--
 arch/mips/include/asm/checksum.h               |   2 +
 arch/mips/kernel/process.c                     | 153 ++++++++++++++++---------
 arch/mips/mm/sc-ip22.c                         |  54 +++++----
 arch/powerpc/kernel/hw_breakpoint.c            |   4 +-
 arch/s390/include/asm/processor.h              |   3 +-
 arch/x86/kvm/vmx.c                             |   2 +-
 arch/xtensa/kernel/setup.c                     |   4 +-
 drivers/bcma/main.c                            |   4 +
 drivers/bluetooth/ath3k.c                      |   2 +
 drivers/bluetooth/btusb.c                      |   1 +
 drivers/gpu/drm/ast/ast_post.c                 |   8 +-
 drivers/gpu/drm/ttm/ttm_bo.c                   |   4 +-
 drivers/hv/hv.c                                |   6 +-
 drivers/infiniband/core/cma.c                  |   3 +
 drivers/infiniband/ulp/ipoib/ipoib_cm.c        |  12 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c      |   6 +-
 drivers/md/linear.c                            |  29 ++++-
 drivers/md/linear.h                            |   1 +
 drivers/media/usb/uvc/uvc_queue.c              |   2 +-
 drivers/net/can/usb/usb_8dev.c                 |   9 +-
 drivers/net/wireless/ath/ath5k/mac80211-ops.c  |   3 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |   4 +-
 drivers/s390/cio/qdio_thinint.c                |   8 +-
 drivers/scsi/aacraid/src.c                     |  21 +++-
 drivers/scsi/lpfc/lpfc_hw4.h                   |   2 +
 drivers/scsi/lpfc/lpfc_sli.c                   |   9 +-
 drivers/scsi/sd.c                              |   9 +-
 drivers/scsi/storvsc_drv.c                     |  32 +++++-
 drivers/staging/rtl8188eu/core/rtw_recv.c      |   3 +
 drivers/staging/rtl8712/rtl871x_recv.c         |   7 +-
 drivers/tty/n_hdlc.c                           | 143 +++++++++++------------
 drivers/tty/serial/8250/8250_pci.c             |  13 +++
 fs/ext4/mballoc.c                              |   7 ++
 fs/ext4/super.c                                |   9 +-
 fs/fat/inode.c                                 |  13 ++-
 fs/fuse/file.c                                 |   1 +
 fs/jbd2/transaction.c                          |   4 +-
 fs/nfs/nfs4proc.c                              |  10 +-
 fs/nfs/nfs4xdr.c                               |   2 +-
 include/linux/lockd/lockd.h                    |   3 +-
 include/rdma/ib_sa.h                           |   6 +-
 ipc/shm.c                                      |  13 ++-
 mm/vmpressure.c                                |  10 +-
 net/mac80211/pm.c                              |   1 +
 net/sched/em_meta.c                            |   9 +-
 net/sctp/socket.c                              |   8 +-
 samples/seccomp/bpf-helper.h                   | 125 +++++++++++---------
 sound/core/seq/seq_fifo.c                      |   3 +
 sound/core/timer.c                             |  18 ++-
 sound/pci/hda/hda_intel.c                      |   4 +-
 tools/perf/builtin-trace.c                     |   4 +-
 tools/testing/ktest/ktest.pl                   |   2 +-
 53 files changed, 535 insertions(+), 300 deletions(-)

-- 
2.12.0

[toc] | [next] | [standalone]


#1600494 — [PATCH 3.12 01/60] md linear: fix a race between linear_add() and linear_congested()

FromJiri Slaby <jslaby@suse.cz>
Date2017-03-14 15:30 +0100
Subject[PATCH 3.12 01/60] md linear: fix a race between linear_add() and linear_congested()
Message-ID<tkUwN-Bf-3@gated-at.bofh.it>
In reply to#1600474
From: "colyli@suse.de" <colyli@suse.de>

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

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

commit 03a9e24ef2aaa5f1f9837356aed79c860521407a upstream.

Recently I receive a bug report that on Linux v3.0 based kerenl, hot add
disk to a md linear device causes kernel crash at linear_congested(). From
the crash image analysis, I find in linear_congested(), mddev->raid_disks
contains value N, but conf->disks[] only has N-1 pointers available. Then
a NULL pointer deference crashes the kernel.

There is a race between linear_add() and linear_congested(), RCU stuffs
used in these two functions cannot avoid the race. Since Linuv v4.0
RCU code is replaced by introducing mddev_suspend().  After checking the
upstream code, it seems linear_congested() is not called in
generic_make_request() code patch, so mddev_suspend() cannot provent it
from being called. The possible race still exists.

Here I explain how the race still exists in current code.  For a machine
has many CPUs, on one CPU, linear_add() is called to add a hard disk to a
md linear device; at the same time on other CPU, linear_congested() is
called to detect whether this md linear device is congested before issuing
an I/O request onto it.

Now I use a possible code execution time sequence to demo how the possible
race happens,

seq    linear_add()                linear_congested()
 0                                 conf=mddev->private
 1   oldconf=mddev->private
 2   mddev->raid_disks++
 3                              for (i=0; i<mddev->raid_disks;i++)
 4                                bdev_get_queue(conf->disks[i].rdev->bdev)
 5   mddev->private=newconf

In linear_add() mddev->raid_disks is increased in time seq 2, and on
another CPU in linear_congested() the for-loop iterates conf->disks[i] by
the increased mddev->raid_disks in time seq 3,4. But conf with one more
element (which is a pointer to struct dev_info type) to conf->disks[] is
not updated yet, accessing its structure member in time seq 4 will cause a
NULL pointer deference fault.

To fix this race, there are 2 parts of modification in the patch,
 1) Add 'int raid_disks' in struct linear_conf, as a copy of
    mddev->raid_disks. It is initialized in linear_conf(), always being
    consistent with pointers number of 'struct dev_info disks[]'. When
    iterating conf->disks[] in linear_congested(), use conf->raid_disks to
    replace mddev->raid_disks in the for-loop, then NULL pointer deference
    will not happen again.
 2) RCU stuffs are back again, and use kfree_rcu() in linear_add() to
    free oldconf memory. Because oldconf may be referenced as mddev->private
    in linear_congested(), kfree_rcu() makes sure that its memory will not
    be released until no one uses it any more.
Also some code comments are added in this patch, to make this modification
to be easier understandable.

This patch can be applied for kernels since v4.0 after commit:
3be260cc18f8 ("md/linear: remove rcu protections in favour of
suspend/resume"). But this bug is reported on Linux v3.0 based kernel, for
people who maintain kernels before Linux v4.0, they need to do some back
back port to this patch.

Changelog:
 - V3: add 'int raid_disks' in struct linear_conf, and use kfree_rcu() to
       replace rcu_call() in linear_add().
 - v2: add RCU stuffs by suggestion from Shaohua and Neil.
 - v1: initial effort.

Signed-off-by: Coly Li <colyli@suse.de>
Cc: Shaohua Li <shli@fb.com>
Cc: Neil Brown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/md/linear.c | 29 ++++++++++++++++++++++++++++-
 drivers/md/linear.h |  1 +
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index f03fabd2b37b..f169afac0266 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -97,6 +97,12 @@ static int linear_mergeable_bvec(struct request_queue *q,
 		return maxsectors << 9;
 }
 
+/*
+ * In linear_congested() conf->raid_disks is used as a copy of
+ * mddev->raid_disks to iterate conf->disks[], because conf->raid_disks
+ * and conf->disks[] are created in linear_conf(), they are always
+ * consitent with each other, but mddev->raid_disks does not.
+ */
 static int linear_congested(void *data, int bits)
 {
 	struct mddev *mddev = data;
@@ -109,7 +115,7 @@ static int linear_congested(void *data, int bits)
 	rcu_read_lock();
 	conf = rcu_dereference(mddev->private);
 
-	for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+	for (i = 0; i < conf->raid_disks && !ret ; i++) {
 		struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
 		ret |= bdi_congested(&q->backing_dev_info, bits);
 	}
@@ -196,6 +202,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
 			conf->disks[i-1].end_sector +
 			conf->disks[i].rdev->sectors;
 
+	/*
+	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
+	 * keep a copy of mddev->raid_disks in struct linear_conf is,
+	 * mddev->raid_disks may not be consistent with pointers number of
+	 * conf->disks[] when it is updated in linear_add() and used to
+	 * iterate old conf->disks[] earray in linear_congested().
+	 * Here conf->raid_disks is always consitent with number of
+	 * pointers in conf->disks[] array, and mddev->private is updated
+	 * with rcu_assign_pointer() in linear_addr(), such race can be
+	 * avoided.
+	 */
+	conf->raid_disks = raid_disks;
+
 	return conf;
 
 out:
@@ -252,10 +271,18 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
 	if (!newconf)
 		return -ENOMEM;
 
+	/* newconf->raid_disks already keeps a copy of * the increased
+	 * value of mddev->raid_disks, WARN_ONCE() is just used to make
+	 * sure of this. It is possible that oldconf is still referenced
+	 * in linear_congested(), therefore kfree_rcu() is used to free
+	 * oldconf until no one uses it anymore.
+	 */
 	oldconf = rcu_dereference_protected(mddev->private,
 					    lockdep_is_held(
 						    &mddev->reconfig_mutex));
 	mddev->raid_disks++;
+	WARN_ONCE(mddev->raid_disks != newconf->raid_disks,
+		"copied raid_disks doesn't match mddev->raid_disks");
 	rcu_assign_pointer(mddev->private, newconf);
 	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 	set_capacity(mddev->gendisk, mddev->array_sectors);
diff --git a/drivers/md/linear.h b/drivers/md/linear.h
index b685ddd7d7f7..8d392e6098b3 100644
--- a/drivers/md/linear.h
+++ b/drivers/md/linear.h
@@ -10,6 +10,7 @@ struct linear_conf
 {
 	struct rcu_head		rcu;
 	sector_t		array_sectors;
+	int			raid_disks; /* a copy of mddev->raid_disks */
 	struct dev_info		disks[0];
 };
 #endif
-- 
2.12.0

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web