aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-12 04:37:58 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-12 04:37:58 -0700
commit15aeed9352711084abde5f6b4cd4e0b29f5f83ba (patch)
tree3f9594b7f27d42565bb4007e3c2a46bfead6e846 /drivers
parent4a869d07a2ea875cc81afac0b9d1c2a9b580d8e2 (diff)
parent3d3c0c33c449888538025470aeecf651d77d09fe (diff)
downloadhistory-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.c11
-rw-r--r--drivers/block/paride/pcd.c2
-rw-r--r--drivers/block/scsi_ioctl.c94
-rw-r--r--drivers/cdrom/cdrom.c6
-rw-r--r--drivers/cdrom/cdu31a.c2
-rw-r--r--drivers/cdrom/cm206.c2
-rw-r--r--drivers/cdrom/mcd.c2
-rw-r--r--drivers/cdrom/mcdx.c2
-rw-r--r--drivers/cdrom/sbpcd.c2
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/ide/ide-cd.c4
-rw-r--r--drivers/ide/ide-disk.c2
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-tape.c2
-rw-r--r--drivers/ide/ide.c6
-rw-r--r--drivers/scsi/ide-scsi.c2
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--drivers/scsi/st.c2
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;