summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-19 09:50:08 +0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 09:43:05 +0400
commit4cf27141cbe0239f48ec6f0b37bad347d51d1785 (patch)
treeef2b247dc3cbbd795331b8937d3c29e5fc3c7b85
parent43e15cdbefea4ce6d68113de98d4f61c0cf45687 (diff)
downloadlinux-4cf27141cbe0239f48ec6f0b37bad347d51d1785.tar.xz
make exec_permission(dir) really equivalent to inode_permission(dir, MAY_EXEC)
capability overrides apply only to the default case; if fs has ->permission() that does _not_ call generic_permission(), we have no business doing them. Moreover, if it has ->permission() that does call generic_permission(), we have no need to recheck capabilities. Besides, the capability overrides should apply only if we got EACCES from acl_permission_check(); any other value (-EIO, etc.) should be returned to caller, capabilities or not capabilities. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 5ba42c453e31..7c8a93042e63 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -584,19 +584,19 @@ static inline int exec_permission(struct inode *inode, unsigned int flags)
if (inode->i_op->permission) {
ret = inode->i_op->permission(inode, MAY_EXEC, flags);
+ if (likely(!ret))
+ goto ok;
} else {
ret = acl_permission_check(inode, MAY_EXEC, flags,
inode->i_op->check_acl);
+ if (likely(!ret))
+ goto ok;
+ if (ret != -EACCES)
+ return ret;
+ if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
+ ns_capable(ns, CAP_DAC_READ_SEARCH))
+ goto ok;
}
- if (likely(!ret))
- goto ok;
- if (ret == -ECHILD)
- return ret;
-
- if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
- ns_capable(ns, CAP_DAC_READ_SEARCH))
- goto ok;
-
return ret;
ok:
return security_inode_exec_permission(inode, flags);