Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933327AbcDKNur (ORCPT ); Mon, 11 Apr 2016 09:50:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:37483 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932410AbcDKNYA (ORCPT ); Mon, 11 Apr 2016 09:24:00 -0400 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" From: Jiri Slaby To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Douglas Gilbert , "Martin K . Petersen" , Jiri Slaby Subject: [PATCH 3.12 42/98] sg: fix dxferp in from_to case Date: Mon, 11 Apr 2016 15:22:44 +0200 Message-Id: <4a34db4214dba5fc55819c3c599eb802c6b7f237.1460380917.git.jslaby@suse.cz> X-Mailer: git-send-email 2.8.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1958 Lines: 49 From: Douglas Gilbert 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 Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen Signed-off-by: Jiri Slaby --- 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