aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c44
1 files changed, 10 insertions, 34 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index cee1e4c6d83c..fccd2e88d600 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -183,8 +183,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
183 int tablesize); 183 int tablesize);
184static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, 184static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
185 Sg_request * srp); 185 Sg_request * srp);
186static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, 186static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
187 int blocking, int read_only, Sg_request ** o_srp); 187 const char __user *buf, size_t count, int blocking,
188 int read_only, Sg_request **o_srp);
188static int sg_common_write(Sg_fd * sfp, Sg_request * srp, 189static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
189 unsigned char *cmnd, int timeout, int blocking); 190 unsigned char *cmnd, int timeout, int blocking);
190static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, 191static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
@@ -205,7 +206,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
205static Sg_request *sg_add_request(Sg_fd * sfp); 206static Sg_request *sg_add_request(Sg_fd * sfp);
206static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); 207static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
207static int sg_res_in_use(Sg_fd * sfp); 208static int sg_res_in_use(Sg_fd * sfp);
208static int sg_allow_access(unsigned char opcode, char dev_type);
209static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); 209static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
210static Sg_device *sg_get_dev(int dev); 210static Sg_device *sg_get_dev(int dev);
211#ifdef CONFIG_SCSI_PROC_FS 211#ifdef CONFIG_SCSI_PROC_FS
@@ -554,7 +554,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
554 return -EFAULT; 554 return -EFAULT;
555 blocking = !(filp->f_flags & O_NONBLOCK); 555 blocking = !(filp->f_flags & O_NONBLOCK);
556 if (old_hdr.reply_len < 0) 556 if (old_hdr.reply_len < 0)
557 return sg_new_write(sfp, buf, count, blocking, 0, NULL); 557 return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL);
558 if (count < (SZ_SG_HEADER + 6)) 558 if (count < (SZ_SG_HEADER + 6))
559 return -EIO; /* The minimum scsi command length is 6 bytes. */ 559 return -EIO; /* The minimum scsi command length is 6 bytes. */
560 560
@@ -631,8 +631,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
631} 631}
632 632
633static ssize_t 633static ssize_t
634sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, 634sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
635 int blocking, int read_only, Sg_request ** o_srp) 635 size_t count, int blocking, int read_only,
636 Sg_request **o_srp)
636{ 637{
637 int k; 638 int k;
638 Sg_request *srp; 639 Sg_request *srp;
@@ -688,8 +689,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
688 sg_remove_request(sfp, srp); 689 sg_remove_request(sfp, srp);
689 return -EFAULT; 690 return -EFAULT;
690 } 691 }
691 if (read_only && 692 if (read_only && !blk_verify_command(file, cmnd)) {
692 (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
693 sg_remove_request(sfp, srp); 693 sg_remove_request(sfp, srp);
694 return -EPERM; 694 return -EPERM;
695 } 695 }
@@ -809,7 +809,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
809 if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) 809 if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
810 return -EFAULT; 810 return -EFAULT;
811 result = 811 result =
812 sg_new_write(sfp, p, SZ_SG_IO_HDR, 812 sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
813 blocking, read_only, &srp); 813 blocking, read_only, &srp);
814 if (result < 0) 814 if (result < 0)
815 return result; 815 return result;
@@ -1058,7 +1058,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
1058 1058
1059 if (copy_from_user(&opcode, siocp->data, 1)) 1059 if (copy_from_user(&opcode, siocp->data, 1))
1060 return -EFAULT; 1060 return -EFAULT;
1061 if (!sg_allow_access(opcode, sdp->device->type)) 1061 if (!blk_verify_command(filp, &opcode))
1062 return -EPERM; 1062 return -EPERM;
1063 } 1063 }
1064 return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); 1064 return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
@@ -2512,30 +2512,6 @@ sg_page_free(struct page *page, int size)
2512 __free_pages(page, order); 2512 __free_pages(page, order);
2513} 2513}
2514 2514
2515#ifndef MAINTENANCE_IN_CMD
2516#define MAINTENANCE_IN_CMD 0xa3
2517#endif
2518
2519static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
2520 INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
2521 READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
2522 SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
2523};
2524
2525static int
2526sg_allow_access(unsigned char opcode, char dev_type)
2527{
2528 int k;
2529
2530 if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */
2531 return 1;
2532 for (k = 0; k < sizeof (allow_ops); ++k) {
2533 if (opcode == allow_ops[k])
2534 return 1;
2535 }
2536 return 0;
2537}
2538
2539#ifdef CONFIG_SCSI_PROC_FS 2515#ifdef CONFIG_SCSI_PROC_FS
2540static int 2516static int
2541sg_idr_max_id(int id, void *p, void *data) 2517sg_idr_max_id(int id, void *p, void *data)