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:
Casey Schaufler
2023-10-26 12:52:55 -07:00
committed by Paolo Pisati
parent 78832d6137
commit 5f3aa067a4
3 changed files with 22 additions and 24 deletions
+15 -14
View File
@@ -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);
}
+2 -5
View File
@@ -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())
+5 -5
View File
@@ -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);
}