All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Van Hensbergen <ericvh@gmail.com>
To: linux-fsdevel@vger.kernel.org,
	Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Subject: [RFC][2.6 patch] Allow creation of new namespaces during mount system call
Date: Tue, 19 Apr 2005 17:13:32 -0500	[thread overview]
Message-ID: <a4e6962a05041915132f57de3f@mail.gmail.com> (raw)

The motivation behind this patch is to make private namespaces more
accessible by allowing their creation at mount/bind time.

Based on some of the FUSE permissions discussions, I wanted to check
into modifying the mount system calls -- adding a flag which created a
new namespace for the resulting mount.  I quickly discovered that what
I typically wanted (for the case of running a mount command) was to
actually create a new namespace for the parent thread (typically the
shell), inherit that namespace, and then perform the mount.

Its not clear to me that both options are needed, cloning the parent's
namespace seems to be what you want most of the time.

In order to minimize code impact I split the copy_namespace function,
perhaps the right long term solution is to change it's interface to
accommodate the changes.  Things look a bit more invasive as I moved
the copy_namespace function above do_mount.  The patch follows:

  fs/namespace.c     |  193
+++++++++++++++++++++++++++++------------------------
  include/linux/fs.h |    2 
 2 files changed, 108 insertions(+), 87 deletions(-)

--- linux-2.5/include/linux/fs.h	2005-04-19 17:02:28.530152496 -0500
+++ newns-2.5/include/linux/fs.h	2005-04-19 17:03:52.619368992 -0500
@@ -103,6 +103,8 @@ extern int dir_notify_enable;
 #define MS_REC		16384
 #define MS_VERBOSE	32768
  #define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
+#define MS_CLONE_NEWNS	(1<<17) /* clone my namespace before mount */
+#define MS_CLONE_NEWPNS (1<<18) /* clone my & my parent namespace */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
--- linux-2.5/fs/namespace.c	2005-04-19 17:02:14.551277608 -0500
+++ newns-2.5/fs/namespace.c	2005-04-19 17:03:38.227556880 -0500
@@ -991,6 +991,104 @@ int copy_mount_options(const void __user
 	return 0;
 }
 
+int update_namespace(struct task_struct *tsk, struct namespace *new_ns )
+{
+	struct namespace *namespace = tsk->namespace;
+	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
+	struct fs_struct *fs = tsk->fs;
+	struct vfsmount *p, *q;
+
+	if (!namespace)
+		return 0;
+
+	get_namespace(namespace);
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		put_namespace(namespace);
+		return -EPERM;
+	}
+
+	down_write(&tsk->namespace->sem);
+	if(!new_ns) {
+		new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
+		if (!new_ns)
+			goto out;
+
+		atomic_set(&new_ns->count, 1);
+		init_rwsem(&new_ns->sem);
+		INIT_LIST_HEAD(&new_ns->list);
+
+		/* First pass: copy the tree topology */
+		new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
+		if (!new_ns->root) {
+			up_write(&tsk->namespace->sem);
+			kfree(new_ns);
+			goto out;
+		}
+		spin_lock(&vfsmount_lock);
+		list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
+		spin_unlock(&vfsmount_lock);
+	} else 
+		get_namespace(new_ns);
+
+	/*
+	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
+	 * as belonging to new namespace.  We have already acquired a private
+	 * fs_struct, so tsk->fs->lock is not needed.
+	 */
+	p = namespace->root;
+	q = new_ns->root;
+	while (p) {
+		q->mnt_namespace = new_ns;
+		if (fs) {
+			if (p == fs->rootmnt) {
+				rootmnt = p;
+				fs->rootmnt = mntget(q);
+			}
+			if (p == fs->pwdmnt) {
+				pwdmnt = p;
+				fs->pwdmnt = mntget(q);
+			}
+			if (p == fs->altrootmnt) {
+				altrootmnt = p;
+				fs->altrootmnt = mntget(q);
+			}
+		}
+		p = next_mnt(p, namespace->root);
+		q = next_mnt(q, new_ns->root);
+	}
+	up_write(&tsk->namespace->sem);
+
+	tsk->namespace = new_ns;
+
+	if (rootmnt)
+		mntput(rootmnt);
+	if (pwdmnt)
+		mntput(pwdmnt);
+	if (altrootmnt)
+		mntput(altrootmnt);
+
+	put_namespace(namespace);
+	return 0;
+
+out:
+	put_namespace(namespace);
+	return -ENOMEM;
+}
+
+int copy_namespace(int flags, struct task_struct *tsk)
+{
+	if (!tsk->namespace)
+		return 0;
+
+	if (!(flags & CLONE_NEWNS)) {
+		get_namespace(tsk->namespace);
+		return 0;
+	}
+
+	return update_namespace( tsk, NULL );
+}
+
 /*
  * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
  * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
@@ -1033,7 +1131,14 @@ long do_mount(char * dev_name, char * di
 		mnt_flags |= MNT_NODEV;
 	if (flags & MS_NOEXEC)
 		mnt_flags |= MNT_NOEXEC;
-	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE);
+        if (flags & MS_CLONE_NEWNS)
+		copy_namespace( CLONE_NEWNS, current);
+	if (flags & MS_CLONE_NEWPNS) {
+		copy_namespace( CLONE_NEWNS, current->real_parent);
+		update_namespace( current, current->real_parent->namespace);
+	}
+
+	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE|MS_CLONE_NEWNS|MS_CLONE_NEWPNS);
 
 	/* ... and get the mountpoint */
 	retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
