aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sg.c40
1 files changed, 10 insertions, 30 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ea0edd1b2e76..f7abccaffaec 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -182,8 +182,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
182 int tablesize); 182 int tablesize);
183static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, 183static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
184 Sg_request * srp); 184 Sg_request * srp);
185static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, 185static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
186 int blocking, int read_only, Sg_request ** o_srp); 186 const char __user *buf, size_t count, int blocking,
187 int read_only, Sg_request **o_srp);
187static int sg_common_write(Sg_fd * sfp, Sg_request * srp, 188static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
188 unsigned char *cmnd, int timeout, int blocking); 189 unsigned char *cmnd, int timeout, int blocking);
189static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, 190static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
@@ -204,7 +205,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
204static Sg_request *sg_add_request(Sg_fd * sfp); 205static Sg_request *sg_add_request(Sg_fd * sfp);
205static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); 206static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
206static int sg_res_in_use(Sg_fd * sfp); 207static int sg_res_in_use(Sg_fd * sfp);
207static int sg_allow_access(unsigned char opcode, char dev_type);
208static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); 208static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
209static Sg_device *sg_get_dev(int dev); 209static Sg_device *sg_get_dev(int dev);
210#ifdef CONFIG_SCSI_PROC_FS 210#ifdef CONFIG_SCSI_PROC_FS
@@ -544,7 +544,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
544 return -EFAULT; 544 return -EFAULT;
545 blocking = !(filp->f_flags & O_NONBLOCK); 545 blocking = !(filp->f_flags & O_NONBLOCK);
546 if (old_hdr.reply_len < 0) 546 if (old_hdr.reply_len < 0)
547 return sg_new_write(sfp, buf, count, blocking, 0, NULL); 547 return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL);
548 if (count < (SZ_SG_HEADER + 6)) 548 if (count < (SZ_SG_HEADER + 6))
549 return -EIO; /* The minimum scsi command length is 6 bytes. */ 549 return -EIO; /* The minimum scsi command length is 6 bytes. */
550 550
@@ -621,8 +621,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
621} 621}
622 622
623static ssize_t 623static ssize_t
624sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, 624sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
625 int blocking, int read_only, Sg_request ** o_srp) 625 size_t count, int blocking, int read_only,
626 Sg_request **o_srp)
626{ 627{
627 int k; 628 int k;
628 Sg_request *srp; 629 Sg_request *srp;
@@ -678,8 +679,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
678 sg_remove_request(sfp, srp); 679 sg_remove_request(sfp, srp);
679 return -EFAULT; 680 return -EFAULT;
680 } 681 }
681 if (read_only && 682 if (read_only && (!blk_verify_command(file, cmnd))) {
682 (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
683 sg_remove_request(sfp, srp); 683 sg_remove_request(sfp, srp);
684 return -EPERM; 684 return -EPERM;
685 } 685 }
@@ -799,7 +799,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
799 if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) 799 if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
800 return -EFAULT; 800 return -EFAULT;
801 result = 801 result =
802 sg_new_write(sfp, p, SZ_SG_IO_HDR, 802 sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
803 blocking, read_only, &srp); 803 blocking, read_only, &srp);
804 if (result < 0) 804 if (result < 0)
805 return result; 805 return result;
@@ -1048,7 +1048,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
1048 1048
1049 if (copy_from_user(&opcode, siocp->data, 1)) 1049 if (copy_from_user(&opcode, siocp->data, 1))
1050 return -EFAULT; 1050 return -EFAULT;
1051 if (!sg_allow_access(opcode, sdp->device->type)) 1051 if (!blk_verify_command(filp, &opcode))
1052 return -EPERM; 1052 return -EPERM;
1053 } 1053 }
1054 return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); 1054 return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
@@ -2506,26 +2506,6 @@ sg_page_free(struct page *page, int size)
2506#define MAINTENANCE_IN_CMD 0xa3 2506#define MAINTENANCE_IN_CMD 0xa3
2507#endif 2507#endif
2508 2508
2509static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
2510 INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
2511 READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
2512 SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
2513};
2514
2515static int
2516sg_allow_access(unsigned char opcode, char dev_type)
2517{
2518 int k;
2519
2520 if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */
2521 return 1;
2522 for (k = 0; k < sizeof (allow_ops); ++k) {
2523 if (opcode == allow_ops[k])
2524 return 1;
2525 }
2526 return 0;
2527}
2528
2529#ifdef CONFIG_SCSI_PROC_FS 2509#ifdef CONFIG_SCSI_PROC_FS
2530static int 2510static int
2531sg_idr_max_id(int id, void *p, void *data) 2511sg_idr_max_id(int id, void *p, void *data)