diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 09:25:20 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 09:25:20 -0800 |
commit | 19e7b5f99474107e8d0b4b3e4652fa19ddb87efc (patch) | |
tree | 49f15b76c07b4c90d6fbd17b49d69017c81a4b58 /fs/namei.c | |
parent | 26064ea409b4d4acb05903a36f3fe2fdccb3d8aa (diff) | |
parent | ce4c253573ad184603e0fa77876ba155b0cde46d (diff) | |
download | linux-stable-19e7b5f99474107e8d0b4b3e4652fa19ddb87efc.tar.gz linux-stable-19e7b5f99474107e8d0b4b3e4652fa19ddb87efc.tar.bz2 linux-stable-19e7b5f99474107e8d0b4b3e4652fa19ddb87efc.zip |
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro:
"All kinds of misc stuff, without any unifying topic, from various
people.
Neil's d_anon patch, several bugfixes, introduction of kvmalloc
analogue of kmemdup_user(), extending bitfield.h to deal with
fixed-endians, assorted cleanups all over the place..."
* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (28 commits)
alpha: osf_sys.c: use timespec64 where appropriate
alpha: osf_sys.c: fix put_tv32 regression
jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path
dcache: delete unused d_hash_mask
dcache: subtract d_hash_shift from 32 in advance
fs/buffer.c: fold init_buffer() into init_page_buffers()
fs: fold __inode_permission() into inode_permission()
fs: add RWF_APPEND
sctp: use vmemdup_user() rather than badly open-coding memdup_user()
snd_ctl_elem_init_enum_names(): switch to vmemdup_user()
replace_user_tlv(): switch to vmemdup_user()
new primitive: vmemdup_user()
memdup_user(): switch to GFP_USER
eventfd: fold eventfd_ctx_get() into eventfd_ctx_fileget()
eventfd: fold eventfd_ctx_read() into eventfd_read()
eventfd: convert to use anon_inode_getfd()
nfs4file: get rid of pointless include of btrfs.h
uvc_v4l2: clean copyin/copyout up
vme_user: don't use __copy_..._user()
usx2y: don't bother with memdup_user() for 16-byte structure
...
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 71 |
1 files changed, 26 insertions, 45 deletions
diff --git a/fs/namei.c b/fs/namei.c index 7c221fb0836b..921ae32dbc80 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -391,50 +391,6 @@ static inline int do_inode_permission(struct inode *inode, int mask) } /** - * __inode_permission - Check for access rights to a given inode - * @inode: Inode to check permission on - * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) - * - * Check for read/write/execute permissions on an inode. - * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. - * - * This does not check for a read-only file system. You probably want - * inode_permission(). - */ -int __inode_permission(struct inode *inode, int mask) -{ - int retval; - - if (unlikely(mask & MAY_WRITE)) { - /* - * Nobody gets write access to an immutable file. - */ - if (IS_IMMUTABLE(inode)) - return -EPERM; - - /* - * Updating mtime will likely cause i_uid and i_gid to be - * written back improperly if their true value is unknown - * to the vfs. - */ - if (HAS_UNMAPPED_ID(inode)) - return -EACCES; - } - - retval = do_inode_permission(inode, mask); - if (retval) - return retval; - - retval = devcgroup_inode_permission(inode, mask); - if (retval) - return retval; - - return security_inode_permission(inode, mask); -} -EXPORT_SYMBOL(__inode_permission); - -/** * sb_permission - Check superblock-level permissions * @sb: Superblock of inode to check permission on * @inode: Inode to check permission on @@ -472,7 +428,32 @@ int inode_permission(struct inode *inode, int mask) retval = sb_permission(inode->i_sb, inode, mask); if (retval) return retval; - return __inode_permission(inode, mask); + + if (unlikely(mask & MAY_WRITE)) { + /* + * Nobody gets write access to an immutable file. + */ + if (IS_IMMUTABLE(inode)) + return -EPERM; + + /* + * Updating mtime will likely cause i_uid and i_gid to be + * written back improperly if their true value is unknown + * to the vfs. + */ + if (HAS_UNMAPPED_ID(inode)) + return -EACCES; + } + + retval = do_inode_permission(inode, mask); + if (retval) + return retval; + + retval = devcgroup_inode_permission(inode, mask); + if (retval) + return retval; + + return security_inode_permission(inode, mask); } EXPORT_SYMBOL(inode_permission); |