public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mount -o noexdev
@ 2016-05-08 18:35 Alexey Dobriyan
  2016-05-08 19:46 ` Al Viro
  0 siblings, 1 reply; 2+ messages in thread
From: Alexey Dobriyan @ 2016-05-08 18:35 UTC (permalink / raw)
  To: viro; +Cc: akpm, linux-fsdevel, linux-kernel

Searching for "rename bint mount exdev" shows that failure with EXDEV
seems somewhat unintuitive behaviour. Allow users to bypass
this restriction with "-o noexdev" flag if the source of operation is on
such mount.

Keep old semantics default so "mount --bind /tmp /tmp" works.

"mount --bind" will inherit "noexdev" flag from parent mount but it can
be cleared with mount(MS_REMOUNT) so it is possible to create exclave
with regular mount point crossing rules inside mount with relaxed mount
point rules.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

 fs/namei.c              |    4 ++--
 fs/namespace.c          |    2 ++
 fs/proc_namespace.c     |    1 +
 include/linux/mount.h   |   15 ++++++++++++++-
 include/uapi/linux/fs.h |    1 +
 5 files changed, 20 insertions(+), 3 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4118,7 +4118,7 @@ retry:
 		goto out;
 
 	error = -EXDEV;
-	if (old_path.mnt != new_path.mnt)
+	if (!mnt_can_cross(old_path.mnt, new_path.mnt))
 		goto out_dput;
 	error = may_linkat(&old_path);
 	if (unlikely(error))
@@ -4379,7 +4379,7 @@ retry:
 	}
 
 	error = -EXDEV;
-	if (old_path.mnt != new_path.mnt)
+	if (!mnt_can_cross(old_path.mnt, new_path.mnt))
 		goto exit2;
 
 	error = -EBUSY;
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2708,6 +2708,8 @@ long do_mount(const char *dev_name, const char __user *dir_name,
 		mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
 	if (flags & MS_RDONLY)
 		mnt_flags |= MNT_READONLY;
+	if (flags & MS_NOEXDEV)
+		mnt_flags |= MNT_NOEXDEV;
 
 	/* The default atime for remount is preservation */
 	if ((flags & MS_REMOUNT) &&
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -67,6 +67,7 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
 		{ MNT_NOATIME, ",noatime" },
 		{ MNT_NODIRATIME, ",nodiratime" },
 		{ MNT_RELATIME, ",relatime" },
+		{ MNT_NOEXDEV, ",noexdev" },
 		{ 0, NULL }
 	};
 	const struct proc_fs_info *fs_infop;
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -28,6 +28,7 @@ struct mnt_namespace;
 #define MNT_NODIRATIME	0x10
 #define MNT_RELATIME	0x20
 #define MNT_READONLY	0x40	/* does the user want this to be r/o? */
+#define MNT_NOEXDEV	0x80	/* allow link(), rename() to cross mount point */
 
 #define MNT_SHRINKABLE	0x100
 #define MNT_WRITE_HOLD	0x200
@@ -44,7 +45,7 @@ struct mnt_namespace;
 #define MNT_SHARED_MASK	(MNT_UNBINDABLE)
 #define MNT_USER_SETTABLE_MASK  (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \
 				 | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \
-				 | MNT_READONLY)
+				 | MNT_READONLY | MNT_NOEXDEV)
 #define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )
 
 #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
@@ -95,4 +96,16 @@ extern void mark_mounts_for_expiry(struct list_head *mounts);
 
 extern dev_t name_to_dev_t(const char *name);
 
+/*
+ * Can operation be done in mnt1 => mnt2 direction?
+ * Not symmetric relation!
+ */
+static inline bool mnt_can_cross(struct vfsmount *mnt1, struct vfsmount *mnt2)
+{
+	if (mnt1 == mnt2)
+		return true;
+	if ((mnt1->mnt_flags & MNT_NOEXDEV) && mnt1->mnt_sb == mnt2->mnt_sb)
+		return true;
+	return false;
+}
 #endif /* _LINUX_MOUNT_H */
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -130,6 +130,7 @@ struct inodes_stat_t {
 #define MS_I_VERSION	(1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
 #define MS_LAZYTIME	(1<<25) /* Update the on-disk [acm]times lazily */
+#define MS_NOEXDEV	(1<<26) /* Allow link(), rename() to cross mount point */
 
 /* These sb flags are internal to the kernel */
 #define MS_NOSEC	(1<<28)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-05-08 19:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-08 18:35 [PATCH] mount -o noexdev Alexey Dobriyan
2016-05-08 19:46 ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox