|
@@ -227,10 +227,10 @@ int generic_permission(struct inode *inode, int mask,
|
|
|
|
|
|
int permission(struct inode *inode, int mask, struct nameidata *nd)
|
|
int permission(struct inode *inode, int mask, struct nameidata *nd)
|
|
{
|
|
{
|
|
|
|
+ umode_t mode = inode->i_mode;
|
|
int retval, submask;
|
|
int retval, submask;
|
|
|
|
|
|
if (mask & MAY_WRITE) {
|
|
if (mask & MAY_WRITE) {
|
|
- umode_t mode = inode->i_mode;
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Nobody gets write access to a read-only fs.
|
|
* Nobody gets write access to a read-only fs.
|
|
@@ -247,6 +247,13 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * MAY_EXEC on regular files requires special handling: We override
|
|
|
|
+ * filesystem execute permissions if the mode bits aren't set.
|
|
|
|
+ */
|
|
|
|
+ if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO))
|
|
|
|
+ return -EACCES;
|
|
|
|
+
|
|
/* Ordinary permission routines do not understand MAY_APPEND. */
|
|
/* Ordinary permission routines do not understand MAY_APPEND. */
|
|
submask = mask & ~MAY_APPEND;
|
|
submask = mask & ~MAY_APPEND;
|
|
if (inode->i_op && inode->i_op->permission)
|
|
if (inode->i_op && inode->i_op->permission)
|