]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Revert "exec: don't WARN for racy path_noexec check"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Dec 2024 09:33:36 +0000 (10:33 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2024 12:54:15 +0000 (13:54 +0100)
This reverts commit d62ba2a5536df83473a2ac15ab302258e3845251 which is
commit 0d196e7589cefe207d5d41f37a0a28a1fdeeb7c6 upstream.

A later commit needs to be reverted so revert this one as well to allow
that to happen properly.

Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/exec.c

index dad402d55681b2267c71750a6e81e063683c5b13..00c968a739c3cdbfe71b8c3fae2f63c9de841d11 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -145,11 +145,13 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
                goto out;
 
        /*
-        * Check do_open_execat() for an explanation.
+        * may_open() has already checked for this, so it should be
+        * impossible to trip now. But we need to be extra cautious
+        * and check again at the very end too.
         */
        error = -EACCES;
-       if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)) ||
-           path_noexec(&file->f_path))
+       if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
+                        path_noexec(&file->f_path)))
                goto exit;
 
        error = -ENOEXEC;
@@ -953,6 +955,7 @@ EXPORT_SYMBOL(transfer_args_to_stack);
 static struct file *do_open_execat(int fd, struct filename *name, int flags)
 {
        struct file *file;
+       int err;
        struct open_flags open_exec_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
                .acc_mode = MAY_EXEC,
@@ -969,20 +972,24 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
 
        file = do_filp_open(fd, name, &open_exec_flags);
        if (IS_ERR(file))
-               return file;
+               goto out;
 
        /*
-        * In the past the regular type check was here. It moved to may_open() in
-        * 633fb6ac3980 ("exec: move S_ISREG() check earlier"). Since then it is
-        * an invariant that all non-regular files error out before we get here.
+        * may_open() has already checked for this, so it should be
+        * impossible to trip now. But we need to be extra cautious
+        * and check again at the very end too.
         */
-       if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)) ||
-           path_noexec(&file->f_path)) {
-               fput(file);
-               return ERR_PTR(-EACCES);
-       }
+       err = -EACCES;
+       if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
+                        path_noexec(&file->f_path)))
+               goto exit;
 
+out:
        return file;
+
+exit:
+       fput(file);
+       return ERR_PTR(err);
 }
 
 /**