linux/drivers/ide
Aristeu Rozanski b5e1a4e286 ide-io: set REQ_FAILED when drive is dead
Currently it's possible to ide-cd to set an incorrect blocksize by
reading garbage if the drive is dead:

ide_cd_probe()
 -> cdrom_read_toc()
     -> cdrom_read_capacity()
         -> cdrom_queue_packet_command()
             -> ide_do_drive_cmd()
                 -> ide_do_request()
                     -> start_request()

on start_request():

        /* bail early if we've exceeded max_failures */
        if (drive->max_failures && (drive->failures > drive->max_failures)) {
                goto kill_rq;
        }
(...)
kill_rq:
        ide_kill_rq(drive, rq);
        return ide_stopped;

ide_kill_rq() and the next calls won't set REQ_FAILED on rq->cmd_flags and thus
cdrom_queue_packet_command() won't return an error. then:

        stat = cdrom_queue_packet_command(drive, &req);
        if (stat == 0) {
                *capacity = 1 + be32_to_cpu(capbuf.lba);
                *sectors_per_frame =
                        be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
        }

cdrom_read_capacity() ends believing capbuf is valid but in fact it's just
uninitialized data. back to cdrom_read_toc():

        /* Try to get the total cdrom capacity and sector size. */
        stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
                                   sense);
        if (stat)
                toc->capacity = 0x1fffff;

        set_capacity(info->disk, toc->capacity * sectors_per_frame);
        /* Save a private copy of te TOC capacity for error handling */
        drive->probed_capacity = toc->capacity * sectors_per_frame;

        blk_queue_hardsect_size(drive->queue,
                                sectors_per_frame << SECTOR_BITS);

that will set drive->queue->hardsect_size to be the random value.
hardsect_size is used to calculate inode->i_blkbits. later on, on a read
path:

void create_empty_buffers(struct page *page,
                        unsigned long blocksize, unsigned long b_state)
{       
        struct buffer_head *bh, *head, *tail;

        head = alloc_page_buffers(page, blocksize, 1);
        bh = head;
        do {    
                bh->b_state |= b_state;
                tail = bh;
                bh = bh->b_this_page;
        } while (bh);
        tail->b_this_page = head;

alloc_page_buffers() will return NULL if blocksize > 4096. blocksize is
calculed based on inode->i_blkbits. that will trigger a null
dereference on create_empty_buffers().

Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
Cc: Borislav Petkov <bbpetkov@yahoo.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-01-25 22:17:04 +01:00
..
arm ide/arm/icside: fallout from commit 86f3a492bb 2007-10-27 22:18:11 -07:00
cris ide-cris: don't override ide_register_hw() result 2007-11-27 21:35:55 +01:00
h8300 icside: use ec->dma directly 2007-10-20 00:32:32 +02:00
legacy ali14xx: constify __initdata 2007-11-27 21:35:57 +01:00
mips [SG] Update drivers to use sg helpers 2007-10-22 21:19:53 +02:00
pci trm290: do hook dma_host_{on,off} methods (take 2) 2008-01-10 23:03:42 +01:00
ppc drivers/ide: Add missing "space" 2007-11-27 21:35:55 +01:00
ide-acpi.c IDE: terminate ACPI DMI list 2008-01-11 11:42:07 -08:00
ide-cd.c ide-cd: fix 'ireason' reporting in cdrom_pc_intr() 2007-12-24 15:23:44 +01:00
ide-cd.h ide-cd: fix SAMSUNG CD-ROM SCR-3231 quirk 2007-12-24 15:23:43 +01:00
ide-disk.c ide: remove stale changelog from ide-disk.c 2007-12-12 23:32:00 +01:00
ide-dma.c ide: remove dead code from __ide_dma_test_irq() 2007-12-12 23:32:00 +01:00
ide-floppy.c Fixup rq_for_each_segment() indentation 2007-10-10 09:25:56 +02:00
ide-generic.c ide: add ide_proc_register_port() 2007-05-10 00:01:11 +02:00
ide-io.c ide-io: set REQ_FAILED when drive is dead 2008-01-25 22:17:04 +01:00
ide-iops.c ide: fix cable detection for SATA bridges 2008-01-10 23:03:42 +01:00
ide-lib.c ide: DMA reporting and validity checking fixes (take 3) 2007-12-12 23:31:58 +01:00
ide-pnp.c icside: use ec->dma directly 2007-10-20 00:32:32 +02:00
ide-probe.c Driver core: convert block from raw kobjects to core devices 2008-01-24 20:40:36 -08:00
ide-proc.c ide: add ide_device_add() 2007-10-20 00:32:31 +02:00
ide-tape.c IDE: Convert from class_device to device for ide-tape 2008-01-24 20:40:05 -08:00
ide-taskfile.c ide: add missing #ifdef/#endif CONFIG_IDE_TASK_IOCTL 2007-11-05 21:42:27 +01:00
ide-timing.h ide: remove ide_find_best_pio_mode() 2007-07-20 01:11:58 +02:00
ide.c ide: fix ->io_32bit race in set_io_32bit() 2007-12-12 23:32:00 +01:00
Kconfig ide: deprecate CONFIG_BLK_DEV_OFFBOARD 2007-12-12 23:31:57 +01:00
Makefile ide: add CONFIG_IDE_H8300 config option 2007-11-27 21:35:54 +01:00
setup-pci.c ide: coding style fixes for drivers/ide/setup-pci.c 2007-12-12 23:31:57 +01:00