• Nicholas Bellinger's avatar
    target: Avoid mappedlun symlink creation during lun shutdown · 49cb77e2
    Nicholas Bellinger authored
    This patch closes a race between se_lun deletion during configfs
    unlink in target_fabric_port_unlink() -> core_dev_del_lun()
    -> core_tpg_remove_lun(), when transport_clear_lun_ref() blocks
    waiting for percpu_ref RCU grace period to finish, but a new
    NodeACL mappedlun is added before the RCU grace period has
    completed.
    
    This can happen in target_fabric_mappedlun_link() because it
    only checks for se_lun->lun_se_dev, which is not cleared until
    after transport_clear_lun_ref() percpu_ref RCU grace period
    finishes.
    
    This bug originally manifested as NULL pointer dereference
    OOPsen in target_stat_scsi_att_intr_port_show_attr_dev() on
    v4.1.y code, because it dereferences lun->lun_se_dev without
    a explicit NULL pointer check.
    
    In post v4.1 code with target-core RCU conversion, the code
    in target_stat_scsi_att_intr_port_show_attr_dev() no longer
    uses se_lun->lun_se_dev, but the same race still exists.
    
    To address the bug, go ahead and set se_lun>lun_shutdown as
    early as possible in core_tpg_remove_lun(), and ensure new
    NodeACL mappedlun creation in target_fabric_mappedlun_link()
    fails during se_lun shutdown.
    Reported-by: default avatarJames Shen <jcs@datera.io>
    Cc: James Shen <jcs@datera.io>
    Tested-by: default avatarJames Shen <jcs@datera.io>
    Cc: stable@vger.kernel.org # 3.10+
    Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
    49cb77e2
target_core_base.h 26.8 KB