• Hou Tao's avatar
    dm: fix race between dm_get_from_kobject() and __dm_destroy() · 4e82464a
    Hou Tao authored
    commit b9a41d21 upstream.
    
    The following BUG_ON was hit when testing repeat creation and removal of
    DM devices:
    
        kernel BUG at drivers/md/dm.c:2919!
        CPU: 7 PID: 750 Comm: systemd-udevd Not tainted 4.1.44
        Call Trace:
         [<ffffffff81649e8b>] dm_get_from_kobject+0x34/0x3a
         [<ffffffff81650ef1>] dm_attr_show+0x2b/0x5e
         [<ffffffff817b46d1>] ? mutex_lock+0x26/0x44
         [<ffffffff811df7f5>] sysfs_kf_seq_show+0x83/0xcf
         [<ffffffff811de257>] kernfs_seq_show+0x23/0x25
         [<ffffffff81199118>] seq_read+0x16f/0x325
         [<ffffffff811de994>] kernfs_fop_read+0x3a/0x13f
         [<ffffffff8117b625>] __vfs_read+0x26/0x9d
         [<ffffffff8130eb59>] ? security_file_permission+0x3c/0x44
         [<ffffffff8117bdb8>] ? rw_verify_area+0x83/0xd9
         [<ffffffff8117be9d>] vfs_read+0x8f/0xcf
         [<ffffffff81193e34>] ? __fdget_pos+0x12/0x41
         [<ffffffff8117c686>] SyS_read+0x4b/0x76
         [<ffffffff817b606e>] system_call_fastpath+0x12/0x71
    
    The bug can be easily triggered, if an extra delay (e.g. 10ms) is added
    between the test of DMF_FREEING & DMF_DELETING and dm_get() in
    dm_get_from_kobject().
    
    To fix it, we need to ensure the test of DMF_FREEING & DMF_DELETING and
    dm_get() are done in an atomic way, so _minor_lock is used.
    
    The other callers of dm_get() have also been checked to be OK: some
    callers invoke dm_get() under _minor_lock, some callers invoke it under
    _hash_lock, and dm_start_request() invoke it after increasing
    md->open_count.
    Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    4e82464a
dm.c 86.9 KB