Revert "exec: move S_ISREG() check earlier"

This reverts commit 633fb6ac39 as it
breaks execev() semantics.

Fixes: 633fb6ac39 ("exec: move S_ISREG() check earlier")
Cc: Kees Cook <keescook@google.com>
Reported-by: Marc Zyngier <mzyngier@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I50eb97745b1ee4f8bd5d3f1d1e6c98e30aa7c5ea
This commit is contained in:
Greg Kroah-Hartman
2020-08-13 16:26:22 +02:00
parent 7799e73232
commit 29298d156e
3 changed files with 10 additions and 18 deletions
+2 -14
View File
@@ -141,14 +141,8 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
if (IS_ERR(file))
goto out;
/*
* 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 ((!S_ISREG(file_inode(file)->i_mode) || path_noexec(&file->f_path)))
goto exit;
fsnotify_open(file);
@@ -911,14 +905,8 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
if (IS_ERR(file))
goto out;
/*
* 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.
*/
err = -EACCES;
if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode) ||
path_noexec(&file->f_path)))
if ((!S_ISREG(file_inode(file)->i_mode) || path_noexec(&file->f_path)))
goto exit;
err = deny_write_access(file);
+2 -4
View File
@@ -2933,18 +2933,16 @@ static int may_open(const struct path *path, int acc_mode, int flag)
case S_IFLNK:
return -ELOOP;
case S_IFDIR:
if (acc_mode & (MAY_WRITE | MAY_EXEC))
if (acc_mode & MAY_WRITE)
return -EISDIR;
break;
case S_IFBLK:
case S_IFCHR:
if (!may_open_dev(path))
return -EACCES;
fallthrough;
/*FALLTHRU*/
case S_IFIFO:
case S_IFSOCK:
if (acc_mode & MAY_EXEC)
return -EACCES;
flag &= ~O_TRUNC;
break;
case S_IFREG:
+6
View File
@@ -779,6 +779,12 @@ static int do_dentry_open(struct file *f,
return 0;
}
/* Any file opened for execve()/uselib() has to be a regular file. */
if (unlikely(f->f_flags & FMODE_EXEC && !S_ISREG(inode->i_mode))) {
error = -EACCES;
goto cleanup_file;
}
if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
error = get_write_access(inode);
if (unlikely(error))