diff options
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 44 |
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); |
184 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, | 184 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, |
185 | Sg_request * srp); | 185 | Sg_request * srp); |
186 | static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 186 | static 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); | ||
188 | static int sg_common_write(Sg_fd * sfp, Sg_request * srp, | 189 | static 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); |
190 | static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, | 191 | static 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); | |||
205 | static Sg_request *sg_add_request(Sg_fd * sfp); | 206 | static Sg_request *sg_add_request(Sg_fd * sfp); |
206 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); | 207 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); |
207 | static int sg_res_in_use(Sg_fd * sfp); | 208 | static int sg_res_in_use(Sg_fd * sfp); |
208 | static int sg_allow_access(unsigned char opcode, char dev_type); | ||
209 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); | 209 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); |
210 | static Sg_device *sg_get_dev(int dev); | 210 | static 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 | ||
633 | static ssize_t | 633 | static ssize_t |
634 | sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 634 | sg_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 | |||
2519 | static 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 | |||
2525 | static int | ||
2526 | sg_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 |
2540 | static int | 2516 | static int |
2541 | sg_idr_max_id(int id, void *p, void *data) | 2517 | sg_idr_max_id(int id, void *p, void *data) |