Skip to content

Commit

Permalink
sg: fix dxferp in from_to case
Browse files Browse the repository at this point in the history
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 fad7f01
("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: fad7f01
Cc: <[email protected]> #v2.6.28+
Signed-off-by: Douglas Gilbert <[email protected]>
Reviewed-by: Ewan Milne <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
doug-gilbert authored and martinkpetersen committed Mar 10, 2016
1 parent ff06c5f commit 5ecee0a
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion drivers/scsi/sg.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,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;
Expand Down

0 comments on commit 5ecee0a

Please sign in to comment.