UBUNTU: SAUCE: apparmor4.0.0 [38/90]: LSM stacking v39: LSM: Correct handling of ENOSYS in inode_setxattr
BugLink: http://bugs.launchpad.net/bugs/2028253 The usual "bail on fail" behavior of LSM hooks doesn't work for security_inode_setxattr(). Modules are allowed to return -ENOSYS if the attribute specified isn't one they manage. Fix the code to accommodate this unusal case. This requires changes to the hooks in SELinux and Smack. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> (cherry picked from commit e4091685f2fa95d8746784180086c24617cbe881 https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
committed by
Paolo Pisati
parent
78832d6137
commit
5f3aa067a4
+15
-14
@@ -2351,24 +2351,25 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
{
|
||||
int ret;
|
||||
struct security_hook_list *hp;
|
||||
int rc = -ENOSYS;
|
||||
|
||||
if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
|
||||
return 0;
|
||||
/*
|
||||
* SELinux and Smack integrate the cap call,
|
||||
* so assume that all LSMs supplying this call do so.
|
||||
*/
|
||||
ret = call_int_hook(inode_setxattr, 1, idmap, dentry, name, value,
|
||||
size, flags);
|
||||
|
||||
if (ret == 1)
|
||||
ret = cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = ima_inode_setxattr(dentry, name, value, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
hlist_for_each_entry(hp, &security_hook_heads.inode_setxattr, list) {
|
||||
rc = hp->hook.inode_setxattr(idmap, dentry, name, value, size,
|
||||
flags);
|
||||
if (rc != -ENOSYS)
|
||||
break;
|
||||
}
|
||||
if (rc == -ENOSYS)
|
||||
rc = cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = ima_inode_setxattr(dentry, name, value, size);
|
||||
if (rc)
|
||||
return rc;
|
||||
return evm_inode_setxattr(idmap, dentry, name, value, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -3215,13 +3215,10 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,
|
||||
int rc = 0;
|
||||
|
||||
if (strcmp(name, XATTR_NAME_SELINUX)) {
|
||||
rc = cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Not an attribute we recognize, so just check the
|
||||
ordinary setattr permission. */
|
||||
return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
|
||||
rc = dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
|
||||
return rc ? rc : -ENOSYS;
|
||||
}
|
||||
|
||||
if (!selinux_initialized())
|
||||
|
||||
@@ -1341,7 +1341,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
|
||||
strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
|
||||
rc = -EINVAL;
|
||||
} else
|
||||
rc = cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
rc = -ENOSYS;
|
||||
|
||||
if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
|
||||
rc = -EPERM;
|
||||
@@ -1355,11 +1355,11 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
|
||||
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
|
||||
|
||||
if (rc == 0) {
|
||||
rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
|
||||
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
|
||||
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
|
||||
rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)),
|
||||
MAY_WRITE, &ad);
|
||||
rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user