ovl: use ovl_lookup_upper() wrapper
authorChristian Brauner <brauner@kernel.org>
Mon, 4 Apr 2022 10:51:49 +0000 (12:51 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 28 Apr 2022 14:31:11 +0000 (16:31 +0200)
Introduce ovl_lookup_upper() as a simple wrapper around lookup_one().
Make it clear in the helper's name that this only operates on the upper
layer. The wrapper will take upper layer's idmapping into account when
checking permission in lookup_one().

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/overlayfs.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/overlayfs/util.c

index 2860ab3ccc6b39f0e1613867ec277f26ceccbda1..b531b5af8c6811b60b9d9f6fd9057423159f2a36 100644 (file)
@@ -486,7 +486,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin,
        if (err)
                goto out;
 
-       index = lookup_one_len(name.name, indexdir, name.len);
+       index = ovl_lookup_upper(ofs, name.name, indexdir, name.len);
        if (IS_ERR(index)) {
                err = PTR_ERR(index);
        } else {
@@ -535,8 +535,8 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
                return err;
 
        inode_lock_nested(udir, I_MUTEX_PARENT);
-       upper = lookup_one_len(c->dentry->d_name.name, upperdir,
-                              c->dentry->d_name.len);
+       upper = ovl_lookup_upper(ofs, c->dentry->d_name.name, upperdir,
+                                c->dentry->d_name.len);
        err = PTR_ERR(upper);
        if (!IS_ERR(upper)) {
                err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper);
@@ -699,7 +699,8 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
                        goto cleanup;
        }
 
-       upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len);
+       upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir,
+                                c->destname.len);
        err = PTR_ERR(upper);
        if (IS_ERR(upper))
                goto cleanup;
@@ -751,7 +752,8 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c)
 
        inode_lock_nested(udir, I_MUTEX_PARENT);
 
-       upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len);
+       upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir,
+                                c->destname.len);
        err = PTR_ERR(upper);
        if (!IS_ERR(upper)) {
                err = ovl_do_link(ofs, temp, udir, upper);
index 8f7917474ee25c88052a4e56f6ab8e3657acd7d9..927abe7e7ab21b1ea5dfe0645ee45c089ede7d0c 100644 (file)
@@ -51,7 +51,7 @@ struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir)
        /* counter is allowed to wrap, since temp dentries are ephemeral */
        snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
 
-       temp = lookup_one_len(name, workdir, strlen(name));
+       temp = ovl_lookup_upper(ofs, name, workdir, strlen(name));
        if (!IS_ERR(temp) && temp->d_inode) {
                pr_err("workdir/%s already exists\n", name);
                dput(temp);
@@ -155,8 +155,8 @@ int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir,
         * to it unhashed and negative. If that happens, try to
         * lookup a new hashed and positive dentry.
         */
-       d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
-                          dentry->d_name.len);
+       d = ovl_lookup_upper(ofs, dentry->d_name.name, dentry->d_parent,
+                            dentry->d_name.len);
        if (IS_ERR(d)) {
                pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
                        dentry, err);
@@ -333,9 +333,8 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
 
        inode_lock_nested(udir, I_MUTEX_PARENT);
        newdentry = ovl_create_real(ofs, udir,
-                                   lookup_one_len(dentry->d_name.name,
-                                                  upperdir,
-                                                  dentry->d_name.len),
+                                   ovl_lookup_upper(ofs, dentry->d_name.name,
+                                                    upperdir, dentry->d_name.len),
                                    attr);
        err = PTR_ERR(newdentry);
        if (IS_ERR(newdentry))
@@ -488,8 +487,8 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
        if (err)
                goto out;
 
-       upper = lookup_one_len(dentry->d_name.name, upperdir,
-                              dentry->d_name.len);
+       upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
+                                dentry->d_name.len);
        err = PTR_ERR(upper);
        if (IS_ERR(upper))
                goto out_unlock;
@@ -771,8 +770,8 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
        if (err)
                goto out_dput;
 
-       upper = lookup_one_len(dentry->d_name.name, upperdir,
-                              dentry->d_name.len);
+       upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
+                                dentry->d_name.len);
        err = PTR_ERR(upper);
        if (IS_ERR(upper))
                goto out_unlock;
@@ -819,8 +818,8 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir,
        }
 
        inode_lock_nested(dir, I_MUTEX_PARENT);
-       upper = lookup_one_len(dentry->d_name.name, upperdir,
-                              dentry->d_name.len);
+       upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
+                                dentry->d_name.len);
        err = PTR_ERR(upper);
        if (IS_ERR(upper))
                goto out_unlock;
@@ -1195,8 +1194,8 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
 
        trap = lock_rename(new_upperdir, old_upperdir);
 
