]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: sg: Change next_cmd_len handling to mirror upstream
authorBen Hutchings <ben@decadent.org.uk>
Thu, 28 May 2020 17:54:25 +0000 (18:54 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 11 Jun 2020 18:05:43 +0000 (19:05 +0100)
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>
drivers/scsi/sg.c

index 3dd6408fa1398bfc6c75c6e848abcb950b860336..ecdf6c7ff2ccf42365a38a4ce33639bea50967b8 100644 (file)
@@ -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: