summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBorislav Petkov <bp@alien8.de>2010-07-05 21:23:52 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-13 13:19:36 -0700
commite943138e4de074176e4c02909f4618cfd11a49d1 (patch)
tree6e81bef75f289887de2f5c051294362f894618d2 /drivers
parent20ae44fa9a6384c5340193a75def7ef8a2a380ec (diff)
ide-cd: Do not access completed requests in the irq handler
commit 110712828365ccafcc61a7f4db44c31ed4cf8793 upstream. ide_cd_error_cmd() can complete an erroneous request with leftover buffers. Signal this with its return value so that the request is not accessed after its completion in the irq handler and we oops. Signed-off-by: Borislav Petkov <bp@alien8.de> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/ide-cd.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 64207df8da82..2de76cc08f61 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -506,15 +506,22 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
+/*
+ * returns true if rq has been completed
+ */
+static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
if (cmd->tf_flags & IDE_TFLAG_WRITE)
nr_bytes -= cmd->last_xfer_len;
- if (nr_bytes > 0)
+ if (nr_bytes > 0) {
ide_complete_rq(drive, 0, nr_bytes);
+ return true;
+ }
+
+ return false;
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
@@ -679,7 +686,8 @@ out_end:
}
if (uptodate == 0 && rq->bio)
- ide_cd_error_cmd(drive, cmd);
+ if (ide_cd_error_cmd(drive, cmd))
+ return ide_stopped;
/* make sure it's fully ended */
if (blk_fs_request(rq) == 0) {