aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBorislav Petkov <bp@alien8.de>2010-07-06 00:23:52 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-09 06:17:49 -0400
commit110712828365ccafcc61a7f4db44c31ed4cf8793 (patch)
treef4c5014dab0cd1e66881eeb86286cacc0203e4fa /drivers/ide
parent45d7f32c7a43cbb9592886d38190e379e2eb2226 (diff)
ide-cd: Do not access completed requests in the irq handler
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. Cc: <stable@kernel.org> # 32.x 33.x 34.x Signed-off-by: Borislav Petkov <bp@alien8.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ide')
-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,
506 return (flags & REQ_FAILED) ? -EIO : 0; 506 return (flags & REQ_FAILED) ? -EIO : 0;
507} 507}
508 508
509static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) 509/*
510 * returns true if rq has been completed
511 */
512static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
510{ 513{
511 unsigned int nr_bytes = cmd->nbytes - cmd->nleft; 514 unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
512 515
513 if (cmd->tf_flags & IDE_TFLAG_WRITE) 516 if (cmd->tf_flags & IDE_TFLAG_WRITE)
514 nr_bytes -= cmd->last_xfer_len; 517 nr_bytes -= cmd->last_xfer_len;
515 518
516 if (nr_bytes > 0) 519 if (nr_bytes > 0) {
517 ide_complete_rq(drive, 0, nr_bytes); 520 ide_complete_rq(drive, 0, nr_bytes);
521 return true;
522 }
523
524 return false;
518} 525}
519 526
520static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) 527static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
@@ -679,7 +686,8 @@ out_end:
679 } 686 }
680 687
681 if (uptodate == 0 && rq->bio) 688 if (uptodate == 0 && rq->bio)
682 ide_cd_error_cmd(drive, cmd); 689 if (ide_cd_error_cmd(drive, cmd))
690 return ide_stopped;
683 691
684 /* make sure it's fully ended */ 692 /* make sure it's fully ended */
685 if (blk_fs_request(rq) == 0) { 693 if (blk_fs_request(rq) == 0) {