[linux] 02/10: sg: Fix double-free when drives detach during SG_IO (CVE-2015-8962)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Dec 28 20:44:02 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch wheezy-security
in repository linux.

commit 895207c3328875f5c25f3919f69c45b654b2a23b
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Dec 28 16:15:00 2016 +0000

    sg: Fix double-free when drives detach during SG_IO (CVE-2015-8962)
---
 debian/changelog                                   |  1 +
 ...uble-free-when-drives-detach-during-sg_io.patch | 66 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 68 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 1d4a7d7..1fde1c3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -102,6 +102,7 @@ linux (3.2.84-1) UNRELEASED; urgency=medium
     - work-simple: Add missing #include <linux/export.h>
   * net: cleanups in sock_setsockopt() (CVE-2012-6704)
   * net: avoid signed overflows for SO_{SND|RCV}BUFFORCE (CVE-2016-9793)
+  * sg: Fix double-free when drives detach during SG_IO (CVE-2015-8962)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 28 Nov 2016 18:43:52 +0000
 
diff --git a/debian/patches/bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch b/debian/patches/bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch
new file mode 100644
index 0000000..7b45bc1
--- /dev/null
+++ b/debian/patches/bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch
@@ -0,0 +1,66 @@
+From: Calvin Owens <calvinowens at fb.com>
+Date: Fri, 30 Oct 2015 16:57:00 -0700
+Subject: sg: Fix double-free when drives detach during SG_IO
+Origin: https://git.kernel.org/linus/f3951a3709ff50990bf3e188c27d346792103432
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2015-8962
+
+In sg_common_write(), we free the block request and return -ENODEV if
+the device is detached in the middle of the SG_IO ioctl().
+
+Unfortunately, sg_finish_rem_req() also tries to free srp->rq, so we
+end up freeing rq->cmd in the already free rq object, and then free
+the object itself out from under the current user.
+
+This ends up corrupting random memory via the list_head on the rq
+object. The most common crash trace I saw is this:
+
+  ------------[ cut here ]------------
+  kernel BUG at block/blk-core.c:1420!
+  Call Trace:
+  [<ffffffff81281eab>] blk_put_request+0x5b/0x80
+  [<ffffffffa0069e5b>] sg_finish_rem_req+0x6b/0x120 [sg]
+  [<ffffffffa006bcb9>] sg_common_write.isra.14+0x459/0x5a0 [sg]
+  [<ffffffff8125b328>] ? selinux_file_alloc_security+0x48/0x70
+  [<ffffffffa006bf95>] sg_new_write.isra.17+0x195/0x2d0 [sg]
+  [<ffffffffa006cef4>] sg_ioctl+0x644/0xdb0 [sg]
+  [<ffffffff81170f80>] do_vfs_ioctl+0x90/0x520
+  [<ffffffff81258967>] ? file_has_perm+0x97/0xb0
+  [<ffffffff811714a1>] SyS_ioctl+0x91/0xb0
+  [<ffffffff81602afb>] tracesys+0xdd/0xe2
+    RIP [<ffffffff81281e04>] __blk_put_request+0x154/0x1a0
+
+The solution is straightforward: just set srp->rq to NULL in the
+failure branch so that sg_finish_rem_req() doesn't attempt to re-free
+it.
+
+Additionally, since sg_rq_end_io() will never be called on the object
+when this happens, we need to free memory backing ->cmd if it isn't
+embedded in the object itself.
+
+KASAN was extremely helpful in finding the root cause of this bug.
+
+Signed-off-by: Calvin Owens <calvinowens at fb.com>
+Acked-by: Douglas Gilbert <dgilbert at interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen at oracle.com>
+[bwh: Backported to 3.2:
+ - sg_finish_rem_req() would not free srp->rq->cmd so don't do it here either
+ - Adjust context]
+---
+ drivers/scsi/sg.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -742,8 +742,11 @@ sg_common_write(Sg_fd * sfp, Sg_request
+ 		return k;	/* probably out of space --> ENOMEM */
+ 	}
+ 	if (sdp->detached) {
+-		if (srp->bio)
++		if (srp->bio) {
+ 			blk_end_request_all(srp->rq, -EIO);
++			srp->rq = NULL;
++		}
++
+ 		sg_finish_rem_req(srp);
+ 		return -ENODEV;
+ 	}
diff --git a/debian/patches/series b/debian/patches/series
index 37d72db..ba81022 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1107,6 +1107,7 @@ bugfix/all/KEYS-Don-t-permit-request_key-to-construct-a-new-key.patch
 bugfix/all/ecryptfs-fix-handling-of-directory-opening.patch
 bugfix/all/net-cleanups-in-sock_setsockopt.patch
 bugfix/all/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch
+bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch
 
 # ABI maintenance
 debian/perf-hide-abi-change-in-3.2.30.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list