diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-15 21:03:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:14 -0400 |
commit | e6305c43eda10ebfd2ad9e35d6e172ccc7bb3695 (patch) | |
tree | 8a95bd0e27fb3ce895cca9ef91af2e1605e4cdab /fs/namei.c | |
parent | 1bd5191d9f5d1928c4efdf604c4164b04bb88dbe (diff) |
[PATCH] sanitize ->permission() prototype
* kill nameidata * argument; map the 3 bits in ->flags anybody cares
about to new MAY_... ones and pass with the mask.
* kill redundant gfs2_iop_permission()
* sanitize ecryptfs_permission()
* fix remaining places where ->permission() instances might barf on new
MAY_... found in mask.
The obvious next target in that direction is permission(9)
folded fix for nfs_permission() breakage from Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c index 3b26a240ade9..46af98ed136b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -185,6 +185,8 @@ int generic_permission(struct inode *inode, int mask, { umode_t mode = inode->i_mode; + mask &= MAY_READ | MAY_WRITE | MAY_EXEC; + if (current->fsuid == inode->i_uid) mode >>= 6; else { @@ -203,7 +205,7 @@ int generic_permission(struct inode *inode, int mask, /* * If the DACs are ok we don't need any capability check. */ - if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) + if ((mask & ~mode) == 0) return 0; check_capabilities: @@ -228,7 +230,7 @@ int generic_permission(struct inode *inode, int mask, int permission(struct inode *inode, int mask, struct nameidata *nd) { - int retval, submask; + int retval; struct vfsmount *mnt = NULL; if (nd) @@ -261,9 +263,17 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) } /* 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); + int extra = 0; + if (nd) { + if (nd->flags & LOOKUP_ACCESS) + extra |= MAY_ACCESS; + if (nd->flags & LOOKUP_CHDIR) + extra |= MAY_CHDIR; + if (nd->flags & LOOKUP_OPEN) + extra |= MAY_OPEN; + } + retval = inode->i_op->permission(inode, mask | extra); if (!retval) { /* * Exec permission on a regular file is denied if none @@ -277,7 +287,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) return -EACCES; } } else { - retval = generic_permission(inode, submask, NULL); + retval = generic_permission(inode, mask, NULL); } if (retval) return retval; @@ -286,7 +296,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) if (retval) return retval; - return security_inode_permission(inode, mask, nd); + return security_inode_permission(inode, + mask & (MAY_READ|MAY_WRITE|MAY_EXEC), nd); } /** |