summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima_appraise.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 9bb351b933fb..d9a627de3930 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -242,12 +242,16 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
hash_start = 1;
fallthrough;
case IMA_XATTR_DIGEST:
- if (iint->flags & IMA_DIGSIG_REQUIRED) {
- *cause = "IMA-signature-required";
- *status = INTEGRITY_FAIL;
- break;
+ if (*status != INTEGRITY_PASS_IMMUTABLE) {
+ if (iint->flags & IMA_DIGSIG_REQUIRED) {
+ *cause = "IMA-signature-required";
+ *status = INTEGRITY_FAIL;
+ break;
+ }
+ clear_bit(IMA_DIGSIG, &iint->atomic_flags);
+ } else {
+ set_bit(IMA_DIGSIG, &iint->atomic_flags);
}
- clear_bit(IMA_DIGSIG, &iint->atomic_flags);
if (xattr_len - sizeof(xattr_value->type) - hash_start >=
iint->ima_hash->length)
/*
@@ -417,6 +421,7 @@ int ima_appraise_measurement(enum ima_hooks func,
cause = "missing-HMAC";
goto out;
case INTEGRITY_FAIL_IMMUTABLE:
+ set_bit(IMA_DIGSIG, &iint->atomic_flags);
fallthrough;
case INTEGRITY_FAIL: /* Invalid HMAC/signature. */
cause = "invalid-HMAC";
@@ -461,9 +466,12 @@ out:
status = INTEGRITY_PASS;
}
- /* Permit new files with file signatures, but without data. */
+ /*
+ * Permit new files with file/EVM portable signatures, but
+ * without data.
+ */
if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
- xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
+ test_bit(IMA_DIGSIG, &iint->atomic_flags)) {
status = INTEGRITY_PASS;
}
@@ -581,6 +589,8 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
return -EINVAL;
digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
+ } else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
+ digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
}
if (result == 1 || evm_revalidate_status(xattr_name)) {
ima_reset_appraise_flags(d_backing_inode(dentry), digsig);