diff options
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 9d28b9f74d90..661f9f21650a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -217,6 +217,18 @@ static int sg_last_dev(void); | |||
217 | #define SZ_SG_IOVEC sizeof(sg_iovec_t) | 217 | #define SZ_SG_IOVEC sizeof(sg_iovec_t) |
218 | #define SZ_SG_REQ_INFO sizeof(sg_req_info_t) | 218 | #define SZ_SG_REQ_INFO sizeof(sg_req_info_t) |
219 | 219 | ||
220 | static int sg_allow_access(struct file *filp, unsigned char *cmd) | ||
221 | { | ||
222 | struct sg_fd *sfp = (struct sg_fd *)filp->private_data; | ||
223 | struct request_queue *q = sfp->parentdp->device->request_queue; | ||
224 | |||
225 | if (sfp->parentdp->device->type == TYPE_SCANNER) | ||
226 | return 0; | ||
227 | |||
228 | return blk_verify_command(&q->cmd_filter, | ||
229 | cmd, filp->f_mode & FMODE_WRITE); | ||
230 | } | ||
231 | |||
220 | static int | 232 | static int |
221 | sg_open(struct inode *inode, struct file *filp) | 233 | sg_open(struct inode *inode, struct file *filp) |
222 | { | 234 | { |
@@ -641,7 +653,6 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, | |||
641 | unsigned char cmnd[MAX_COMMAND_SIZE]; | 653 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
642 | int timeout; | 654 | int timeout; |
643 | unsigned long ul_timeout; | 655 | unsigned long ul_timeout; |
644 | struct request_queue *q; | ||
645 | 656 | ||
646 | if (count < SZ_SG_IO_HDR) | 657 | if (count < SZ_SG_IO_HDR) |
647 | return -EINVAL; | 658 | return -EINVAL; |
@@ -690,9 +701,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, | |||
690 | sg_remove_request(sfp, srp); | 701 | sg_remove_request(sfp, srp); |
691 | return -EFAULT; | 702 | return -EFAULT; |
692 | } | 703 | } |
693 | q = sfp->parentdp->device->request_queue; | 704 | if (read_only && sg_allow_access(file, cmnd)) { |
694 | if (read_only && blk_verify_command(&q->cmd_filter, cmnd, | ||
695 | file->f_mode & FMODE_WRITE)) { | ||
696 | sg_remove_request(sfp, srp); | 705 | sg_remove_request(sfp, srp); |
697 | return -EPERM; | 706 | return -EPERM; |
698 | } | 707 | } |
@@ -1061,14 +1070,11 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1061 | return -ENODEV; | 1070 | return -ENODEV; |
1062 | if (read_only) { | 1071 | if (read_only) { |
1063 | unsigned char opcode = WRITE_6; | 1072 | unsigned char opcode = WRITE_6; |
1064 | struct request_queue *q = sdp->device->request_queue; | ||
1065 | Scsi_Ioctl_Command __user *siocp = p; | 1073 | Scsi_Ioctl_Command __user *siocp = p; |
1066 | 1074 | ||
1067 | if (copy_from_user(&opcode, siocp->data, 1)) | 1075 | if (copy_from_user(&opcode, siocp->data, 1)) |
1068 | return -EFAULT; | 1076 | return -EFAULT; |
1069 | if (blk_verify_command(&q->cmd_filter, | 1077 | if (sg_allow_access(filp, &opcode)) |
1070 | &opcode, | ||
1071 | filp->f_mode & FMODE_WRITE)) | ||
1072 | return -EPERM; | 1078 | return -EPERM; |
1073 | } | 1079 | } |
1074 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); | 1080 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); |