]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
vfs: shave a branch in getname_flags
authorMateusz Guzik <mjguzik@gmail.com>
Tue, 4 Jun 2024 15:52:57 +0000 (17:52 +0200)
committerChristian Brauner <brauner@kernel.org>
Fri, 21 Jun 2024 09:40:49 +0000 (11:40 +0200)
Check for an error while copying and no path in one branch.

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://lore.kernel.org/r/20240604155257.109500-4-mjguzik@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/namei.c

index 950ad6bdd9feb4e02d8adf7281651ba0997f08fe..3d3674c21d3c492a7ff801c097ea551eb773f5d7 100644 (file)
@@ -148,9 +148,20 @@ getname_flags(const char __user *filename, int flags)
        result->name = kname;
 
        len = strncpy_from_user(kname, filename, EMBEDDED_NAME_MAX);
-       if (unlikely(len < 0)) {
-               __putname(result);
-               return ERR_PTR(len);
+       /*
+        * Handle both empty path and copy failure in one go.
+        */
+       if (unlikely(len <= 0)) {
+               if (unlikely(len < 0)) {
+                       __putname(result);
+                       return ERR_PTR(len);
+               }
+
+               /* The empty path is special. */
+               if (!(flags & LOOKUP_EMPTY)) {
+                       __putname(result);
+                       return ERR_PTR(-ENOENT);
+               }
        }
 
        /*
@@ -180,6 +191,12 @@ getname_flags(const char __user *filename, int flags)
                        kfree(result);
                        return ERR_PTR(len);
                }
+               /* The empty path is special. */
+               if (unlikely(!len) && !(flags & LOOKUP_EMPTY)) {
+                       __putname(kname);
+                       kfree(result);
+                       return ERR_PTR(-ENOENT);
+               }
                if (unlikely(len == PATH_MAX)) {
                        __putname(kname);
                        kfree(result);
@@ -188,14 +205,6 @@ getname_flags(const char __user *filename, int flags)
        }
 
        atomic_set(&result->refcnt, 1);
-       /* The empty path is special. */
-       if (unlikely(!len)) {
-               if (!(flags & LOOKUP_EMPTY)) {
-                       putname(result);
-                       return ERR_PTR(-ENOENT);
-               }
-       }
-
        result->uptr = filename;
        result->aname = NULL;
        audit_getname(result);