Revert "exec: move S_ISREG() check earlier"
This reverts commit633fb6ac39as 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:
@@ -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
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user