History

scsi: scsi_ioctl: Simplify SCSI passthrough permission checking

Remove the separate command filter structure and just use a switch statement (which also cought two duplicate commands), return a bool and give the function a sensible name.

Christoph Hellwig committed 5 years ago

Commit 7353dc01 parent b69367d4 files · +104 −124Browse files

Unified · Split

4 files
  1. block/scsi_ioctl.c +99 −120
  2. drivers/scsi/scsi_bsg.c +1 −1
  3. drivers/scsi/sg.c +3 −2
  4. include/linux/blkdev.h +1 −1
block/scsi_ioctl.c+99−120
@@ -22,13 +22,6 @@ · 21 unmodified lines
22#include <scsi/scsi_cmnd.h>22#include <scsi/scsi_cmnd.h>
23#include <scsi/sg.h>23#include <scsi/sg.h>
24 24
25struct blk_cmd_filter {
26 unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
27 unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
28};
29
30static struct blk_cmd_filter blk_default_cmd_filter;
31
32static int sg_get_version(int __user *p)25static int sg_get_version(int __user *p)
33{26{
34 static const int sg_version_num = 30527;27 static const int sg_version_num = 30527;
@@ -80,115 +73,108 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) · 45 unmodified lines
80 return put_user(1, p);73 return put_user(1, p);
81}74}
82 75
83static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)76/*
84{77 * Check if the given command is allowed.
85 /* Basic read-only commands */78 *
86 __set_bit(TEST_UNIT_READY, filter->read_ok);79 * For unprivileged users only a small set of whitelisted command is allowed so
87 __set_bit(REQUEST_SENSE, filter->read_ok);80 * that they can't format the drive or update the firmware.
88 __set_bit(READ_6, filter->read_ok);81 */
89 __set_bit(READ_10, filter->read_ok);82bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode)
90 __set_bit(READ_12, filter->read_ok);
91 __set_bit(READ_16, filter->read_ok);
92 __set_bit(READ_BUFFER, filter->read_ok);
93 __set_bit(READ_DEFECT_DATA, filter->read_ok);
94 __set_bit(READ_CAPACITY, filter->read_ok);
95 __set_bit(READ_LONG, filter->read_ok);
96 __set_bit(INQUIRY, filter->read_ok);
97 __set_bit(MODE_SENSE, filter->read_ok);
98 __set_bit(MODE_SENSE_10, filter->read_ok);
99 __set_bit(LOG_SENSE, filter->read_ok);
100 __set_bit(START_STOP, filter->read_ok);
101 __set_bit(GPCMD_VERIFY_10, filter->read_ok);
102 __set_bit(VERIFY_16, filter->read_ok);
103 __set_bit(REPORT_LUNS, filter->read_ok);
104 __set_bit(SERVICE_ACTION_IN_16, filter->read_ok);
105 __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok);
106 __set_bit(MAINTENANCE_IN, filter->read_ok);
107 __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok);
108
109 /* Audio CD commands */
110 __set_bit(GPCMD_PLAY_CD, filter->read_ok);
111 __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok);
112 __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok);
113 __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok);
114 __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok);
115
116 /* CD/DVD data reading */
117 __set_bit(GPCMD_READ_CD, filter->read_ok);
118 __set_bit(GPCMD_READ_CD_MSF, filter->read_ok);
119 __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok);
120 __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok);
121 __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok);
122 __set_bit(GPCMD_READ_HEADER, filter->read_ok);
123 __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok);
124 __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok);
125 __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok);
126 __set_bit(GPCMD_REPORT_KEY, filter->read_ok);
127 __set_bit(GPCMD_SCAN, filter->read_ok);
128 __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok);
129 __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok);
130 __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok);
131 __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok);
132 __set_bit(GPCMD_SEEK, filter->read_ok);
133 __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok);
134
135 /* Basic writing commands */
136 __set_bit(WRITE_6, filter->write_ok);
137 __set_bit(WRITE_10, filter->write_ok);
138 __set_bit(WRITE_VERIFY, filter->write_ok);
139 __set_bit(WRITE_12, filter->write_ok);
140 __set_bit(WRITE_VERIFY_12, filter->write_ok);
141 __set_bit(WRITE_16, filter->write_ok);
142 __set_bit(WRITE_LONG, filter->write_ok);
143 __set_bit(WRITE_LONG_2, filter->write_ok);
144 __set_bit(WRITE_SAME, filter->write_ok);
145 __set_bit(WRITE_SAME_16, filter->write_ok);
146 __set_bit(WRITE_SAME_32, filter->write_ok);
147 __set_bit(ERASE, filter->write_ok);
148 __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
149 __set_bit(MODE_SELECT, filter->write_ok);
150 __set_bit(LOG_SELECT, filter->write_ok);
151 __set_bit(GPCMD_BLANK, filter->write_ok);
152 __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok);
153 __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok);
154 __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok);
155 __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok);
156 __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok);
157 __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok);
158 __set_bit(GPCMD_SEND_EVENT, filter->write_ok);
159 __set_bit(GPCMD_SEND_KEY, filter->write_ok);
160 __set_bit(GPCMD_SEND_OPC, filter->write_ok);
161 __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok);
162 __set_bit(GPCMD_SET_SPEED, filter->write_ok);
163 __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
164 __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
165 __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
166 __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
167
168 /* ZBC Commands */
169 __set_bit(ZBC_OUT, filter->write_ok);
170 __set_bit(ZBC_IN, filter->read_ok);
171}
172
173int blk_verify_command(unsigned char *cmd, fmode_t mode)
174{83{
175 struct blk_cmd_filter *filter = &blk_default_cmd_filter;
176
177 /* root can do any command. */84 /* root can do any command. */
178 if (capable(CAP_SYS_RAWIO))85 if (capable(CAP_SYS_RAWIO))
179 return 0;86 return true;
180 87
181 /* Anybody who can open the device can do a read-safe command */88 /* Anybody who can open the device can do a read-safe command */
182 if (test_bit(cmd[0], filter->read_ok))89 switch (cmd[0]) {
183 return 0;90 /* Basic read-only commands */
184 91 case TEST_UNIT_READY:
185 /* Write-safe commands require a writable open */92 case REQUEST_SENSE:
186 if (test_bit(cmd[0], filter->write_ok) && (mode & FMODE_WRITE))93 case READ_6:
187 return 0;94 case READ_10:
188 95 case READ_12:
189 return -EPERM;96 case READ_16:
97 case READ_BUFFER:
98 case READ_DEFECT_DATA:
99 case READ_CAPACITY: /* also GPCMD_READ_CDVD_CAPACITY */
100 case READ_LONG:
101 case INQUIRY:
102 case MODE_SENSE:
103 case MODE_SENSE_10:
104 case LOG_SENSE:
105 case START_STOP:
106 case GPCMD_VERIFY_10:
107 case VERIFY_16:
108 case REPORT_LUNS:
109 case SERVICE_ACTION_IN_16:
110 case RECEIVE_DIAGNOSTIC:
111 case MAINTENANCE_IN: /* also GPCMD_SEND_KEY, which is a write command */
112 case GPCMD_READ_BUFFER_CAPACITY:
113 /* Audio CD commands */
114 case GPCMD_PLAY_CD:
115 case GPCMD_PLAY_AUDIO_10:
116 case GPCMD_PLAY_AUDIO_MSF:
117 case GPCMD_PLAY_AUDIO_TI:
118 case GPCMD_PAUSE_RESUME:
119 /* CD/DVD data reading */
120 case GPCMD_READ_CD:
121 case GPCMD_READ_CD_MSF:
122 case GPCMD_READ_DISC_INFO:
123 case GPCMD_READ_DVD_STRUCTURE:
124 case GPCMD_READ_HEADER:
125 case GPCMD_READ_TRACK_RZONE_INFO:
126 case GPCMD_READ_SUBCHANNEL:
127 case GPCMD_READ_TOC_PMA_ATIP:
128 case GPCMD_REPORT_KEY:
129 case GPCMD_SCAN:
130 case GPCMD_GET_CONFIGURATION:
131 case GPCMD_READ_FORMAT_CAPACITIES:
132 case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
133 case GPCMD_GET_PERFORMANCE:
134 case GPCMD_SEEK:
135 case GPCMD_STOP_PLAY_SCAN:
136 /* ZBC */
137 case ZBC_IN:
138 return true;
139 /* Basic writing commands */
140 case WRITE_6:
141 case WRITE_10:
142 case WRITE_VERIFY:
143 case WRITE_12:
144 case WRITE_VERIFY_12:
145 case WRITE_16:
146 case WRITE_LONG:
147 case WRITE_LONG_2:
148 case WRITE_SAME:
149 case WRITE_SAME_16:
150 case WRITE_SAME_32:
151 case ERASE:
152 case GPCMD_MODE_SELECT_10:
153 case MODE_SELECT:
154 case LOG_SELECT:
155 case GPCMD_BLANK:
156 case GPCMD_CLOSE_TRACK:
157 case GPCMD_FLUSH_CACHE:
158 case GPCMD_FORMAT_UNIT:
159 case GPCMD_REPAIR_RZONE_TRACK:
160 case GPCMD_RESERVE_RZONE_TRACK:
161 case GPCMD_SEND_DVD_STRUCTURE:
162 case GPCMD_SEND_EVENT:
163 case GPCMD_SEND_OPC:
164 case GPCMD_SEND_CUE_SHEET:
165 case GPCMD_SET_SPEED:
166 case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
167 case GPCMD_LOAD_UNLOAD:
168 case GPCMD_SET_STREAMING:
169 case GPCMD_SET_READ_AHEAD:
170 /* ZBC */
171 case ZBC_OUT:
172 return (mode & FMODE_WRITE);
173 default:
174 return false;
175 }
190}176}
191EXPORT_SYMBOL(blk_verify_command);177EXPORT_SYMBOL(scsi_cmd_allowed);
192 178
193static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,179static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
194 struct sg_io_hdr *hdr, fmode_t mode)180 struct sg_io_hdr *hdr, fmode_t mode)
@@ -197,7 +183,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, · 2 unmodified lines
197 183
198 if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))184 if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
199 return -EFAULT;185 return -EFAULT;
200 if (blk_verify_command(req->cmd, mode))186 if (!scsi_cmd_allowed(req->cmd, mode))
201 return -EPERM;187 return -EPERM;
202 188
203 /*189 /*
@@ -428,8 +414,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, · 224 unmodified lines
428 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))414 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
429 goto error;415 goto error;
430 416
431 err = blk_verify_command(req->cmd, mode);417 err = -EPERM;
432 if (err)418 if (!scsi_cmd_allowed(req->cmd, mode))
433 goto error;419 goto error;
434 420
435 /* default. possible overriden later */421 /* default. possible overriden later */
@@ -808,10 +794,3 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod · 372 unmodified lines
808 return err;794 return err;
809}795}
810EXPORT_SYMBOL(scsi_cmd_ioctl);796EXPORT_SYMBOL(scsi_cmd_ioctl);
811
812static int __init blk_scsi_ioctl_init(void)
813{
814 blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
815 return 0;
816}
817fs_initcall(blk_scsi_ioctl_init);
drivers/scsi/scsi_bsg.c+1−1
@@ -36,7 +36,7 @@ static int scsi_bsg_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, · 35 unmodified lines
36 36
37 if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len))37 if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len))
38 return -EFAULT;38 return -EFAULT;
39 if (blk_verify_command(sreq->cmd, mode))39 if (!scsi_cmd_allowed(sreq->cmd, mode))
40 return -EPERM;40 return -EPERM;
41 return 0;41 return 0;
42}42}
drivers/scsi/sg.c+3−2
@@ -238,8 +238,9 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd) · 237 unmodified lines
238 238
239 if (sfp->parentdp->device->type == TYPE_SCANNER)239 if (sfp->parentdp->device->type == TYPE_SCANNER)
240 return 0;240 return 0;
241 241 if (!scsi_cmd_allowed(cmd, filp->f_mode))
242 return blk_verify_command(cmd, filp->f_mode);242 return -EPERM;
243 return 0;
243}244}
244 245
245static int246static int
include/linux/blkdev.h+1−1
@@ -1343,7 +1343,7 @@ static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, · 1342 unmodified lines
1343 gfp_mask, 0);1343 gfp_mask, 0);
1344}1344}
1345 1345
1346extern int blk_verify_command(unsigned char *cmd, fmode_t mode);1346bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode);
1347 1347
1348static inline bool bdev_is_partition(struct block_device *bdev)1348static inline bool bdev_is_partition(struct block_device *bdev)
1349{1349{