| From 2a5f07b5ec098edc69e05fdd2f35d3fbb1235723 Mon Sep 17 00:00:00 2001 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Mon, 1 Nov 2010 11:39:19 +0100 |
| Subject: libata: fix NULL sdev dereference race in atapi_qc_complete() |
| |
| From: Tejun Heo <tj@kernel.org> |
| |
| 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: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/ata/libata-scsi.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/ata/libata-scsi.c |
| +++ b/drivers/ata/libata-scsi.c |
| @@ -2547,8 +2547,11 @@ static void atapi_qc_complete(struct ata |
| * |
| * 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; |