lkml.org 
[lkml]   [2016]   [Apr]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 42/98] sg: fix dxferp in from_to case
    Date
    From: Douglas Gilbert <dgilbert@interlog.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    commit 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 upstream.

    One of the strange things that the original sg driver did was let the
    user provide both a data-out buffer (it followed the sg_header+cdb)
    _and_ specify a reply length greater than zero. What happened was that
    the user data-out buffer was copied into some kernel buffers and then
    the mid level was told a read type operation would take place with the
    data from the device overwriting the same kernel buffers. The user would
    then read those kernel buffers back into the user space.

    From what I can tell, the above action was broken by commit fad7f01e61bf
    ("sg: set dxferp to NULL for READ with the older SG interface") in 2008
    and syzkaller found that out recently.

    Make sure that a user space pointer is passed through when data follows
    the sg_header structure and command. Fix the abnormal case when a
    non-zero reply_len is also given.

    Fixes: fad7f01e61bf737fe8a3740d803f000db57ecac6
    Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
    Reviewed-by: Ewan Milne <emilne@redhat.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    drivers/scsi/sg.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
    index 0be16bf5f0cd..1f65e32db285 100644
    --- a/drivers/scsi/sg.c
    +++ b/drivers/scsi/sg.c
    @@ -633,7 +633,8 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
    else
    hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
    hp->dxfer_len = mxsize;
    - if (hp->dxfer_direction == SG_DXFER_TO_DEV)
    + if ((hp->dxfer_direction == SG_DXFER_TO_DEV) ||
    + (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV))
    hp->dxferp = (char __user *)buf + cmd_size;
    else
    hp->dxferp = NULL;
    --
    2.8.1
    \
     
     \ /
      Last update: 2016-04-11 16:02    [W:4.138 / U:0.224 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site