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.c22
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
220static 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
220static int 232static int
221sg_open(struct inode *inode, struct file *filp) 233sg_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);