lkml.org 
[lkml]   [2018]   [Sep]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 18/63] sr: pass down correctly sized SCSI sense buffer
    3.16.58-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jens Axboe <axboe@kernel.dk>

    commit f7068114d45ec55996b9040e98111afa56e010fe upstream.

    We're casting the CDROM layer request_sense to the SCSI sense
    buffer, but the former is 64 bytes and the latter is 96 bytes.
    As we generally allocate these on the stack, we end up blowing
    up the stack.

    Fix this by wrapping the scsi_execute() call with a properly
    sized sense buffer, and copying back the bits for the CDROM
    layer.

    Reported-by: Piotr Gabriel Kosinski <pg.kosinski@gmail.com>
    Reported-by: Daniel Shapira <daniel@twistlock.com>
    Tested-by: Kees Cook <keescook@chromium.org>
    Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    [bwh: Despite what the "Fixes" field says, a buffer overrun was already
    possible if the sense data was really > 64 bytes long.
    Backported to 3.16:
    - We always need to allocate a sense buffer in order to call
    scsi_normalize_sense()
    - Remove the existing conditional heap-allocation of the sense buffer]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/scsi/sr_ioctl.c | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    --- a/drivers/scsi/sr_ioctl.c
    +++ b/drivers/scsi/sr_ioctl.c
    @@ -188,30 +188,25 @@ int sr_do_ioctl(Scsi_CD *cd, struct pack
    struct scsi_device *SDev;
    struct scsi_sense_hdr sshdr;
    int result, err = 0, retries = 0;
    - struct request_sense *sense = cgc->sense;
    + unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];

    SDev = cd->device;

    - if (!sense) {
    - sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
    - if (!sense) {
    - err = -ENOMEM;
    - goto out;
    - }
    - }
    -
    retry:
    if (!scsi_block_when_processing_errors(SDev)) {
    err = -ENODEV;
    goto out;
    }

    - memset(sense, 0, sizeof(*sense));
    + memset(sense_buffer, 0, sizeof(sense_buffer));
    result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
    - cgc->buffer, cgc->buflen, (char *)sense,
    + cgc->buffer, cgc->buflen, sense_buffer,
    cgc->timeout, IOCTL_RETRIES, 0, NULL);

    - scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);
    + scsi_normalize_sense(sense_buffer, sizeof(sense_buffer), &sshdr);
    +
    + if (cgc->sense)
    + memcpy(cgc->sense, sense_buffer, sizeof(*cgc->sense));

    /* Minimal error checking. Ignore cases we know about, and report the rest. */
    if (driver_byte(result) != 0) {
    @@ -268,8 +263,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct pack

    /* Wake up a process waiting for device */
    out:
    - if (!cgc->sense)
    - kfree(sense);
    cgc->stat = err;
    return err;
    }
    \
     
     \ /
      Last update: 2018-09-22 02:27    [W:4.835 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site