diff options
author | Andy Whitcroft <apw@canonical.com> | 2011-05-20 11:48:16 +0100 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2012-03-17 17:04:01 -0600 |
commit | b2f40b3bbbc7ea59a063fc5b74d7bdcd484b7a38 (patch) | |
tree | af865b2f4490a86c718e3941811626164f6fc0a3 /security | |
parent | 673327f1145536b15a8e588b89de766a478e6b0c (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" |