summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2020-05-28 18:54:25 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-06-11 19:05:43 +0100
commitf4c55b72c7d3d87945acdee027d7b07cdbc2f8b7 (patch)
tree573b41927e8fcece2823ba4c39394421fcb36873
parentfc23502b1025b597c6cf4b479b52a466724944a1 (diff)
downloadlinux-stable-f4c55b72c7d3d87945acdee027d7b07cdbc2f8b7.tar.gz
linux-stable-f4c55b72c7d3d87945acdee027d7b07cdbc2f8b7.tar.bz2
linux-stable-f4c55b72c7d3d87945acdee027d7b07cdbc2f8b7.zip
scsi: sg: Change next_cmd_len handling to mirror upstream
Change the type of next_cmd_len to unsigned char, done in upstream commit 65c26a0f3969 "sg: relax 16 byte cdb restriction". Move the range check from sg_write() to sg_ioctl(), which was done by that commit and commit bf33f87dd04c "scsi: sg: check length passed to SG_NEXT_CMD_LEN". Continue limiting the command length to MAX_COMMAND_SIZE (16). Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--drivers/scsi/sg.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3dd6408fa139..ecdf6c7ff2cc 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -160,7 +160,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
char low_dma; /* as in parent but possibly overridden to 1 */
char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
- char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
+ unsigned char next_cmd_len; /* 0: automatic, >0: use on next write() */
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
char mmap_called; /* 0 -> mmap() never called on this fd */
struct kref f_ref;
@@ -653,12 +653,6 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
buf += SZ_SG_HEADER;
__get_user(opcode, buf);
if (sfp->next_cmd_len > 0) {
- if (sfp->next_cmd_len > MAX_COMMAND_SIZE) {
- SCSI_LOG_TIMEOUT(1, printk("sg_write: command length too long\n"));
- sfp->next_cmd_len = 0;
- sg_remove_request(sfp, srp);
- return -EIO;
- }
cmd_size = sfp->next_cmd_len;
sfp->next_cmd_len = 0; /* reset so only this write() effected */
} else {
@@ -1045,6 +1039,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
result = get_user(val, ip);
if (result)
return result;
+ if (val > MAX_COMMAND_SIZE)
+ return -ENOMEM;
sfp->next_cmd_len = (val > 0) ? val : 0;
return 0;
case SG_GET_VERSION_NUM: