diff options
author | Andy Whitcroft <apw@canonical.com> | 2011-05-20 11:48:16 +0100 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2011-10-17 09:52:34 -0600 |
commit | 2e0ca64f09ed54098bf451d68049308a3b562b63 (patch) | |
tree | 6490aebdb00c04e5261f0ddcfdba505e99c16d73 /security | |
parent | b0328f8b82758ca3e45f761c06aab2c6e8f3fbc4 (diff) |
UBUNTU: ubuntu: Yama: if an underlying filesystem provides a permissions op use it
When we are checking permissions on hardlinks we use generic_permissions()
to work out if the user actually has read/write permissions and only
then allow the link. However where the underlying filesystem supplies
a permissions() op there is no guarentee that the inode ownership is
actually valid and we must use that op instead.
Add a new function mirroring the core fragment from inode_permission
using the filesystem specific permissions() op falling back to
generic_permissions() when it is not present.
With this in place links in overlayfs behave as expected.
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/yama/yama_lsm.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 4127150c402..23d4111d077 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -326,6 +326,18 @@ int yama_inode_follow_link(struct dentry *dentry, return rc; } +static int yama_generic_permission(struct inode *inode, int mask) +{ + int retval; + + if (inode->i_op->permission) + retval = inode->i_op->permission(inode, mask, 0); + else + retval = generic_permission(inode, mask, 0, + inode->i_op->check_acl); + return retval; +} + /** * yama_path_link - verify that hardlinking is allowed * @old_dentry: the source inode/dentry to hardlink from @@ -357,7 +369,7 @@ int yama_path_link(struct dentry *old_dentry, struct path *new_dir, if (cred->fsuid != inode->i_uid && (!S_ISREG(mode) || (mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || - (generic_permission(inode, MAY_READ | MAY_WRITE, 0, NULL))) && + (yama_generic_permission(inode, MAY_READ | MAY_WRITE))) && !capable(CAP_FOWNER)) { char name[sizeof(current->comm)]; printk_ratelimited(KERN_INFO "non-accessible hardlink" |