[PATCH] move executable checking into ->permission()
For execute permission on a regular files we need to check if file has
any execute bits at all, regardless of capabilites.
This check is normally performed by generic_permission() but was also
added to the case when the filesystem defines its own ->permission()
method. In the latter case the filesystem should be responsible for
performing this check.
Move the check from inode_permission() inside filesystems which are
not calling generic_permission().
Create a helper function execute_ok() that returns true if the inode
is a directory or if any execute bits are present in i_mode.
Also fix up the following code:
- coda control file is never executable
- sysctl files are never executable
- hfs_permission seems broken on MAY_EXEC, remove
- hfsplus_permission is eqivalent to generic_permission(), remove
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
diff --git a/fs/namei.c b/fs/namei.c
index 9e2a534..09ce58e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -212,8 +212,7 @@
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
*/
- if (!(mask & MAY_EXEC) ||
- (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
+ if (!(mask & MAY_EXEC) || execute_ok(inode))
if (capable(CAP_DAC_OVERRIDE))
return 0;
@@ -249,23 +248,11 @@
}
/* Ordinary permission routines do not understand MAY_APPEND. */
- if (inode->i_op && inode->i_op->permission) {
+ if (inode->i_op && inode->i_op->permission)
retval = inode->i_op->permission(inode, mask);
- if (!retval) {
- /*
- * Exec permission on a regular file is denied if none
- * of the execute bits are set.
- *
- * This check should be done by the ->permission()
- * method.
- */
- if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) &&
- !(inode->i_mode & S_IXUGO))
- return -EACCES;
- }
- } else {
+ else
retval = generic_permission(inode, mask, NULL);
- }
+
if (retval)
return retval;