move read-only and immutable checks into permission()
Subsystems (2)
PATCH 1/1 move read-only and immutable checks into permission()
Currently it's up to the filesystem ->permission method to check whether the filesystem is readonly or the file marked immutable. But this is really a VFS decision, and the distintion becomes more important when moving to per-mountpoint read only flags.
For most filesystems that have been using generic_permission this is not change in behaviour. For those that we're missing the check (cifs without CIFS_MOUNT_NO_PERM and coda [1]) this is a bugfix.
Both reiserfs and xfs have this check still in their ->permission routine because they call it from other places aswell. I'll try switching them over to generic_permission and will take care of this one.
[1] coda_ioctl_permission always returns 0, aka always grants access, which looks more than fishy to me.
fs/namei.c +20 -19
@@ -169,21 +169,6 @@ {umode_t mode = inode->i_mode; -if (mask &MAY_WRITE ) { -/* -* Nobody gets write access to a read-only fs. -*/ -if (IS_RDONLY (inode) && - (S_ISREG (mode) ||S_ISDIR (mode) ||S_ISLNK (mode))) -return -EROFS ; - -/* -* Nobody gets write access to an immutable file. -*/ -if (IS_IMMUTABLE (inode)) -return -EACCES ; - } -if (current->fsuid == inode->i_uid) mode >>=6 ;else {
@@ -225,14 +210,30 @@return -EACCES ; } -int permission (struct inode * inode,int mask,struct nameidata *nd) +int permission (struct inode *inode,int mask,struct nameidata *nd) { -int retval; -int submask; +int retval, submask; + +if (mask &MAY_WRITE ) { +umode_t mode = inode->i_mode; + +/* +* Nobody gets write access to a read-only fs. +*/ +if (IS_RDONLY (inode) && + (S_ISREG (mode) ||S_ISDIR (mode) ||S_ISLNK (mode))) +return -EROFS ; + +/* +* Nobody gets write access to an immutable file. +*/ +if (IS_IMMUTABLE (inode)) +return -EACCES ; + } +/* Ordinary permission routines do not understand MAY_APPEND. */ submask = mask & ~MAY_APPEND ; -if (inode->i_op && inode->i_op->permission) retval = inode->i_op->permission (inode, submask, nd);else
fs/nfs/dir.c +0 -18
@@ -1498,29 +1498,11 @@int nfs_permission (struct inode *inode,int mask,struct nameidata *nd) {struct rpc_cred *cred; -int mode = inode->i_mode;int res;if (mask ==0 )return 0 ; -if (mask &MAY_WRITE ) { -/* -* -* Nobody gets write access to a read-only fs. -* -*/ -if (IS_RDONLY (inode) && - (S_ISREG (mode) ||S_ISDIR (mode) ||S_ISLNK (mode))) -return -EROFS ; -/* -* -* Nobody gets write access to an immutable file. -* -*/ -if (IS_IMMUTABLE (inode)) -return -EACCES ; - }/* Are we checking permissions on anything other than lookup/execute? */ if ((mask &MAY_EXEC ) ==0 ) {/* We only need to check permissions on file open() and access() */