diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-12 04:37:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-12 04:37:58 -0700 |
commit | 15aeed9352711084abde5f6b4cd4e0b29f5f83ba (patch) | |
tree | 3f9594b7f27d42565bb4007e3c2a46bfead6e846 /drivers | |
parent | 4a869d07a2ea875cc81afac0b9d1c2a9b580d8e2 (diff) | |
parent | 3d3c0c33c449888538025470aeecf651d77d09fe (diff) | |
download | history-15aeed9352711084abde5f6b4cd4e0b29f5f83ba.tar.gz |
Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/ll_rw_blk.c | 11 | ||||
-rw-r--r-- | drivers/block/paride/pcd.c | 2 | ||||
-rw-r--r-- | drivers/block/scsi_ioctl.c | 94 | ||||
-rw-r--r-- | drivers/cdrom/cdrom.c | 6 | ||||
-rw-r--r-- | drivers/cdrom/cdu31a.c | 2 | ||||
-rw-r--r-- | drivers/cdrom/cm206.c | 2 | ||||
-rw-r--r-- | drivers/cdrom/mcd.c | 2 | ||||
-rw-r--r-- | drivers/cdrom/mcdx.c | 2 | ||||
-rw-r--r-- | drivers/cdrom/sbpcd.c | 2 | ||||
-rw-r--r-- | drivers/cdrom/viocd.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide.c | 6 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/st.c | 2 |
19 files changed, 114 insertions, 35 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 8dc40d5d86daa8..17c403ebd58bbf 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1467,9 +1467,6 @@ request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) printk("Using %s io scheduler\n", chosen_elevator->elevator_name); } - if (elevator_init(q, chosen_elevator)) - goto out_elv; - q->request_fn = rfn; q->back_merge_fn = ll_back_merge_fn; q->front_merge_fn = ll_front_merge_fn; @@ -1487,8 +1484,12 @@ request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); - return q; -out_elv: + /* + * all done + */ + if (!elevator_init(q, chosen_elevator)) + return q; + blk_cleanup_queue(q); out_init: kmem_cache_free(requestq_cachep, q); diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 2f1901b606c22c..876a2369088399 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -259,7 +259,7 @@ static int pcd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(&cd->info, inode, cmd, arg); + return cdrom_ioctl(file, &cd->info, inode, cmd, arg); } static int pcd_block_media_changed(struct gendisk *disk) diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index 03df600806502a..41d023931f472b 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c @@ -105,8 +105,80 @@ static int sg_emulated_host(request_queue_t *q, int __user *p) return put_user(1, p); } -static int sg_io(request_queue_t *q, struct gendisk *bd_disk, - struct sg_io_hdr *hdr) +#define CMD_READ_SAFE 0x01 +#define CMD_WRITE_SAFE 0x02 +#define safe_for_read(cmd) [cmd] = CMD_READ_SAFE +#define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE + +static int verify_command(struct file *file, unsigned char *cmd) +{ + static const unsigned char cmd_type[256] = { + + /* Basic read-only commands */ + safe_for_read(TEST_UNIT_READY), + safe_for_read(REQUEST_SENSE), + safe_for_read(READ_6), + safe_for_read(READ_10), + safe_for_read(READ_12), + safe_for_read(READ_16), + safe_for_read(READ_BUFFER), + safe_for_read(READ_LONG), + safe_for_read(INQUIRY), + safe_for_read(MODE_SENSE), + safe_for_read(MODE_SENSE_10), + safe_for_read(START_STOP), + + /* Audio CD commands */ + safe_for_read(GPCMD_PLAY_CD), + safe_for_read(GPCMD_PLAY_AUDIO_10), + safe_for_read(GPCMD_PLAY_AUDIO_MSF), + safe_for_read(GPCMD_PLAY_AUDIO_TI), + + /* CD/DVD data reading */ + safe_for_read(GPCMD_READ_CD), + safe_for_read(GPCMD_READ_CD_MSF), + safe_for_read(GPCMD_READ_DISC_INFO), + safe_for_read(GPCMD_READ_CDVD_CAPACITY), + safe_for_read(GPCMD_READ_DVD_STRUCTURE), + safe_for_read(GPCMD_READ_HEADER), + safe_for_read(GPCMD_READ_TRACK_RZONE_INFO), + safe_for_read(GPCMD_READ_SUBCHANNEL), + safe_for_read(GPCMD_READ_TOC_PMA_ATIP), + safe_for_read(GPCMD_REPORT_KEY), + safe_for_read(GPCMD_SCAN), + + /* Basic writing commands */ + safe_for_write(WRITE_6), + safe_for_write(WRITE_10), + safe_for_write(WRITE_VERIFY), + safe_for_write(WRITE_12), + safe_for_write(WRITE_VERIFY_12), + safe_for_write(WRITE_16), + safe_for_write(WRITE_BUFFER), + safe_for_write(WRITE_LONG), + }; + unsigned char type = cmd_type[cmd[0]]; + + /* Anybody who can open the device can do a read-safe command */ + if (type & CMD_READ_SAFE) + return 0; + + /* Write-safe commands just require a writable open.. */ + if (type & CMD_WRITE_SAFE) { + if (file->f_mode & FMODE_WRITE) + return 0; + } + + /* And root can do any command.. */ + if (capable(CAP_SYS_RAWIO)) + return 0; + + /* Otherwise fail it with an "Operation not permitted" */ + return -EPERM; +} + +static int sg_io(struct file *file, request_queue_t *q, + struct gendisk *bd_disk, struct sg_io_hdr *hdr) { unsigned long start_time; int reading, writing; @@ -121,6 +193,8 @@ static int sg_io(request_queue_t *q, struct gendisk *bd_disk, return -EINVAL; if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; + if (verify_command(file, cmd)) + return -EPERM; /* * we'll do that later @@ -226,8 +300,8 @@ static int sg_io(request_queue_t *q, struct gendisk *bd_disk, #define READ_DEFECT_DATA_TIMEOUT (60 * HZ ) #define OMAX_SB_LEN 16 /* For backward compatibility */ -static int sg_scsi_ioctl(request_queue_t *q, struct gendisk *bd_disk, - Scsi_Ioctl_Command __user *sic) +static int sg_scsi_ioctl(struct file *file, request_queue_t *q, + struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic) { struct request *rq; int err, in_len, out_len, bytes, opcode, cmdlen; @@ -269,6 +343,10 @@ static int sg_scsi_ioctl(request_queue_t *q, struct gendisk *bd_disk, if (copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; + err = verify_command(file, rq->cmd); + if (err) + goto error; + switch (opcode) { case SEND_DIAGNOSTIC: case FORMAT_UNIT: @@ -319,7 +397,7 @@ error: return err; } -int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg) +int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg) { request_queue_t *q; struct request *rq; @@ -366,7 +444,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg) err = -EFAULT; if (copy_from_user(&hdr, arg, sizeof(hdr))) break; - err = sg_io(q, bd_disk, &hdr); + err = sg_io(file, q, bd_disk, &hdr); if (err == -EFAULT) break; @@ -414,7 +492,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg) hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; hdr.cmd_len = sizeof(cgc.cmd); - err = sg_io(q, bd_disk, &hdr); + err = sg_io(file, q, bd_disk, &hdr); if (err == -EFAULT) break; @@ -437,7 +515,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg) if (!arg) break; - err = sg_scsi_ioctl(q, bd_disk, arg); + err = sg_scsi_ioctl(file, q, bd_disk, arg); break; case CDROMCLOSETRAY: close = 1; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 360d4b64a42e53..2f778c92b88b34 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2072,14 +2072,14 @@ retry: * these days. ATAPI / SCSI specific code now mainly resides in * mmc_ioct(). */ -int cdrom_ioctl(struct cdrom_device_info *cdi, struct inode *ip, - unsigned int cmd, unsigned long arg) +int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi, + struct inode *ip, unsigned int cmd, unsigned long arg) { struct cdrom_device_ops *cdo = cdi->ops; int ret; /* Try the generic SCSI command ioctl's first.. */ - ret = scsi_cmd_ioctl(ip->i_bdev->bd_disk, cmd, (void __user *)arg); + ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, (void __user *)arg); if (ret != -ENOTTY) return ret; diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 3a758a020280c7..cbe336429c2f9a 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -3179,7 +3179,7 @@ static int scd_block_release(struct inode *inode, struct file *file) static int scd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(&scd_info, inode, cmd, arg); + return cdrom_ioctl(file, &scd_info, inode, cmd, arg); } static int scd_block_media_changed(struct gendisk *disk) diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index d6d49df4dea5e3..ccd2603625dfbe 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c @@ -1363,7 +1363,7 @@ static int cm206_block_release(struct inode *inode, struct file *file) static int cm206_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(&cm206_info, inode, cmd, arg); + return cdrom_ioctl(file, &cm206_info, inode, cmd, arg); } static int cm206_block_media_changed(struct gendisk *disk) diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c index 33b35e30e619a0..4cb0fb491c65a3 100644 --- a/drivers/cdrom/mcd.c +++ b/drivers/cdrom/mcd.c @@ -227,7 +227,7 @@ static int mcd_block_release(struct inode *inode, struct file *file) static int mcd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(&mcd_info, inode, cmd, arg); + return cdrom_ioctl(file, &mcd_info, inode, cmd, arg); } static int mcd_block_media_changed(struct gendisk *disk) diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 3ada792c81f8ad..01b4e9a5602e45 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c @@ -233,7 +233,7 @@ static int mcdx_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(&p->info, inode, cmd, arg); + return cdrom_ioctl(file, &p->info, inode, cmd, arg); } static int mcdx_block_media_changed(struct gendisk *disk) diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index a2475c6bb183e3..88467495983a31 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c @@ -5372,7 +5372,7 @@ static int sbpcd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(p->sbpcd_infop, inode, cmd, arg); + return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg); } static int sbpcd_block_media_changed(struct gendisk *disk) diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 85f0aca152224f..3a2acc0fb855ac 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -199,7 +199,7 @@ static int viocd_blk_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { struct disk_info *di = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(&di->viocd_info, inode, cmd, arg); + return cdrom_ioctl(file, &di->viocd_info, inode, cmd, arg); } static int viocd_blk_media_changed(struct gendisk *disk) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index f8414d0a4aae4d..c3d6286eb87c1f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3395,10 +3395,10 @@ static int idecd_ioctl (struct inode *inode, struct file *file, { struct block_device *bdev = inode->i_bdev; ide_drive_t *drive = bdev->bd_disk->private_data; - int err = generic_ide_ioctl(bdev, cmd, arg); + int err = generic_ide_ioctl(file, bdev, cmd, arg); if (err == -EINVAL) { struct cdrom_info *info = drive->driver_data; - err = cdrom_ioctl(&info->devinfo, inode, cmd, arg); + err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); } return err; } diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8b6be30b12c8fd..7b3bf05cbf95da 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1668,7 +1668,7 @@ static int idedisk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - return generic_ide_ioctl(bdev, cmd, arg); + return generic_ide_ioctl(file, bdev, cmd, arg); } static int idedisk_media_changed(struct gendisk *disk) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 56fec5ca18792b..7383f44a2d0ba7 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -1946,7 +1946,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, ide_drive_t *drive = bdev->bd_disk->private_data; idefloppy_floppy_t *floppy = drive->driver_data; void __user *argp = (void __user *)arg; - int err = generic_ide_ioctl(bdev, cmd, arg); + int err = generic_ide_ioctl(file, bdev, cmd, arg); int prevent = (arg) ? 1 : 0; idefloppy_pc_t pc; if (err != -EINVAL) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f86ffc4b356b2f..d19ee543e2023f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4807,7 +4807,7 @@ static int idetape_ioctl(struct inode *inode, struct file *file, { struct block_device *bdev = inode->i_bdev; ide_drive_t *drive = bdev->bd_disk->private_data; - int err = generic_ide_ioctl(bdev, cmd, arg); + int err = generic_ide_ioctl(file, bdev, cmd, arg); if (err == -EINVAL) err = idetape_blkdev_ioctl(drive, cmd, arg); return err; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 2bdb860e03c3bf..e99d9ec19bbe6e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1453,8 +1453,8 @@ static int generic_ide_resume(struct device *dev) return ide_do_drive_cmd(drive, &rq, ide_head_wait); } -int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, - unsigned long arg) +int generic_ide_ioctl(struct file *file, struct block_device *bdev, + unsigned int cmd, unsigned long arg) { ide_drive_t *drive = bdev->bd_disk->private_data; ide_settings_t *setting; @@ -1605,7 +1605,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, case CDROMEJECT: case CDROMCLOSETRAY: - return scsi_cmd_ioctl(bdev->bd_disk, cmd, p); + return scsi_cmd_ioctl(file, bdev->bd_disk, cmd, p); case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 811c66d7285462..4f2a284c2056e5 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -735,7 +735,7 @@ static int idescsi_ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - return generic_ide_ioctl(bdev, cmd, arg); + return generic_ide_ioctl(file, bdev, cmd, arg); } static struct block_device_operations idescsi_ops = { diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 75c80671e0699b..8fd45906059acf 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -594,7 +594,7 @@ static int sd_ioctl(struct inode * inode, struct file * filp, case SCSI_IOCTL_GET_BUS_NUMBER: return scsi_ioctl(sdp, cmd, p); default: - error = scsi_cmd_ioctl(disk, cmd, p); + error = scsi_cmd_ioctl(filp, disk, cmd, p); if (error != -ENOTTY) return error; } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 06aa858f9a8099..b80aa283c92129 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -504,7 +504,7 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, case SCSI_IOCTL_GET_BUS_NUMBER: return scsi_ioctl(sdev, cmd, (void __user *)arg); } - return cdrom_ioctl(&cd->cdi, inode, cmd, arg); + return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); } static int sr_block_media_changed(struct gendisk *disk) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 6e87d622662649..5fa0153dac1467 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3408,7 +3408,7 @@ static int st_ioctl(struct inode *inode, struct file *file, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: - i = scsi_cmd_ioctl(STp->disk, cmd_in, p); + i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p); if (i != -ENOTTY) return i; break; |