[RFC,09/27] vfs: Allow mounting to other namespaces
diff mbox series

Message ID 155024692658.21651.7276705643207668882.stgit@warthog.procyon.org.uk
State New
Headers show
Series
  • Containers and using authenticated filesystems
Related show

Commit Message

David Howells Feb. 15, 2019, 4:08 p.m. UTC
Currently sys_move_mount() and sys_mount(MS_MOVE) prevent the caller from
moving a mount into a namespace not their own.  Relax this such that any
mount can be mounted onto any given mountpoint provided that the source
mount is either detached or the same namespace as the destination.

This permits container namespaces to be built from the outside rather than
from the inside.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/namespace.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

Comments

Al Viro Feb. 17, 2019, 12:14 a.m. UTC | #1
On Fri, Feb 15, 2019 at 04:08:46PM +0000, David Howells wrote:
> Currently sys_move_mount() and sys_mount(MS_MOVE) prevent the caller from
> moving a mount into a namespace not their own.  Relax this such that any
> mount can be mounted onto any given mountpoint provided that the source
> mount is either detached or the same namespace as the destination.
> 
> This permits container namespaces to be built from the outside rather than
> from the inside.

I'm looking forward to your analysis of security implications, as well as
the proof that attach_recursive_mnt() won't get confused by that...

Patch
diff mbox series

diff --git a/fs/namespace.c b/fs/namespace.c
index 22cf4a8f8065..804601b6297c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2627,12 +2627,10 @@  static int do_move_mount(struct path *old_path, struct path *new_path)
 	ns = old->mnt_ns;
 
 	err = -EINVAL;
-	/* The mountpoint must be in our namespace. */
-	if (!check_mnt(p))
-		goto out;
-
-	/* The thing moved should be either ours or completely unattached. */
-	if (attached && !check_mnt(old))
+	/* The new mount must be either unattached or in the same namespace as
+	 * the mountpoint.
+	 */
+	if (attached && old->mnt_ns != p->mnt_ns)
 		goto out;
 
 	if (!attached && !is_anon_ns(ns))