X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fblock%2Fscsi_ioctl.c;h=cd3bc2d423c739f549e9e2924457bc6eab95512c;hb=746550cff061581f89c687ada8523670768364f2;hp=e88b6eca91a3c7e10adbb880b1c6be7d16f55812;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index e88b6eca9..cd3bc2d42 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c @@ -44,18 +44,18 @@ EXPORT_SYMBOL(scsi_command_size); #include -static int sg_get_version(int *p) +static int sg_get_version(int __user *p) { static int sg_version_num = 30527; return put_user(sg_version_num, p); } -static int scsi_get_idlun(request_queue_t *q, int *p) +static int scsi_get_idlun(request_queue_t *q, int __user *p) { return put_user(0, p); } -static int scsi_get_bus(request_queue_t *q, int *p) +static int scsi_get_bus(request_queue_t *q, int __user *p) { return put_user(0, p); } @@ -65,7 +65,7 @@ static int sg_get_timeout(request_queue_t *q) return q->sg_timeout / (HZ / USER_HZ); } -static int sg_set_timeout(request_queue_t *q, int *p) +static int sg_set_timeout(request_queue_t *q, int __user *p) { int timeout, err = get_user(timeout, p); @@ -75,12 +75,12 @@ static int sg_set_timeout(request_queue_t *q, int *p) return err; } -static int sg_get_reserved_size(request_queue_t *q, int *p) +static int sg_get_reserved_size(request_queue_t *q, int __user *p) { return put_user(q->sg_reserved_size, p); } -static int sg_set_reserved_size(request_queue_t *q, int *p) +static int sg_set_reserved_size(request_queue_t *q, int __user *p) { int size, err = get_user(size, p); @@ -100,7 +100,7 @@ static int sg_set_reserved_size(request_queue_t *q, int *p) * will always return that we are ATAPI even for a real SCSI drive, I'm not * so sure this is worth doing anything about (why would you care??) */ -static int sg_emulated_host(request_queue_t *q, int *p) +static int sg_emulated_host(request_queue_t *q, int __user *p) { return put_user(1, p); } @@ -113,11 +113,14 @@ static int sg_io(request_queue_t *q, struct gendisk *bd_disk, struct request *rq; struct bio *bio; char sense[SCSI_SENSE_BUFFERSIZE]; + unsigned char cmd[BLK_MAX_CDB]; if (hdr->interface_id != 'S') return -EINVAL; - if (hdr->cmd_len > sizeof(rq->cmd)) + if (hdr->cmd_len > BLK_MAX_CDB) return -EINVAL; + if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len)) + return -EFAULT; /* * we'll do that later @@ -156,7 +159,7 @@ static int sg_io(request_queue_t *q, struct gendisk *bd_disk, * fill in request structure */ rq->cmd_len = hdr->cmd_len; - memcpy(rq->cmd, hdr->cmdp, hdr->cmd_len); + memcpy(rq->cmd, cmd, hdr->cmd_len); if (sizeof(rq->cmd) != hdr->cmd_len) memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len); @@ -217,7 +220,7 @@ static int sg_io(request_queue_t *q, struct gendisk *bd_disk, #define OMAX_SB_LEN 16 /* For backward compatibility */ static int sg_scsi_ioctl(request_queue_t *q, struct gendisk *bd_disk, - Scsi_Ioctl_Command *sic) + Scsi_Ioctl_Command __user *sic) { struct request *rq; int err, in_len, out_len, bytes, opcode, cmdlen; @@ -232,12 +235,12 @@ static int sg_scsi_ioctl(request_queue_t *q, struct gendisk *bd_disk, return -EFAULT; if (in_len > PAGE_SIZE || out_len > PAGE_SIZE) return -EINVAL; - if (get_user(opcode, sic->data)) + if (get_user(opcode, (int *)sic->data)) return -EFAULT; bytes = max(in_len, out_len); if (bytes) { - buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER); + buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER | __GFP_NOWARN); if (!buffer) return -ENOMEM; @@ -309,7 +312,7 @@ error: return err; } -int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) +int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg) { request_queue_t *q; struct request *rq; @@ -327,51 +330,40 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) * new sgv3 interface */ case SG_GET_VERSION_NUM: - err = sg_get_version((int *) arg); + err = sg_get_version(arg); break; case SCSI_IOCTL_GET_IDLUN: - err = scsi_get_idlun(q, (int *) arg); + err = scsi_get_idlun(q, arg); break; case SCSI_IOCTL_GET_BUS_NUMBER: - err = scsi_get_bus(q, (int *) arg); + err = scsi_get_bus(q, arg); break; case SG_SET_TIMEOUT: - err = sg_set_timeout(q, (int *) arg); + err = sg_set_timeout(q, arg); break; case SG_GET_TIMEOUT: err = sg_get_timeout(q); break; case SG_GET_RESERVED_SIZE: - err = sg_get_reserved_size(q, (int *) arg); + err = sg_get_reserved_size(q, arg); break; case SG_SET_RESERVED_SIZE: - err = sg_set_reserved_size(q, (int *) arg); + err = sg_set_reserved_size(q, arg); break; case SG_EMULATED_HOST: - err = sg_emulated_host(q, (int *) arg); + err = sg_emulated_host(q, arg); break; case SG_IO: { struct sg_io_hdr hdr; - unsigned char cdb[BLK_MAX_CDB], *old_cdb; err = -EFAULT; - if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) - break; - err = -EINVAL; - if (hdr.cmd_len > sizeof(rq->cmd)) - break; - err = -EFAULT; - if (copy_from_user(cdb, hdr.cmdp, hdr.cmd_len)) + if (copy_from_user(&hdr, arg, sizeof(hdr))) break; - - old_cdb = hdr.cmdp; - hdr.cmdp = cdb; err = sg_io(q, bd_disk, &hdr); if (err == -EFAULT) break; - hdr.cmdp = old_cdb; - if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr))) + if (copy_to_user(arg, &hdr, sizeof(hdr))) err = -EFAULT; break; } @@ -380,7 +372,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) struct sg_io_hdr hdr; err = -EFAULT; - if (copy_from_user(&cgc, (struct cdrom_generic_command *) arg, sizeof(cgc))) + if (copy_from_user(&cgc, arg, sizeof(cgc))) break; cgc.timeout = clock_t_to_jiffies(cgc.timeout); memset(&hdr, 0, sizeof(hdr)); @@ -408,11 +400,11 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) break; hdr.dxferp = cgc.buffer; - hdr.sbp = (char *) cgc.sense; + hdr.sbp = cgc.sense; if (hdr.sbp) hdr.mx_sb_len = sizeof(struct request_sense); hdr.timeout = cgc.timeout; - hdr.cmdp = cgc.cmd; + hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; hdr.cmd_len = sizeof(cgc.cmd); err = sg_io(q, bd_disk, &hdr); @@ -424,7 +416,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) cgc.stat = err; cgc.buflen = hdr.resid; - if (copy_to_user((struct cdrom_generic_command *) arg, &cgc, sizeof(cgc))) + if (copy_to_user(arg, &cgc, sizeof(cgc))) err = -EFAULT; break; @@ -438,8 +430,7 @@ int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, unsigned long arg) if (!arg) break; - err = sg_scsi_ioctl(q, bd_disk, - (Scsi_Ioctl_Command *)arg); + err = sg_scsi_ioctl(q, bd_disk, arg); break; case CDROMCLOSETRAY: close = 1;