diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-06-19 01:50:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 01:43:05 -0400 |
commit | 4cf27141cbe0239f48ec6f0b37bad347d51d1785 (patch) | |
tree | ef2b247dc3cbbd795331b8937d3c29e5fc3c7b85 /fs/namei.c | |
parent | 43e15cdbefea4ce6d68113de98d4f61c0cf45687 (diff) | |
download | op-kernel-dev-4cf27141cbe0239f48ec6f0b37bad347d51d1785.zip op-kernel-dev-4cf27141cbe0239f48ec6f0b37bad347d51d1785.tar.gz |
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>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 18 |
1 files changed, 9 insertions, 9 deletions
@@ -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); |