linux-stable/drivers/block
Stefan Hajnoczi 30f4ac2c49 virtio-blk: handle block_device_operations callbacks after hot unplug
[ Upstream commit 90b5feb8c4 ]

A userspace process holding a file descriptor to a virtio_blk device can
still invoke block_device_operations after hot unplug.  This leads to a
use-after-free accessing vblk->vdev in virtblk_getgeo() when
ioctl(HDIO_GETGEO) is invoked:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000090
  IP: [<ffffffffc00e5450>] virtio_check_driver_offered_feature+0x10/0x90 [virtio]
  PGD 800000003a92f067 PUD 3a930067 PMD 0
  Oops: 0000 [#1] SMP
  CPU: 0 PID: 1310 Comm: hdio-getgeo Tainted: G           OE  ------------   3.10.0-1062.el7.x86_64 #1
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
  task: ffff9be5fbfb8000 ti: ffff9be5fa890000 task.ti: ffff9be5fa890000
  RIP: 0010:[<ffffffffc00e5450>]  [<ffffffffc00e5450>] virtio_check_driver_offered_feature+0x10/0x90 [virtio]
  RSP: 0018:ffff9be5fa893dc8  EFLAGS: 00010246
  RAX: ffff9be5fc3f3400 RBX: ffff9be5fa893e30 RCX: 0000000000000000
  RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff9be5fbc10b40
  RBP: ffff9be5fa893dc8 R08: 0000000000000301 R09: 0000000000000301
  R10: 0000000000000000 R11: 0000000000000000 R12: ffff9be5fdc24680
  R13: ffff9be5fbc10b40 R14: ffff9be5fbc10480 R15: 0000000000000000
  FS:  00007f1bfb968740(0000) GS:ffff9be5ffc00000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000000000000090 CR3: 000000003a894000 CR4: 0000000000360ff0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  Call Trace:
   [<ffffffffc016ac37>] virtblk_getgeo+0x47/0x110 [virtio_blk]
   [<ffffffff8d3f200d>] ? handle_mm_fault+0x39d/0x9b0
   [<ffffffff8d561265>] blkdev_ioctl+0x1f5/0xa20
   [<ffffffff8d488771>] block_ioctl+0x41/0x50
   [<ffffffff8d45d9e0>] do_vfs_ioctl+0x3a0/0x5a0
   [<ffffffff8d45dc81>] SyS_ioctl+0xa1/0xc0

A related problem is that virtblk_remove() leaks the vd_index_ida index
when something still holds a reference to vblk->disk during hot unplug.
This causes virtio-blk device names to be lost (vda, vdb, etc).

Fix these issues by protecting vblk->vdev with a mutex and reference
counting vblk so the vd_index_ida index can be removed in all cases.

Fixes: 48e4043d45 ("virtio: add virtio disk geometry feature")
Reported-by: Lance Digby <ldigby@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Link: https://lore.kernel.org/r/20200430140442.171016-1-stefanha@redhat.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-05-20 08:17:05 +02:00
..
aoe block: don't set bounce limit in blk_init_queue 2017-06-27 12:13:45 -06:00
drbd signal: Allow cifs and drbd to receive their terminating signals 2020-01-27 14:46:43 +01:00
mtip32xx License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
paride cdrom: do not call check_disk_change() inside cdrom_open() 2018-05-30 07:52:34 +02:00
rsxx rsxx: add missed destroy_workqueue calls in remove 2019-12-17 20:37:30 +01:00
xen-blkback xen/blkback: Avoid unmapping unmapped grant pages 2020-01-09 10:17:59 +01:00
zram zram: fix race between backing_dev_show and backing_dev_store 2019-11-06 12:42:50 +01:00
amiflop.c amiflop: clean up on errors during setup 2019-12-01 09:13:26 +01:00
ataflop.c ataflop: fix error handling during setup 2018-11-13 11:14:51 -08:00
brd.c brd: check and limit max_part par 2020-02-28 16:36:08 +01:00
cryptoloop.c
DAC960.c block: DAC960: shut up format-overflow warning 2017-07-29 09:00:03 -06:00
DAC960.h
floppy.c floppy: check FDC index for errors before assigning it 2020-02-28 16:36:10 +01:00
Kconfig License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
loop.c loop: fix no-unmap write-zeroes request behavior 2019-12-31 12:37:18 +01:00
loop.h Revert "block/loop: Use global lock for ioctl() operation." 2019-05-02 09:40:33 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nbd.c nbd: add a flush_workqueue in nbd_start_device 2020-02-28 16:35:58 +01:00
null_blk.c null_blk: fix spurious IO errors after failed past-wp access 2020-04-24 08:00:25 +02:00
pktcdvd.c pktcdvd: remove warning on attempting to register non-passthrough dev 2019-10-07 18:55:13 +02:00
ps3disk.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
ps3vram.c block/ps3vram: Check return of ps3vram_cache_init 2017-08-17 23:03:44 +10:00
rbd.c rbd: call rbd_dev_unprobe() after unwatching and flushing notifies 2020-04-24 08:01:16 +02:00
rbd_types.h rbd: RBD_V{1,2}_DATA_FORMAT macros 2017-02-20 12:16:15 +01:00
skd_main.c skd: fixup usage of legacy IO API 2019-12-01 09:13:20 +01:00
skd_s1120.h skd: Use __packed only when needed 2017-08-18 08:45:29 -06:00
smart1,2.h
sunvdc.c sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN 2019-02-12 19:46:00 +01:00
swim.c swim: fix cleanup on setup error 2018-11-13 11:14:52 -08:00
swim3.c block/swim3: Fix -EBUSY error when re-opening device after unmount 2019-02-12 19:46:09 +01:00
swim_asm.S
sx8.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
umem.c blk: remove bio_set arg from blk_queue_split() 2017-06-18 12:40:59 -06:00
umem.h
virtio_blk.c virtio-blk: handle block_device_operations callbacks after hot unplug 2020-05-20 08:17:05 +02:00
xen-blkfront.c xen/blkfront: Adjust indentation in xlvbd_alloc_gendisk 2020-01-23 08:20:35 +01:00
xsysace.c xsysace: Fix error handling in ace_setup 2019-05-08 07:20:51 +02:00
z2ram.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00