• Yufen Yu's avatar
    md: fix NULL dereference of mddev->pers in remove_and_add_spares() · c42a0e26
    Yufen Yu authored
    We met NULL pointer BUG as follow:
    
    [  151.760358] BUG: unable to handle kernel NULL pointer dereference at 0000000000000060
    [  151.761340] PGD 80000001011eb067 P4D 80000001011eb067 PUD 1011ea067 PMD 0
    [  151.762039] Oops: 0000 [#1] SMP PTI
    [  151.762406] Modules linked in:
    [  151.762723] CPU: 2 PID: 3561 Comm: mdadm-test Kdump: loaded Not tainted 4.17.0-rc1+ #238
    [  151.763542] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1.fc26 04/01/2014
    [  151.764432] RIP: 0010:remove_and_add_spares.part.56+0x13c/0x3a0
    [  151.765061] RSP: 0018:ffffc90001d7fcd8 EFLAGS: 00010246
    [  151.765590] RAX: 0000000000000000 RBX: ffff88013601d600 RCX: 0000000000000000
    [  151.766306] RDX: 0000000000000000 RSI: ffff88013601d600 RDI: ffff880136187000
    [  151.767014] RBP: ffff880136187018 R08: 0000000000000003 R09: 0000000000000051
    [  151.767728] R10: ffffc90001d7fed8 R11: 0000000000000000 R12: ffff88013601d600
    [  151.768447] R13: ffff8801298b1300 R14: ffff880136187000 R15: 0000000000000000
    [  151.769160] FS:  00007f2624276700(0000) GS:ffff88013ae80000(0000) knlGS:0000000000000000
    [  151.769971] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  151.770554] CR2: 0000000000000060 CR3: 0000000111aac000 CR4: 00000000000006e0
    [  151.771272] Call Trace:
    [  151.771542]  md_ioctl+0x1df2/0x1e10
    [  151.771906]  ? __switch_to+0x129/0x440
    [  151.772295]  ? __schedule+0x244/0x850
    [  151.772672]  blkdev_ioctl+0x4bd/0x970
    [  151.773048]  block_ioctl+0x39/0x40
    [  151.773402]  do_vfs_ioctl+0xa4/0x610
    [  151.773770]  ? dput.part.23+0x87/0x100
    [  151.774151]  ksys_ioctl+0x70/0x80
    [  151.774493]  __x64_sys_ioctl+0x16/0x20
    [  151.774877]  do_syscall_64+0x5b/0x180
    [  151.775258]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    For raid6, when two disk of the array are offline, two spare disks can
    be added into the array. Before spare disks recovery completing,
    system reboot and mdadm thinks it is ok to restart the degraded
    array by md_ioctl(). Since disks in raid6 is not only_parity(),
    raid5_run() will abort, when there is no PPL feature or not setting
    'start_dirty_degraded' parameter. Therefore, mddev->pers is NULL.
    
    But, mddev->raid_disks has been set and it will not be cleared when
    raid5_run abort. md_ioctl() can execute cmd 'HOT_REMOVE_DISK' to
    remove a disk by mdadm, which will cause NULL pointer dereference
    in remove_and_add_spares() finally.
    Signed-off-by: default avatarYufen Yu <yuyufen@huawei.com>
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    c42a0e26
md.c 245 KB