[patch 11/29] ide-cd: fix oops when using growisofs

From: Greg KH
Date: Wed Jul 30 2008 - 19:36:37 EST


2.6.25-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jens Axboe <jens.axboe@xxxxxxxxxx>

commit e8e7b9eb11c34ee18bde8b7011af41938d1ad667 upstream

cdrom_read_capacity() will blindly return the capacity from the device
without sanity-checking it. This later causes code in fs/buffer.c to
oops.

Fix this by checking that the device is telling us sensible things.

From: Jens Axboe <jens.axboe@xxxxxxxxxx>
Cc: Michael Buesch <mb@xxxxxxxxx>
Cc: Jan Kara <jack@xxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Borislav Petkov <petkovbb@xxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
[bart: print device name instead of driver name]
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@xxxxxxxxx>
[harvey: blocklen is a big-endian value]
Signed-off-by: Harvey Harrison <harvey.harrison@xxxxxxxxx>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

---
drivers/ide/ide-cd.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1421,13 +1421,30 @@ static int cdrom_read_capacity(ide_drive
req.cmd_flags |= REQ_QUIET;

stat = ide_cd_queue_pc(drive, &req);
- if (stat == 0) {
- *capacity = 1 + be32_to_cpu(capbuf.lba);
- *sectors_per_frame =
- be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
+ if (stat)
+ return stat;
+
+ /*
+ * Sanity check the given block size
+ */
+ switch (capbuf.blocklen) {
+ case __constant_cpu_to_be32(512):
+ case __constant_cpu_to_be32(1024):
+ case __constant_cpu_to_be32(2048):
+ case __constant_cpu_to_be32(4096):
+ break;
+ default:
+ printk(KERN_ERR "%s: weird block size %u\n",
+ drive->name, capbuf.blocklen);
+ printk(KERN_ERR "%s: default to 2kb block size\n",
+ drive->name);
+ capbuf.blocklen = __constant_cpu_to_be32(2048);
+ break;
}

- return stat;
+ *capacity = 1 + be32_to_cpu(capbuf.lba);
+ *sectors_per_frame = be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
+ return 0;
}

static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,

--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/