From: Christian Brauner <christian.brauner@xxxxxxxxxx> Various filesystems use the lookup_one_len_unlocked() helper to lookup a single path component relative to a well-known starting point. Allow such filesystems to support idmapped mounts by enabling lookup_one_len_unlocked() to take the idmap into account when calling inode_permission(). Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: linux-fsdevel@xxxxxxxxxxxxxxx Signed-off-by: Christian Brauner <christian.brauner@xxxxxxxxxx> --- fs/ecryptfs/inode.c | 3 ++- fs/exportfs/expfs.c | 3 ++- fs/namei.c | 9 +++++---- fs/overlayfs/namei.c | 3 ++- include/linux/namei.h | 3 ++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 16d50dface59..755975a214a9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -405,7 +405,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, name = encrypted_and_encoded_name; } - lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len); + lower_dentry = lookup_one_len_unlocked(&init_user_ns, name, + lower_dir_dentry, len); if (IS_ERR(lower_dentry)) { ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " "[%ld] on lower_dentry = [%s]\n", __func__, diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 9ba408594094..0e35efba2bc5 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -145,7 +145,8 @@ static struct dentry *reconnect_one(struct vfsmount *mnt, if (err) goto out_err; dprintk("%s: found name: %s\n", __func__, nbuf); - tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf)); + tmp = lookup_one_len_unlocked(&init_user_ns, nbuf, + parent, strlen(nbuf)); if (IS_ERR(tmp)) { dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp)); err = PTR_ERR(tmp); diff --git a/fs/namei.c b/fs/namei.c index 5a3e8188585e..53561311b492 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2679,14 +2679,15 @@ EXPORT_SYMBOL(lookup_one_len); * Unlike lookup_one_len, it should be called without the parent * i_mutex held, and will take the i_mutex itself if necessary. */ -struct dentry *lookup_one_len_unlocked(const char *name, - struct dentry *base, int len) +struct dentry *lookup_one_len_unlocked(struct user_namespace *mnt_userns, + const char *name, struct dentry *base, + int len) { struct qstr this; int err; struct dentry *ret; - err = lookup_one_len_common(&init_user_ns, name, base, len, &this); + err = lookup_one_len_common(mnt_userns, name, base, len, &this); if (err) return ERR_PTR(err); @@ -2708,7 +2709,7 @@ EXPORT_SYMBOL(lookup_one_len_unlocked); struct dentry *lookup_positive_unlocked(const char *name, struct dentry *base, int len) { - struct dentry *ret = lookup_one_len_unlocked(name, base, len); + struct dentry *ret = lookup_one_len_unlocked(&init_user_ns, name, base, len); if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) { dput(ret); ret = ERR_PTR(-ENOENT); diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 210cd6f66e28..291985b79a6d 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -202,7 +202,8 @@ static struct dentry *ovl_lookup_positive_unlocked(const char *name, struct dentry *base, int len, bool drop_negative) { - struct dentry *ret = lookup_one_len_unlocked(name, base, len); + struct dentry *ret = lookup_one_len_unlocked(&init_user_ns, name, + base, len); if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) { if (drop_negative && ret->d_lockref.count == 1) { diff --git a/include/linux/namei.h b/include/linux/namei.h index 7f8b58b43075..b4073e36450a 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -67,7 +67,8 @@ extern struct dentry *kern_path_locked(const char *, struct path *); extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); extern struct dentry *lookup_one_len(struct user_namespace *mnt_userns, const char *, struct dentry *, int); -extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); +extern struct dentry *lookup_one_len_unlocked(struct user_namespace *, + const char *, struct dentry *, int); extern struct dentry *lookup_positive_unlocked(const char *, struct dentry *, int); extern int follow_down_one(struct path *); -- 2.30.2