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;
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,
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);
}
/**