| From 5fab6d70584d4b9228283e27901c6dd97fd4555d Mon Sep 17 00:00:00 2001 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Mon, 1 Nov 2010 11:39:19 +0100 |
| Subject: [PATCH] libata: fix NULL sdev dereference race in |
| atapi_qc_complete() |
| |
| commit 2a5f07b5ec098edc69e05fdd2f35d3fbb1235723 upstream. |
| |
| 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> |
| Signed-off-by: Jeff Garzik <jgarzik@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c |
| index 0088cde..1d266e2 100644 |
| --- a/drivers/ata/libata-scsi.c |
| +++ b/drivers/ata/libata-scsi.c |
| @@ -2548,8 +2548,11 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) |
| * |
| * If door lock fails, always clear sdev->locked to |
| * 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->scsicmd->result = SAM_STAT_CHECK_CONDITION; |
| -- |
| 1.7.4.4 |
| |