linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Tyler Hicks <code@tyhicks.com>, ecryptfs@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org,
	Amir Goldstein <amir73il@gmail.com>,
	Christian Brauner <christian.brauner@ubuntu.com>
Subject: [PATCH 2/3] ecryptfs: use private mount in path
Date: Fri,  9 Apr 2021 18:24:21 +0200	[thread overview]
Message-ID: <20210409162422.1326565-3-brauner@kernel.org> (raw)
In-Reply-To: <20210409162422.1326565-1-brauner@kernel.org>

From: Christian Brauner <christian.brauner@ubuntu.com>

Since [1] we support creating private mounts from a given path's
vfsmount. This makes them very suitable for any filesystem or
filesystem functionality that piggybacks on paths of another filesystem.
Overlayfs, cachefiles, and ecryptfs are three prime examples.

Since private mounts aren't attached in the filesystem they aren't
affected by mount property changes after ecryptfs makes use of them.
This seems a rather desirable property as the underlying path can't e.g.
suddenly go from read-write to read-only and in general it means that
ecryptfs is always in full control of the underlying mount after the
user has allowed it to be used (apart from operations that affect the
superblock of course).

Besides that it also makes things simpler for a variety of other vfs
features. One concrete example is fanotify. When the path->mnt of the
path that is used as a cache has been marked with FAN_MARK_MOUNT the
semantics get tricky as it isn't clear whether the watchers of path->mnt
should get notified about fsnotify events when files are created by
cachefilesd via path->mnt. Using a private mount let's us elegantly
handle this case too and aligns the behavior of stacks created by
overlayfs and cachefiles.

Reading through the codebase of ecryptfs it currently takes path->mnt
and then retrieves that path whenever it needs to perform operations in
the underlying filesystem. Simply drop the old path->mnt once we've
created a private mount and place the new private mnt into path->mnt.
This should be all that is needed to make this work since ecryptfs uses
the same lower path's vfsmount to construct the paths it uses to operate
on the underlying filesystem.

[1]: c771d683a62e ("vfs: introduce clone_private_mount()")
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: Tyler Hicks <code@tyhicks.com>
Cc: ecryptfs@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
 fs/ecryptfs/main.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index cdf40a54a35d..9dcf9a0dd37b 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -476,6 +476,7 @@ static struct file_system_type ecryptfs_fs_type;
 static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags,
 			const char *dev_name, void *raw_data)
 {
+	struct vfsmount *mnt = NULL;
 	struct super_block *s;
 	struct ecryptfs_sb_info *sbi;
 	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
@@ -537,6 +538,14 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 		goto out_free;
 	}
 
+	mnt = clone_private_mount(&path);
+	if (IS_ERR(mnt)) {
+		rc = PTR_ERR(mnt);
+		mnt = NULL;
+		pr_warn("Failed to create private mount for ecryptfs\n");
+		goto out_free;
+	}
+
 	if (check_ruid && !uid_eq(d_inode(path.dentry)->i_uid, current_uid())) {
 		rc = -EPERM;
 		printk(KERN_ERR "Mount of device (uid: %d) not owned by "
@@ -592,6 +601,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 
 	/* ->kill_sb() will take care of root_info */
 	ecryptfs_set_dentry_private(s->s_root, root_info);
+
+	/* We've created a private clone of this mount above so drop it now. */
+	mntput(path.mnt);
+
+	/* Use our private mount from now on. */
+	path.mnt = mnt;
+
 	root_info->lower_path = path;
 
 	s->s_flags |= SB_ACTIVE;
@@ -599,6 +615,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 
 out_free:
 	path_put(&path);
+	mntput(mnt);
 out1:
 	deactivate_locked_super(s);
 out:
-- 
2.27.0


  parent reply	other threads:[~2021-04-09 16:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-09 16:24 [PATCH 0/3] ecryptfs: fixes and port to private mounts Christian Brauner
2021-04-09 16:24 ` [PATCH 1/3] ecryptfs: remove unused helpers Christian Brauner
2021-04-19  4:48   ` Tyler Hicks
2021-04-19 13:49     ` Al Viro
2021-04-19 14:22       ` Tyler Hicks
2021-04-19 15:27         ` Al Viro
2021-04-19 14:37       ` Christian Brauner
2021-04-09 16:24 ` Christian Brauner [this message]
2021-04-10  0:31   ` [PATCH 2/3] ecryptfs: use private mount in path Al Viro
2021-04-10 12:30     ` Christian Brauner
2021-04-12  8:53       ` Miklos Szeredi
2021-04-09 16:24 ` [PATCH 3/3] ecryptfs: extend ro check to private mount Christian Brauner

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=20210409162422.1326565-3-brauner@kernel.org \
    --to=brauner@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=christian.brauner@ubuntu.com \
    --cc=code@tyhicks.com \
    --cc=ecryptfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).