|
@@ -227,10 +227,10 @@ int generic_permission(struct inode *inode, int mask,
|
|
|
|
|
|
int permission(struct inode *inode, int mask, struct nameidata *nd)
|
|
|
{
|
|
|
- umode_t mode = inode->i_mode;
|
|
|
int retval, submask;
|
|
|
|
|
|
if (mask & MAY_WRITE) {
|
|
|
+ umode_t mode = inode->i_mode;
|
|
|
|
|
|
/*
|
|
|
* Nobody gets write access to a read-only fs.
|
|
@@ -246,22 +246,34 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
|
|
|
return -EACCES;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- /*
|
|
|
- * MAY_EXEC on regular files requires special handling: We override
|
|
|
- * filesystem execute permissions if the mode bits aren't set or
|
|
|
- * the fs is mounted with the "noexec" flag.
|
|
|
- */
|
|
|
- if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
|
|
|
- (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))))
|
|
|
- return -EACCES;
|
|
|
+ if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
|
|
|
+ /*
|
|
|
+ * MAY_EXEC on regular files is denied if the fs is mounted
|
|
|
+ * with the "noexec" flag.
|
|
|
+ */
|
|
|
+ if (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))
|
|
|
+ return -EACCES;
|
|
|
+ }
|
|
|
|
|
|
/* Ordinary permission routines do not understand MAY_APPEND. */
|
|
|
submask = mask & ~MAY_APPEND;
|
|
|
- if (inode->i_op && inode->i_op->permission)
|
|
|
+ if (inode->i_op && inode->i_op->permission) {
|
|
|
retval = inode->i_op->permission(inode, submask, nd);
|
|
|
- else
|
|
|
+ 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 {
|
|
|
retval = generic_permission(inode, submask, NULL);
|
|
|
+ }
|
|
|
if (retval)
|
|
|
return retval;
|
|
|
|