hulk inclusion category: feature feature: digest-lists
---------------------------
Loading a digest list affects the behavior of IMA for subsequent operations. For example, if the digest of a file is found in a loaded digest list, the file won't be added to the measurement list (with PCR 11). If an administrator loaded the digest list before the IMA policy, he could hide from verifiers the fact that files in that digest list were accessed.
To avoid this situation, this patch prevents usage of digest lists for an IMA submodule if that submodule didn't process it. If a digest list wasn't measured, the digest of measured files will not be searched in the digest list and regular measurement will be performed. The same mechanism applies for appraisal.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com --- security/integrity/ima/ima.h | 1 + security/integrity/ima/ima_digest_list.c | 45 ++++++++++++++++++++++++ security/integrity/ima/ima_digest_list.h | 4 +++ security/integrity/ima/ima_main.c | 4 +++ 4 files changed, 54 insertions(+)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index eb4ebd2cfa56..1cf20bbb106c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -57,6 +57,7 @@ extern int ima_hash_algo; extern int ima_appraise; extern struct tpm_chip *ima_tpm_chip; extern const char boot_aggregate_name[]; +extern int ima_digest_list_actions;
/* IMA event related data */ struct ima_event_data { diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c index 0dcc69954887..58cdbd82840d 100644 --- a/security/integrity/ima/ima_digest_list.c +++ b/security/integrity/ima/ima_digest_list.c @@ -113,6 +113,9 @@ int ima_parse_compact_list(loff_t size, void *buf, int op) size_t digest_len; int ret = 0, i;
+ if (!(ima_digest_list_actions & ima_policy_flag)) + return -EACCES; + while (bufp < bufendp) { if (bufp + sizeof(*hdr) > bufendp) { pr_err("compact list, invalid data\n"); @@ -174,3 +177,45 @@ int ima_parse_compact_list(loff_t size, void *buf, int op)
return bufp - buf; } + +/*************************** + * Digest list usage check * + ***************************/ +void ima_check_measured_appraised(struct file *file) +{ + struct integrity_iint_cache *iint; + + if (!ima_digest_list_actions) + return; + + iint = integrity_iint_find(file_inode(file)); + if (!iint) { + pr_err("disabling digest lists lookup\n"); + ima_digest_list_actions = 0; + return; + } + + mutex_lock(&iint->mutex); + if ((ima_digest_list_actions & IMA_MEASURE) && + !(iint->flags & IMA_MEASURED)) { + pr_err("disabling digest lists lookup for measurement\n"); + ima_digest_list_actions &= ~IMA_MEASURE; + } + + if ((ima_digest_list_actions & IMA_APPRAISE) && + (!(iint->flags & IMA_APPRAISED) || + !test_bit(IMA_DIGSIG, &iint->atomic_flags))) { + pr_err("disabling digest lists lookup for appraisal\n"); + ima_digest_list_actions &= ~IMA_APPRAISE; + } + + mutex_unlock(&iint->mutex); +} + +struct ima_digest *ima_digest_allow(struct ima_digest *digest, int action) +{ + if (!(ima_digest_list_actions & action)) + return NULL; + + return digest; +} diff --git a/security/integrity/ima/ima_digest_list.h b/security/integrity/ima/ima_digest_list.h index e9c6473c1829..f587e9ab8f75 100644 --- a/security/integrity/ima/ima_digest_list.h +++ b/security/integrity/ima/ima_digest_list.h @@ -23,10 +23,14 @@ extern struct ima_h_table ima_digests_htable;
int ima_parse_compact_list(loff_t size, void *buf, int op); +void ima_check_measured_appraised(struct file *file); #else static inline int ima_parse_compact_list(loff_t size, void *buf, int op) { return -ENOTSUPP; } +static inline void ima_check_measured_appraised(struct file *file) +{ +} #endif /*CONFIG_IMA_DIGEST_LIST*/ #endif /*LINUX_IMA_DIGEST_LIST_H*/ diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 703f65dcedde..78a904525711 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -39,6 +39,10 @@ int ima_appraise; #endif
int ima_hash_algo = HASH_ALGO_SHA256; + +/* Actions (measure/appraisal) for which digest lists can be used */ +int ima_digest_list_actions; + static int hash_setup_done;
static int __init hash_setup(char *str)