lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  4 Apr 2016 20:29:21 -0500
From:	"Eric W. Biederman" <ebiederm@...ssion.com>
To:	Linus Torvalds <torvalds@...ux-foundation.org>
Cc:	"H. Peter Anvin" <hpa@...or.com>,
	Peter Hurley <peter@...leysoftware.com>,
	Greg KH <greg@...ah.com>, Jiri Slaby <jslaby@...e.com>,
	Aurelien Jarno <aurelien@...el32.net>,
	Andy Lutomirski <luto@...capital.net>,
	Florian Weimer <fw@...eb.enyo.de>,
	Al Viro <viro@...iv.linux.org.uk>,
	Serge Hallyn <serge.hallyn@...ntu.com>,
	Jann Horn <jann@...jh.net>,
	"security@...nel.org" <security@...nel.org>, security@...ntu.com,
	security@...ian.org, Willy Tarreau <w@....eu>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	"Eric W. Biederman" <ebiederm@...ssion.com>
Subject: [PATCH 05/13] devpts: Fail early (if appropriate) on overmount

Update the vfs with a may_overmount superblock operation, allowing
devpts to fail early if the primary mount of devpts is going to be
mounted on top of itself.

This change is in preparation for each mount of devpts being distinct
from every other mount of devpts.  To maintain a backward compatible
notion of a primary mount of devpts we need overmounts of the mount to
fail (as they do now), which requires a little vfs support so the case
can be detected.

Cause failed over mounts of devpts to go through the devpts remount
path.  This already happens as overmounts have previously been detected
late, and it looks like CentOS 6 may actually depend on this behavior
to allow changing devpts mount options by placing them in /etc/fstab.

Signed-off-by: "Eric W. Biederman" <ebiederm@...ssion.com>
---
 fs/devpts/inode.c  | 15 +++++++++++++++
 fs/namespace.c     |  8 ++++++++
 include/linux/fs.h |  1 +
 3 files changed, 24 insertions(+)

diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 14be886f987c..cb0cc4e33c3f 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -427,10 +427,25 @@ static int devpts_show_options(struct seq_file *seq, struct dentry *root)
 	return 0;
 }
 
+bool devpts_may_overmount(struct super_block *sb,
+			  int flags, const char *dev_name, void *data)
+{
+	if ((sb == devpts_mnt->mnt_sb) &&
+	    (current_user_ns() == &init_user_ns) &&
+	    !parse_newinstance(data)) {
+		down_write(&sb->s_umount);
+		devpts_remount(sb, &flags, data);
+		up_write(&sb->s_umount);
+		return false;
+	}
+	return true;
+}
+
 static const struct super_operations devpts_sops = {
 	.statfs		= simple_statfs,
 	.remount_fs	= devpts_remount,
 	.show_options	= devpts_show_options,
+	.may_overmount	= devpts_may_overmount,
 };
 
 static void *new_pts_fs_info(void)
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691b4355..90bbbabfe3c9 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2386,6 +2386,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
 {
 	struct file_system_type *type;
 	struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
+	struct super_block *path_sb;
 	struct vfsmount *mnt;
 	int err;
 
@@ -2414,6 +2415,13 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
 		}
 	}
 
+	path_sb = path->mnt->mnt_sb;
+	if ((path_sb->s_type == type) &&
+	    (path->mnt->mnt_root == path->dentry) &&
+	    path_sb->s_op->may_overmount &&
+	    !path_sb->s_op->may_overmount(path_sb, flags, name, data))
+		return -EBUSY;
+
 	mnt = vfs_kern_mount(type, flags, name, data);
 	if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
 	    !mnt->mnt_sb->s_subtype)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 045bbfe2ecfc..02a980bfad5c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1755,6 +1755,7 @@ struct super_operations {
 				  struct shrink_control *);
 	long (*free_cached_objects)(struct super_block *,
 				    struct shrink_control *);
+	bool (*may_overmount)(struct super_block *, int, const char *, void *);
 };
 
 /*
-- 
2.6.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