linux/drivers/block
Dongsheng Yang 23edca8649 rbd: flush rbd_dev->watch_dwork after watch is unregistered
There is a problem if we are going to unmap a rbd device and the
watch_dwork is going to queue delayed work for watch:

unmap Thread                    watch Thread                  timer
do_rbd_remove
  cancel_tasks_sync(rbd_dev)
                                queue_delayed_work for watch
  destroy_workqueue(rbd_dev->task_wq)
    drain_workqueue(wq)
    destroy other resources in wq
                                                              call_timer_fn
                                                                __queue_work()

Then the delayed work escape the cancel_tasks_sync() and
destroy_workqueue() and we will get an user-after-free call trace:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
  PGD 0 P4D 0
  Oops: 0000 [#1] SMP PTI
  Modules linked in:
  CPU: 7 PID: 0 Comm: swapper/7 Tainted: G           OE     4.17.0-rc6+ #13
  Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
  RIP: 0010:__queue_work+0x6a/0x3b0
  RSP: 0018:ffff9427df1c3e90 EFLAGS: 00010086
  RAX: ffff9427deca8400 RBX: 0000000000000000 RCX: 0000000000000000
  RDX: ffff9427deca8400 RSI: ffff9427df1c3e50 RDI: 0000000000000000
  RBP: ffff942783e39e00 R08: ffff9427deca8400 R09: ffff9427df1c3f00
  R10: 0000000000000004 R11: 0000000000000005 R12: ffff9427cfb85970
  R13: 0000000000002000 R14: 000000000001eca0 R15: 0000000000000007
  FS:  0000000000000000(0000) GS:ffff9427df1c0000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000000000000000 CR3: 00000004c900a005 CR4: 00000000000206e0
  Call Trace:
   <IRQ>
   ? __queue_work+0x3b0/0x3b0
   call_timer_fn+0x2d/0x130
   run_timer_softirq+0x16e/0x430
   ? tick_sched_timer+0x37/0x70
   __do_softirq+0xd2/0x280
   irq_exit+0xd5/0xe0
   smp_apic_timer_interrupt+0x6c/0x130
   apic_timer_interrupt+0xf/0x20

[ Move rbd_dev->watch_dwork cancellation so that rbd_reregister_watch()
  either bails out early because the watch is UNREGISTERED at that point
  or just gets cancelled. ]

Cc: stable@vger.kernel.org
Fixes: 99d1694310 ("rbd: retry watch re-registration periodically")
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2018-06-04 20:46:02 +02:00
..
aoe aoe: use ktime_t instead of timeval 2018-01-17 08:41:07 -07:00
drbd block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
mtip32xx mtip32xx: Use the blk_queue_flag_*() functions 2018-03-08 14:13:48 -07:00
paride cdrom: do not call check_disk_change() inside cdrom_open() 2018-03-09 08:06:35 -07:00
rsxx block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
xen-blkback Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block 2017-09-07 11:59:42 -07:00
zram Merge branch 'akpm' (patches from Andrew) 2018-04-06 14:19:26 -07:00
amiflop.c genhd: Rename get_disk() to get_disk_and_module() 2018-02-26 09:48:42 -07:00
ataflop.c genhd: Rename get_disk() to get_disk_and_module() 2018-02-26 09:48:42 -07:00
brd.c block: Move SECTOR_SIZE and SECTOR_SHIFT definitions into <linux/blkdev.h> 2018-03-17 14:45:23 -06:00
cryptoloop.c block: cryptoloop - Fix build warning 2017-09-26 07:41:22 -06:00
DAC960.c pci-v4.16-changes 2018-02-06 09:59:40 -08:00
DAC960.h block: DAC960: Replace PCI pool old API 2018-01-02 16:09:50 -06:00
floppy.c genhd: Rename get_disk() to get_disk_and_module() 2018-02-26 09:48:42 -07:00
Kconfig null_blk: remove explicit 'select FAULT_INJECTION' 2018-01-11 07:58:31 -07:00
loop.c loop: clear wb_err in bd_inode when detaching backing file 2018-05-21 12:36:03 -06:00
loop.h loop: remove cmd->rq member 2018-04-14 22:34:27 -06: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 block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
null_blk.c block: Move SECTOR_SIZE and SECTOR_SHIFT definitions into <linux/blkdev.h> 2018-03-17 14:45:23 -06:00
pktcdvd.c block: fix a typo 2018-03-01 08:41:27 -07: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_types.h rbd: RBD_V{1,2}_DATA_FORMAT macros 2017-02-20 12:16:15 +01:00
rbd.c rbd: flush rbd_dev->watch_dwork after watch is unregistered 2018-06-04 20:46:02 +02:00
skd_main.c block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
skd_s1120.h skd: Use __packed only when needed 2017-08-18 08:45:29 -06:00
sunvdc.c treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
swim3.c block/swim: Rename macros to avoid inconsistent inverted logic 2018-04-16 21:49:35 -06:00
swim_asm.S
swim.c block/swim: Select appropriate drive on device open 2018-04-16 21:49:35 -06:00
sx8.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
umem.c block: Fix a race between the cgroup code and request queue initialization 2018-02-28 12:23:35 -07:00
umem.h
virtio_blk.c virtio, vhost: fixes, cleanups, features 2018-02-08 10:41:00 -08:00
xen-blkfront.c for-4.17/block-20180402 2018-04-05 14:27:02 -07:00
xsysace.c treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
z2ram.c genhd: Rename get_disk() to get_disk_and_module() 2018-02-26 09:48:42 -07:00