-----Original Message----- From: Roberto Sassu [mailto:roberto.sassu@huawei.com] Sent: Monday, July 6, 2020 5:41 PM To: kernel@openeuler.org Cc: Silviu Vlasceanu Silviu.Vlasceanu@huawei.com Subject: [PATCH 29/35] ima: Add support for appraisal with digest lists
hulk inclusion category: feature feature: digest-lists
IMA-Appraise grants access to files with a valid signature or with actual file digest equal to the digest included in security.ima.
This patch adds support for appraisal based on digest lists. Instead of using the reference value from security.ima, this patch checks if the calculated file digest is included in the uploaded digest lists.
This functionality must be explicitly enabled by providing one of the following values for the ima_appraise_digest_list= kernel option:
digest: this mode enables appraisal verification with digest lists until EVM is initialized; after that, EVM verification must be successful even if the file digest is found in a digest list;
digest-nometadata: this mode enables appraisal verification with digest lists even after EVM has been initialized; files without security.evm are allowed if the digest of the content is found in the digest list, and security.evm is created with current values of xattrs (trust at first use); all files created in this way will have the new security.ima type EVM_IMA_XATTR_DIGEST_LIST; they can be accessed later only if this
mode has been selected.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com
.../admin-guide/kernel-parameters.txt | 9 +++ security/integrity/ima/ima.h | 5 +- security/integrity/ima/ima_appraise.c | 70 ++++++++++++++++++- security/integrity/ima/ima_main.c | 4 +- security/integrity/integrity.h | 1 + 5 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index d6423042d787..65efa24e3dd0 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1557,6 +1557,15 @@ "enforce-evm" | "log-evm" } default: "enforce"
- ima_appraise_digest_list= [IMA]
Format: { "digest" | "digest-nometadata" }
digest: enables appraisal of files with digest lists
until EVM is initialized.
digest-nometadata: enables appraisal of files with
digest lists even after EVM is initialized.
- ima_appraise_tcb [IMA] The builtin appraise policy appraises all files owned by uid=0.
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index dbdbd9c84262..9fea7431b0cc 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -247,7 +247,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct integrity_iint_cache *iint, struct file *file, const unsigned char *filename, struct evm_ima_xattr_data *xattr_value,
int xattr_len);
int xattr_len, struct ima_digest *found_digest);
int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, @@ -258,7 +258,8 @@ static inline int ima_appraise_measurement(enum ima_hooks func, struct file *file, const unsigned char *filename, struct evm_ima_xattr_data *xattr_value,
int xattr_len)
int xattr_len,
struct ima_digest *found_digest)
{ return INTEGRITY_UNKNOWN; } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index f51ab67f7ab5..b7f234292054 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -17,6 +17,7 @@ #include <linux/evm.h>
#include "ima.h" +#include "ima_digest_list.h"
static bool ima_appraise_req_evm __ro_after_init; static int __init default_appraise_setup(char *str) @@ -37,6 +38,22 @@ static int __init default_appraise_setup(char *str)
__setup("ima_appraise=", default_appraise_setup);
+static bool ima_appraise_no_metadata __ro_after_init; +#ifdef CONFIG_IMA_DIGEST_LIST +static int __init appraise_digest_list_setup(char *str) +{
- if (!strncmp(str, "digest", 6)) {
ima_digest_list_actions |= IMA_APPRAISE;
if (!strcmp(str + 6, "-nometadata"))
ima_appraise_no_metadata = true;
- }
- return 1;
+} +__setup("ima_appraise_digest_list=", appraise_digest_list_setup); +#endif
/*
- is_ima_appraise_enabled - return appraise status
@@ -70,7 +87,11 @@ static int ima_fix_xattr(struct dentry *dentry, int rc, offset; u8 algo = iint->ima_hash->algo;
- if (algo <= HASH_ALGO_SHA1) {
- if (test_bit(IMA_DIGEST_LIST, &iint->atomic_flags)) {
offset = 0;
iint->ima_hash->xattr.ng.type =
EVM_IMA_XATTR_DIGEST_LIST;
iint->ima_hash->xattr.ng.algo = algo;
- } else if (algo <= HASH_ALGO_SHA1) { offset = 1; iint->ima_hash->xattr.sha1.type = IMA_XATTR_DIGEST; } else {
@@ -165,18 +186,29 @@ int ima_appraise_measurement(enum ima_hooks func, struct integrity_iint_cache *iint, struct file *file, const unsigned char *filename, struct evm_ima_xattr_data *xattr_value,
int xattr_len)
int xattr_len, struct ima_digest *found_digest)
{ static const char op[] = "appraise_data"; const char *cause = "unknown"; struct dentry *dentry = file_dentry(file); struct inode *inode = d_backing_inode(dentry); enum integrity_status status = INTEGRITY_UNKNOWN;
- struct evm_ima_xattr_data digest_list_value;
I will fix this. Maximum size of the digest is SHA1_DIGEST_SIZE. It is not enough for SHA256 digests.
Roberto
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063 Managing Director: Li Peng, Li Jian, Shi Yanli
int rc = xattr_len, hash_start = 0;
if (!(inode->i_opflags & IOP_XATTR)) return INTEGRITY_UNKNOWN;
- if (rc == -ENODATA && found_digest &&
!(file->f_mode && FMODE_CREATED)) {
digest_list_value.type = EVM_IMA_XATTR_DIGEST_LIST;
digest_list_value.digest[0] = found_digest->algo;
memcpy(&digest_list_value.digest[1], found_digest->digest,
hash_digest_size[found_digest->algo]);
xattr_value = &digest_list_value;
rc = hash_digest_size[found_digest->algo] + 2;
- }
- if (rc <= 0) { if (rc && rc != -ENODATA) goto out;
@@ -200,11 +232,18 @@ int ima_appraise_measurement(enum ima_hooks func, break; case INTEGRITY_UNKNOWN: if (ima_appraise_req_evm &&
xattr_value->type != EVM_IMA_XATTR_DIGSIG)
xattr_value->type != EVM_IMA_XATTR_DIGSIG
&& !found_digest) goto out; break; case INTEGRITY_NOXATTRS: /* No EVM protected xattrs. */ case INTEGRITY_NOLABEL: /* No security.evm xattr. */
/*
* If the digest-nometadata mode is selected, allow access
* without metadata check. EVM will eventually create an
HMAC
* based on current xattr values.
*/
if (ima_appraise_no_metadata && found_digest)
cause = "missing-HMAC"; goto out; case INTEGRITY_FAIL_IMMUTABLE:break;
@@ -218,6 +257,31 @@ int ima_appraise_measurement(enum ima_hooks func, }
switch (xattr_value->type) {
- case EVM_IMA_XATTR_DIGEST_LIST:
set_bit(IMA_DIGEST_LIST, &iint->atomic_flags);
if (found_digest) {
if (!ima_digest_is_immutable(found_digest)) {
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);
}
status = INTEGRITY_PASS;
break;
}
if (!ima_appraise_no_metadata) {
cause = "IMA-xattr-untrusted";
status = INTEGRITY_FAIL;
break;
}
case IMA_XATTR_DIGEST_NG: /* first byte contains algorithm id */ hash_start = 1;/* fall through */
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 198b2b4c3654..a386a5bf1ed9 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -366,7 +366,9 @@ static int process_measurement(struct file *file, const struct cred *cred, if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) { inode_lock(inode); rc = ima_appraise_measurement(func, iint, file, pathname,
xattr_value, xattr_len);
xattr_value, xattr_len,
ima_digest_allow(found_digest,
inode_unlock(inode); } if (action & IMA_AUDIT)IMA_APPRAISE));
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 02d40e5f401c..49132ab9ef0a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -68,6 +68,7 @@ #define IMA_CHANGE_ATTR 2 #define IMA_DIGSIG 3 #define IMA_MUST_MEASURE 4 +#define IMA_DIGEST_LIST 5
enum evm_ima_xattr_type { IMA_XATTR_DIGEST = 0x01, -- 2.27.GIT _______________________________________________ Kernel mailing list -- kernel@openeuler.org To unsubscribe send an email to kernel-leave@openeuler.org