浏览代码

libata: fix NULL sdev dereference race in atapi_qc_complete()

SCSI commands may be issued between __scsi_add_device() and dev->sdev
assignment, so it's unsafe for ata_qc_complete() to dereference
dev->sdev->locked without checking whether it's NULL or not.  Fix it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@kernel.org
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Tejun Heo 14 年之前
父节点
当前提交
2a5f07b5ec
共有 1 个文件被更改,包括 4 次插入1 次删除
  1. 4 1
      drivers/ata/libata-scsi.c

+ 4 - 1
drivers/ata/libata-scsi.c

@@ -2552,8 +2552,11 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
 		 *
 		 *
 		 * If door lock fails, always clear sdev->locked to
 		 * If door lock fails, always clear sdev->locked to
 		 * avoid this infinite loop.
 		 * avoid this infinite loop.
+		 *
+		 * This may happen before SCSI scan is complete.  Make
+		 * sure qc->dev->sdev isn't NULL before dereferencing.
 		 */
 		 */
-		if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
+		if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
 			qc->dev->sdev->locked = 0;
 			qc->dev->sdev->locked = 0;
 
 
 		qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
 		qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;