diff options
Diffstat (limited to 'security/integrity/evm')
-rw-r--r-- | security/integrity/evm/evm.h | 3 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 9 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 85 |
3 files changed, 49 insertions, 48 deletions
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 0d44f41d16f8..f8b8c5004fc7 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h @@ -38,9 +38,6 @@ extern int evm_initialized; extern int evm_hmac_attrs; -extern struct crypto_shash *hmac_tfm; -extern struct crypto_shash *hash_tfm; - /* List of EVM protected security xattrs */ extern struct list_head evm_config_xattrnames; diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 0450d79afdc8..708de9656bbd 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -26,7 +26,7 @@ static unsigned char evmkey[MAX_KEY_SIZE]; static const int evmkey_len = MAX_KEY_SIZE; -struct crypto_shash *hmac_tfm; +static struct crypto_shash *hmac_tfm; static struct crypto_shash *evm_tfm[HASH_ALGO__LAST]; static DEFINE_MUTEX(mutex); @@ -75,7 +75,7 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo) { long rc; const char *algo; - struct crypto_shash **tfm, *tmp_tfm = NULL; + struct crypto_shash **tfm, *tmp_tfm; struct shash_desc *desc; if (type == EVM_XATTR_HMAC) { @@ -120,16 +120,13 @@ unlock: alloc: desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), GFP_KERNEL); - if (!desc) { - crypto_free_shash(tmp_tfm); + if (!desc) return ERR_PTR(-ENOMEM); - } desc->tfm = *tfm; rc = crypto_shash_init(desc); if (rc) { - crypto_free_shash(tmp_tfm); kfree(desc); return ERR_PTR(rc); } diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 08f907382c61..23d484e05e6f 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -36,42 +36,36 @@ static const char * const integrity_status_msg[] = { int evm_hmac_attrs; static struct xattr_list evm_config_default_xattrnames[] = { - {.name = XATTR_NAME_SELINUX, -#ifdef CONFIG_SECURITY_SELINUX - .enabled = true -#endif + { + .name = XATTR_NAME_SELINUX, + .enabled = IS_ENABLED(CONFIG_SECURITY_SELINUX) }, - {.name = XATTR_NAME_SMACK, -#ifdef CONFIG_SECURITY_SMACK - .enabled = true -#endif + { + .name = XATTR_NAME_SMACK, + .enabled = IS_ENABLED(CONFIG_SECURITY_SMACK) }, - {.name = XATTR_NAME_SMACKEXEC, -#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS - .enabled = true -#endif + { + .name = XATTR_NAME_SMACKEXEC, + .enabled = IS_ENABLED(CONFIG_EVM_EXTRA_SMACK_XATTRS) }, - {.name = XATTR_NAME_SMACKTRANSMUTE, -#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS - .enabled = true -#endif + { + .name = XATTR_NAME_SMACKTRANSMUTE, + .enabled = IS_ENABLED(CONFIG_EVM_EXTRA_SMACK_XATTRS) }, - {.name = XATTR_NAME_SMACKMMAP, -#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS - .enabled = true -#endif + { + .name = XATTR_NAME_SMACKMMAP, + .enabled = IS_ENABLED(CONFIG_EVM_EXTRA_SMACK_XATTRS) }, - {.name = XATTR_NAME_APPARMOR, -#ifdef CONFIG_SECURITY_APPARMOR - .enabled = true -#endif + { + .name = XATTR_NAME_APPARMOR, + .enabled = IS_ENABLED(CONFIG_SECURITY_APPARMOR) }, - {.name = XATTR_NAME_IMA, -#ifdef CONFIG_IMA_APPRAISE - .enabled = true -#endif + { + .name = XATTR_NAME_IMA, + .enabled = IS_ENABLED(CONFIG_IMA_APPRAISE) }, - {.name = XATTR_NAME_CAPS, + { + .name = XATTR_NAME_CAPS, .enabled = true }, }; @@ -86,7 +80,7 @@ static int __init evm_set_fixmode(char *str) else pr_err("invalid \"%s\" mode", str); - return 0; + return 1; } __setup("evm=", evm_set_fixmode); @@ -436,7 +430,7 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry) struct inode *inode = d_backing_inode(dentry); if (!evm_key_loaded() || !S_ISREG(inode->i_mode) || evm_fixmode) - return 0; + return INTEGRITY_PASS; return evm_verify_hmac(dentry, NULL, NULL, 0, NULL); } @@ -463,10 +457,21 @@ static int evm_xattr_acl_change(struct user_namespace *mnt_userns, int rc; /* - * user_ns is not relevant here, ACL_USER/ACL_GROUP don't have impact - * on the inode mode (see posix_acl_equiv_mode()). + * An earlier comment here mentioned that the idmappings for + * ACL_{GROUP,USER} don't matter since EVM is only interested in the + * mode stored as part of POSIX ACLs. Nonetheless, if it must translate + * from the uapi POSIX ACL representation to the VFS internal POSIX ACL + * representation it should do so correctly. There's no guarantee that + * we won't change POSIX ACLs in a way that ACL_{GROUP,USER} matters + * for the mode at some point and it's difficult to keep track of all + * the LSM and integrity modules and what they do to POSIX ACLs. + * + * Frankly, EVM shouldn't try to interpret the uapi struct for POSIX + * ACLs it received. It requires knowledge that only the VFS is + * guaranteed to have. */ - acl = posix_acl_from_xattr(&init_user_ns, xattr_value, xattr_value_len); + acl = vfs_set_acl_prepare(mnt_userns, i_user_ns(inode), + xattr_value, xattr_value_len); if (IS_ERR_OR_NULL(acl)) return 1; @@ -755,13 +760,14 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) evm_update_evmxattr(dentry, xattr_name, NULL, 0); } -static int evm_attr_change(struct dentry *dentry, struct iattr *attr) +static int evm_attr_change(struct user_namespace *mnt_userns, + struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_backing_inode(dentry); unsigned int ia_valid = attr->ia_valid; - if ((!(ia_valid & ATTR_UID) || uid_eq(attr->ia_uid, inode->i_uid)) && - (!(ia_valid & ATTR_GID) || gid_eq(attr->ia_gid, inode->i_gid)) && + if (!i_uid_needs_update(mnt_userns, attr, inode) && + !i_gid_needs_update(mnt_userns, attr, inode) && (!(ia_valid & ATTR_MODE) || attr->ia_mode == inode->i_mode)) return 0; @@ -775,7 +781,8 @@ static int evm_attr_change(struct dentry *dentry, struct iattr *attr) * Permit update of file attributes when files have a valid EVM signature, * except in the case of them having an immutable portable signature. */ -int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) +int evm_inode_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; enum integrity_status evm_status; @@ -801,7 +808,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) return 0; if (evm_status == INTEGRITY_PASS_IMMUTABLE && - !evm_attr_change(dentry, attr)) + !evm_attr_change(mnt_userns, dentry, attr)) return 0; integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), |