linux-imx/block
Dan Williams 36d08048a7 block: fix del_gendisk() vs blkdev_ioctl crash
commit ac34f15e0c 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

Cc: Jan Kara <jack@suse.cz>
Cc: Jens Axboe <axboe@fb.com>
Reported-by: Robert Hu <robert.hu@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
2017-05-09 08:19:40 +02:00
..
partitions mac: validate mac_partition is within sector 2016-03-03 12:45:57 +01:00
blk-cgroup.c blkcg: fix gendisk reference leak in blkg_conf_prep() 2015-08-19 08:36:39 +02:00
blk-cgroup.h blkcg: fix use-after-free in __blkg_release_rcu() by making blkcg_gq refcnt an atomic_t 2014-07-18 15:51:04 +02:00
blk-core.c SCSI: Fix NULL pointer dereference in runtime PM 2016-02-24 10:23:26 +01:00
blk-exec.c If the queue is dying then we only call the rq->end_io callout. 2013-09-18 08:33:55 -06:00
blk-flush.c Block: blk-flush: Fixed indent code style 2013-03-22 12:22:51 -06:00
blk-integrity.c scatterlist: introduce sg_unmark_end 2013-03-20 15:43:04 +10:30
blk-ioc.c lib/radix-tree.c: make radix_tree_node_alloc() work correctly within interrupt 2013-09-11 15:59:36 -07:00
blk-iopoll.c block: delete __cpuinit usage from all block files 2013-07-14 19:36:59 -04:00
blk-lib.c block: add cond_resched() to potentially long running ioctl discard loop 2014-02-22 13:32:28 -08:00
blk-map.c block: re-use existing 'reading' variable instead of checking direction again 2011-12-21 15:27:24 +01:00
blk-merge.c scatterlist: introduce sg_unmark_end 2013-03-20 15:43:04 +10:30
blk-settings.c block: fix alignment_offset math that assumes io_min is a power-of-2 2014-11-13 19:02:21 +01:00
blk-softirq.c block: delete __cpuinit usage from all block files 2013-07-14 19:36:59 -04:00
blk-sysfs.c block/blk-sysfs.c: replace strict_strtoul() with kstrtoul() 2013-09-11 15:56:56 -07:00
blk-tag.c block: don't assume last put of shared tags is for the host 2014-07-30 11:15:55 +02:00
blk-throttle.c blk-throttle: check stats_cpu before reading it from sysfs 2015-03-05 15:37:11 +01:00
blk-timeout.c block: fix race between request completion and timeout handling 2013-11-29 11:28:06 -08:00
blk.h block: __elv_next_request() shouldn't call into the elevator if bypassing 2014-02-22 13:32:28 -08:00
bsg-lib.c bsg: Remove unused function bsg_goose_queue() 2012-12-06 14:33:02 +01:00
bsg.c sg_write()/bsg_write() is not fit to be called under KERNEL_DS 2017-01-26 17:39:15 +01:00
cfq-iosched.c cfq: fix starvation of asynchronous writes 2016-10-25 18:11:20 +02:00
cmdline-parser.c block: support embedded device command line partition 2013-09-11 15:56:57 -07:00
compat_ioctl.c block: provide compat ioctl for BLKZEROOUT 2014-07-30 11:15:55 +02:00
deadline-iosched.c block: Convert kmalloc_node(...GFP_ZERO...) to kzalloc_node(...) 2013-09-11 13:22:03 -06:00
elevator.c elevator: acquire q->sysfs_lock in elevator_change() 2013-12-08 07:29:16 -08:00
genhd.c block: fix del_gendisk() vs blkdev_ioctl crash 2017-05-09 08:19:40 +02:00
ioctl.c Merge branch 'for-3.7/core' of git://git.kernel.dk/linux-block 2012-10-11 09:04:23 +09:00
Kconfig block: change config option name for cmdline partition parsing 2013-09-30 14:31:02 -07:00
Kconfig.iosched blkcg: make CONFIG_BLK_CGROUP bool 2012-03-06 21:27:21 +01:00
Makefile block: change config option name for cmdline partition parsing 2013-09-30 14:31:02 -07:00
noop-iosched.c elevator: Fix a race in elevator switching 2013-07-03 13:25:24 +02:00
partition-generic.c block: Fix dev_t minor allocation lifetime 2014-10-13 15:41:19 +02:00
scsi_ioctl.c block: allow WRITE_SAME commands with the SG_IO ioctl 2017-04-07 10:38:28 +02:00