-       olddentry = lookup_one_len(old->d_name.name, old_upperdir,
-                                  old->d_name.len);
+       olddentry = ovl_lookup_upper(ofs, old->d_name.name, old_upperdir,
+                                    old->d_name.len);
        err = PTR_ERR(olddentry);
        if (IS_ERR(olddentry))
                goto out_unlock;
@@ -1205,8 +1204,8 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
        if (!ovl_matches_upper(old, olddentry))
                goto out_dput_old;
 
-       newdentry = lookup_one_len(new->d_name.name, new_upperdir,
-                                  new->d_name.len);
+       newdentry = ovl_lookup_upper(ofs, new->d_name.name, new_upperdir,
+                                    new->d_name.len);
        err = PTR_ERR(newdentry);
        if (IS_ERR(newdentry))
                goto out_dput_old;
index bc81f279b170b7f8c0613a82013e8e87eeceb7eb..e91f0df914f96803cfb68e8d0c1786b423bde7a0 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/uuid.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 #include "ovl_entry.h"
 
 #undef pr_fmt
@@ -310,6 +311,13 @@ static inline struct dentry *ovl_do_tmpfile(struct ovl_fs *ofs,
        return ret;
 }
 
+static inline struct dentry *ovl_lookup_upper(struct ovl_fs *ofs,
+                                             const char *name,
+                                             struct dentry *base, int len)
+{
+       return lookup_one(ovl_upper_mnt_userns(ofs), name, base, len);
+}
+
 static inline bool ovl_open_flags_need_copy_up(int flags)
 {
        if (!flags)
index 9c580ef8cd6fcfdac970ea536e998149b6ebf23a..1d06222a496cc1aa385b29fc0299f69115b62250 100644 (file)
@@ -1013,7 +1013,7 @@ void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
                if (WARN_ON(!p->is_whiteout || !p->is_upper))
                        continue;
 
-               dentry = lookup_one_len(p->name, upper, p->len);
+               dentry = ovl_lookup_upper(ofs, p->name, upper, p->len);
                if (IS_ERR(dentry)) {
                        pr_err("lookup '%s/%.*s' failed (%i)\n",
                               upper->d_name.name, p->len, p->name,
@@ -1113,7 +1113,7 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, struct path *path,
                        err = -EINVAL;
                        break;
                }
-               dentry = lookup_one_len(p->name, path->dentry, p->len);
+               dentry = ovl_lookup_upper(ofs, p->name, path->dentry, p->len);
                if (IS_ERR(dentry))
                        continue;
                if (dentry->d_inode)
@@ -1181,7 +1181,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
                        if (p->len == 2 && p->name[1] == '.')
                                continue;
                }
-               index = lookup_one_len(p->name, indexdir, p->len);
+               index = ovl_lookup_upper(ofs, p->name, indexdir, p->len);
                if (IS_ERR(index)) {
                        err = PTR_ERR(index);
                        index = NULL;
index 432ef060d2ab807491747a071e6c10fe52619078..2fd2d3e5eaba73b68261458441479031ea5792fe 100644 (file)
@@ -761,7 +761,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
 
        inode_lock_nested(dir, I_MUTEX_PARENT);
 retry:
-       work = lookup_one_len(name, ofs->workbasedir, strlen(name));
+       work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name));
 
        if (!IS_ERR(work)) {
                struct iattr attr = {
@@ -1289,7 +1289,7 @@ static int ovl_check_rename_whiteout(struct ovl_fs *ofs)
                goto cleanup_temp;
        }
 
-       whiteout = lookup_one_len(name.name.name, workdir, name.name.len);
+       whiteout = ovl_lookup_upper(ofs, name.name.name, workdir, name.name.len);
        err = PTR_ERR(whiteout);
        if (IS_ERR(whiteout))
                goto cleanup_temp;
@@ -1321,7 +1321,7 @@ static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs,
        struct dentry *child;
 
        inode_lock_nested(parent->d_inode, I_MUTEX_PARENT);
-       child = lookup_one_len(name, parent, len);
+       child = ovl_lookup_upper(ofs, name, parent, len);
        if (!IS_ERR(child) && !child->d_inode)
                child = ovl_create_real(ofs, parent->d_inode, child,
                                        OVL_CATTR(mode));
index 42293610f64ecb9fb71b3c67edd5989333c71416..79e5a22a3c7ca847187d15e53a6a5ff03d9abf3a 100644 (file)
@@ -838,7 +838,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
        }
 
        inode_lock_nested(dir, I_MUTEX_PARENT);
-       index = lookup_one_len(name.name, indexdir, name.len);
+       index = ovl_lookup_upper(ofs, name.name, indexdir, name.len);
        err = PTR_ERR(index);
        if (IS_ERR(index)) {
                index = NULL;