@@ -1059,92 +1164,6 @@ dput_out:
 	return retval;
 }
 
-int copy_namespace(int flags, struct task_struct *tsk)
-{
-	struct namespace *namespace = tsk->namespace;
-	struct namespace *new_ns;
-	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
-	struct fs_struct *fs = tsk->fs;
-	struct vfsmount *p, *q;
-
-	if (!namespace)
-		return 0;
-
-	get_namespace(namespace);
-
-	if (!(flags & CLONE_NEWNS))
-		return 0;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		put_namespace(namespace);
-		return -EPERM;
-	}
-
-	new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
-	if (!new_ns)
-		goto out;
-
-	atomic_set(&new_ns->count, 1);
-	init_rwsem(&new_ns->sem);
-	INIT_LIST_HEAD(&new_ns->list);
-
-	down_write(&tsk->namespace->sem);
-	/* First pass: copy the tree topology */
-	new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
-	if (!new_ns->root) {
-		up_write(&tsk->namespace->sem);
-		kfree(new_ns);
-		goto out;
-	}
-	spin_lock(&vfsmount_lock);
-	list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
-	spin_unlock(&vfsmount_lock);
-
-	/*
-	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
-	 * as belonging to new namespace.  We have already acquired a private
-	 * fs_struct, so tsk->fs->lock is not needed.
-	 */
-	p = namespace->root;
-	q = new_ns->root;
-	while (p) {
-		q->mnt_namespace = new_ns;
-		if (fs) {
-			if (p == fs->rootmnt) {
-				rootmnt = p;
-				fs->rootmnt = mntget(q);
-			}
-			if (p == fs->pwdmnt) {
-				pwdmnt = p;
-				fs->pwdmnt = mntget(q);
-			}
-			if (p == fs->altrootmnt) {
-				altrootmnt = p;
-				fs->altrootmnt = mntget(q);
-			}
-		}
-		p = next_mnt(p, namespace->root);
-		q = next_mnt(q, new_ns->root);
-	}
-	up_write(&tsk->namespace->sem);
-
-	tsk->namespace = new_ns;
-
-	if (rootmnt)
-		mntput(rootmnt);
-	if (pwdmnt)
-		mntput(pwdmnt);
-	if (altrootmnt)
-		mntput(altrootmnt);
-
-	put_namespace(namespace);
-	return 0;
-
-out:
-	put_namespace(namespace);
-	return -ENOMEM;
-}
-
 asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
 			  char __user * type, unsigned long flags,
 			  void __user * data)

             reply	other threads:[~2005-04-19 22:13 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-19 22:13 Eric Van Hensbergen [this message]
2005-04-19 22:23 ` [RFC][2.6 patch] Allow creation of new namespaces during mount system call Al Viro
2005-04-19 23:53   ` Eric Van Hensbergen
2005-04-20  3:33     ` Al Viro
2005-04-20  9:45       ` Jamie Lokier
2005-04-20 10:27         ` Al Viro
2005-04-20 12:03           ` Jamie Lokier
2005-04-20 12:39             ` Al Viro
2005-04-20 16:51               ` Ram
2005-04-20 17:09                 ` Al Viro
2005-04-20 17:53                   ` Miklos Szeredi
     [not found]                     ` <a4e6962a0504201107518416e9@mail.gmail.com>
2005-04-20 18:18                       ` Eric Van Hensbergen
2005-04-20 18:34                         ` Miklos Szeredi
2005-04-20 20:43                           ` Jamie Lokier
2005-04-20 20:54                             ` Al Viro
2005-04-20 22:16                               ` Jamie Lokier
2005-04-20 21:08                     ` Al Viro
2005-04-20 22:19                       ` Jamie Lokier
2005-04-20 18:00                   ` Eric Van Hensbergen
2005-04-20 18:33                   ` Ram
2005-04-20 22:04                     ` Jamie Lokier
2005-04-30  8:56                       ` Christoph Hellwig
2005-04-30 15:01                         ` Jamie Lokier
2005-05-11  9:05                           ` Christoph Hellwig
2005-04-21  7:33                   ` Mount bind filehandle (Was: Re: [RFC][2.6 patch] Allow creation of new namespaces during mount system call) Jan Hudec
2005-04-21  8:09                     ` Christoph Hellwig
2005-04-21  9:32                       ` Jan Hudec
2005-04-20 18:57                 ` [RFC][2.6 patch] Allow creation of new namespaces during mount system call Bryan Henderson
2005-04-20 19:37                   ` Miklos Szeredi
2005-04-21  0:08                     ` Bryan Henderson
2005-04-21  8:06                       ` Miklos Szeredi
2005-04-21 13:33                         ` [RFC][patch] mount permissions (was: [RFC][2.6 patch] Allow ...) Miklos Szeredi
2005-04-21 16:57                         ` [RFC][2.6 patch] Allow creation of new namespaces during mount system call Bryan Henderson
2005-04-20 20:51                   ` Al Viro
2005-04-21  0:23                     ` Bryan Henderson
2005-04-21  0:32                       ` Al Viro
2005-04-21  8:10                       ` Christoph Hellwig
2005-04-20 21:09                   ` Ram
2005-04-21  0:42                     ` Bryan Henderson
2005-04-21 19:10                       ` Ram
2005-04-20 18:25               ` Bryan Henderson
2005-04-20 12:48         ` Jan Hudec
2005-04-20 22:13           ` Jamie Lokier
2005-04-21 10:09             ` Jan Hudec
2005-04-21 18:44               ` Jamie Lokier
2005-04-21 18:52                 ` Hiding secrets from root (Was: Re: [RFC][2.6 patch] Allow creation of new namespaces during mount system call) Jan Hudec
2005-04-21 20:35                   ` Jamie Lokier
2005-04-20 13:14       ` [RFC][2.6 patch] Allow creation of new namespaces during mount system call Eric Van Hensbergen
2005-04-20 13:55         ` Eric Van Hensbergen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a4e6962a05041915132f57de3f@mail.gmail.com \
    --to=ericvh@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=viro@parcelfarce.linux.theplanet.co.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.