[linux] 02/02: propogate_mnt: Handle the first propogated copy being a slave (CVE-2016-4581)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Sat May 28 05:45:22 UTC 2016


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

carnil pushed a commit to branch jessie-security
in repository linux.

commit 499c129373b8b78e8865a38f977cc86932f7ded4
Author: Salvatore Bonaccorso <carnil at debian.org>
Date:   Fri May 27 20:02:23 2016 +0200

    propogate_mnt: Handle the first propogated copy being a slave (CVE-2016-4581)
---
 debian/changelog                                   |   2 +
 ...nt-Handle-the-first-propogated-copy-being.patch | 131 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 134 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 7de897f..c92c632 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -23,6 +23,8 @@ linux (3.16.7-ckt25-2+deb8u1) UNRELEASED; urgency=medium
   * [x86] xen: suppress hugetlbfs in PV guests (CVE-2016-3961)
   * get_rock_ridge_filename(): handle malformed NM entries (CVE-2016-4913)
   * fs/pnode.c: treat zero mnt_group_id-s as unequal
+  * propogate_mnt: Handle the first propogated copy being a slave
+    (CVE-2016-4581)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Wed, 30 Mar 2016 16:32:07 +0100
 
diff --git a/debian/patches/bugfix/all/propogate_mnt-Handle-the-first-propogated-copy-being.patch b/debian/patches/bugfix/all/propogate_mnt-Handle-the-first-propogated-copy-being.patch
new file mode 100644
index 0000000..f9c9e42
--- /dev/null
+++ b/debian/patches/bugfix/all/propogate_mnt-Handle-the-first-propogated-copy-being.patch
@@ -0,0 +1,131 @@
+From: "Eric W. Biederman" <ebiederm at xmission.com>
+Date: Thu, 5 May 2016 09:29:29 -0500
+Subject: propogate_mnt: Handle the first propogated copy being a slave
+Origin: https://git.kernel.org/linus/5ec0811d30378ae104f250bfc9b3640242d81e3f
+
+When the first propgated copy was a slave the following oops would result:
+> BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
+> IP: [<ffffffff811fba4e>] propagate_one+0xbe/0x1c0
+> PGD bacd4067 PUD bac66067 PMD 0
+> Oops: 0000 [#1] SMP
+> Modules linked in:
+> CPU: 1 PID: 824 Comm: mount Not tainted 4.6.0-rc5userns+ #1523
+> Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
+> task: ffff8800bb0a8000 ti: ffff8800bac3c000 task.ti: ffff8800bac3c000
+> RIP: 0010:[<ffffffff811fba4e>]  [<ffffffff811fba4e>] propagate_one+0xbe/0x1c0
+> RSP: 0018:ffff8800bac3fd38  EFLAGS: 00010283
+> RAX: 0000000000000000 RBX: ffff8800bb77ec00 RCX: 0000000000000010
+> RDX: 0000000000000000 RSI: ffff8800bb58c000 RDI: ffff8800bb58c480
+> RBP: ffff8800bac3fd48 R08: 0000000000000001 R09: 0000000000000000
+> R10: 0000000000001ca1 R11: 0000000000001c9d R12: 0000000000000000
+> R13: ffff8800ba713800 R14: ffff8800bac3fda0 R15: ffff8800bb77ec00
+> FS:  00007f3c0cd9b7e0(0000) GS:ffff8800bfb00000(0000) knlGS:0000000000000000
+> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+> CR2: 0000000000000010 CR3: 00000000bb79d000 CR4: 00000000000006e0
+> Stack:
+>  ffff8800bb77ec00 0000000000000000 ffff8800bac3fd88 ffffffff811fbf85
+>  ffff8800bac3fd98 ffff8800bb77f080 ffff8800ba713800 ffff8800bb262b40
+>  0000000000000000 0000000000000000 ffff8800bac3fdd8 ffffffff811f1da0
+> Call Trace:
+>  [<ffffffff811fbf85>] propagate_mnt+0x105/0x140
+>  [<ffffffff811f1da0>] attach_recursive_mnt+0x120/0x1e0
+>  [<ffffffff811f1ec3>] graft_tree+0x63/0x70
+>  [<ffffffff811f1f6b>] do_add_mount+0x9b/0x100
+>  [<ffffffff811f2c1a>] do_mount+0x2aa/0xdf0
+>  [<ffffffff8117efbe>] ? strndup_user+0x4e/0x70
+>  [<ffffffff811f3a45>] SyS_mount+0x75/0xc0
+>  [<ffffffff8100242b>] do_syscall_64+0x4b/0xa0
+>  [<ffffffff81988f3c>] entry_SYSCALL64_slow_path+0x25/0x25
+> Code: 00 00 75 ec 48 89 0d 02 22 22 01 8b 89 10 01 00 00 48 89 05 fd 21 22 01 39 8e 10 01 00 00 0f 84 e0 00 00 00 48 8b 80 d8 00 00 00 <48> 8b 50 10 48 89 05 df 21 22 01 48 89 15 d0 21 22 01 8b 53 30
+> RIP  [<ffffffff811fba4e>] propagate_one+0xbe/0x1c0
+>  RSP <ffff8800bac3fd38>
+> CR2: 0000000000000010
+> ---[ end trace 2725ecd95164f217 ]---
+
+This oops happens with the namespace_sem held and can be triggered by
+non-root users.  An all around not pleasant experience.
+
+To avoid this scenario when finding the appropriate source mount to
+copy stop the walk up the mnt_master chain when the first source mount
+is encountered.
+
+Further rewrite the walk up the last_source mnt_master chain so that
+it is clear what is going on.
+
+The reason why the first source mount is special is that it it's
+mnt_parent is not a mount in the dest_mnt propagation tree, and as
+such termination conditions based up on the dest_mnt mount propgation
+tree do not make sense.
+
+To avoid other kinds of confusion last_dest is not changed when
+computing last_source.  last_dest is only used once in propagate_one
+and that is above the point of the code being modified, so changing
+the global variable is meaningless and confusing.
+
+Cc: stable at vger.kernel.org
+fixes: f2ebb3a921c1ca1e2ddd9242e95a1989a50c4c68 ("smarter propagate_mnt()")
+Reported-by: Tycho Andersen <tycho.andersen at canonical.com>
+Reviewed-by: Seth Forshee <seth.forshee at canonical.com>
+Tested-by: Seth Forshee <seth.forshee at canonical.com>
+Signed-off-by: "Eric W. Biederman" <ebiederm at xmission.com>
+---
+ fs/pnode.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/fs/pnode.c b/fs/pnode.c
+index c524fdd..9989970 100644
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -198,7 +198,7 @@ static struct mount *next_group(struct mount *m, struct mount *origin)
+ 
+ /* all accesses are serialized by namespace_sem */
+ static struct user_namespace *user_ns;
+-static struct mount *last_dest, *last_source, *dest_master;
++static struct mount *last_dest, *first_source, *last_source, *dest_master;
+ static struct mountpoint *mp;
+ static struct hlist_head *list;
+ 
+@@ -221,20 +221,22 @@ static int propagate_one(struct mount *m)
+ 		type = CL_MAKE_SHARED;
+ 	} else {
+ 		struct mount *n, *p;
++		bool done;
+ 		for (n = m; ; n = p) {
+ 			p = n->mnt_master;
+-			if (p == dest_master || IS_MNT_MARKED(p)) {
+-				while (last_dest->mnt_master != p) {
+-					last_source = last_source->mnt_master;
+-					last_dest = last_source->mnt_parent;
+-				}
+-				if (!peers(n, last_dest)) {
+-					last_source = last_source->mnt_master;
+-					last_dest = last_source->mnt_parent;
+-				}
++			if (p == dest_master || IS_MNT_MARKED(p))
+ 				break;
+-			}
+ 		}
++		do {
++			struct mount *parent = last_source->mnt_parent;
++			if (last_source == first_source)
++				break;
++			done = parent->mnt_master == p;
++			if (done && peers(n, parent))
++				break;
++			last_source = last_source->mnt_master;
++		} while (!done);
++
+ 		type = CL_SLAVE;
+ 		/* beginning of peer group among the slaves? */
+ 		if (IS_MNT_SHARED(m))
+@@ -286,6 +288,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
+ 	 */
+ 	user_ns = current->nsproxy->mnt_ns->user_ns;
+ 	last_dest = dest_mnt;
++	first_source = source_mnt;
+ 	last_source = source_mnt;
+ 	mp = dest_mp;
+ 	list = tree_list;
+-- 
+2.8.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 6115d742..a776b50 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -676,3 +676,4 @@ bugfix/all/atl2-disable-unimplemented-scatter-gather-feature.patch
 bugfix/x86/x86-mm-xen-Suppress-hugetlbfs-in-PV-guests.patch
 bugfix/all/get_rock_ridge_filename-handle-malformed-NM-entries.patch
 bugfix/all/fs-pnode.c-treat-zero-mnt_group_id-s-as-unequal.patch
+bugfix/all/propogate_mnt-Handle-the-first-propogated-copy-being.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