diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/namei.c b/fs/namei.c index fde8fe086c09..e99e2a9da0f7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2851,16 +2851,24 @@ static int may_open(const struct path *path, int acc_mode, int flag) case S_IFDIR: if (acc_mode & MAY_WRITE) return -EISDIR; + if (acc_mode & MAY_EXEC) + return -EACCES; break; case S_IFBLK: case S_IFCHR: if (!may_open_dev(path)) return -EACCES; - /*FALLTHRU*/ + fallthrough; case S_IFIFO: case S_IFSOCK: + if (acc_mode & MAY_EXEC) + return -EACCES; flag &= ~O_TRUNC; break; + case S_IFREG: + if ((acc_mode & MAY_EXEC) && path_noexec(path)) + return -EACCES; + break; } error = inode_permission(inode, MAY_OPEN | acc_mode); @@ -3770,11 +3778,11 @@ exit2: mnt_drop_write(path.mnt); exit1: path_put(&path); - putname(name); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } + putname(name); return error; } |