diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c index dd6dbdbbc7dd9d7d1289d9de2dd6f2e550fee820..15ad7d584d347ed188fd39c6a253bd418b7cc0ca 100644 --- a/security/integrity/ima/ima_digest_list.c +++ b/security/integrity/ima/ima_digest_list.c @@ -241,42 +241,39 @@ int ima_parse_compact_list(loff_t size, void *buf, int op) /*************************** * Digest list usage check * ***************************/ -void ima_check_measured_appraised(struct file *file) +bool ima_check_measured_appraised(struct file *file) { struct integrity_iint_cache *iint; if (!ima_digest_list_actions) - return; + return true; if (file_inode(file)->i_sb->s_magic == SECURITYFS_MAGIC || S_ISDIR(file_inode(file)->i_mode)) - return; + return true; iint = integrity_iint_find(file_inode(file)); if (!iint) { - pr_err("%s not processed, disabling digest lists lookup\n", - file_dentry(file)->d_name.name); - ima_digest_list_actions = 0; - return; + pr_err("%s not processed\n", file_dentry(file)->d_name.name); + return false; } mutex_lock(&iint->mutex); if ((ima_digest_list_actions & IMA_MEASURE) && !(iint->flags & IMA_MEASURED)) { - pr_err("%s not measured, disabling digest lists lookup " - "for measurement\n", file_dentry(file)->d_name.name); - ima_digest_list_actions &= ~IMA_MEASURE; + pr_err("%s not measured\n", file_dentry(file)->d_name.name); + return false; } if ((ima_digest_list_actions & IMA_APPRAISE) && (!(iint->flags & IMA_APPRAISED) || !test_bit(IMA_DIGSIG, &iint->atomic_flags))) { - pr_err("%s not appraised, disabling digest lists lookup " - "for appraisal\n", file_dentry(file)->d_name.name); - ima_digest_list_actions &= ~IMA_APPRAISE; + pr_err("%s not appraised\n", file_dentry(file)->d_name.name); + return false; } mutex_unlock(&iint->mutex); + return true; } struct ima_digest *ima_digest_allow(struct ima_digest *digest, int action) @@ -357,15 +354,17 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name, if (size > ima_digest_db_max_size - ima_digest_db_size) { pr_err_once("digest DB is full: %d\n", ima_digest_db_size); - goto out_fput; + goto out_vfree; } - ima_check_measured_appraised(file); + if (!ima_check_measured_appraised(file)) + goto out_vfree; ret = ima_parse_compact_list(size, datap, DIGEST_LIST_OP_ADD); if (ret < 0) pr_err("Unable to parse file: %s (%d)", name, ret); +out_vfree: vfree(datap); out_fput: fput(file); diff --git a/security/integrity/ima/ima_digest_list.h b/security/integrity/ima/ima_digest_list.h index 4a8b0e000ad3e1c87a0f18d0a527b0080609fbf0..8f106825be7c41d1865a21ce7214894137007d80 100644 --- a/security/integrity/ima/ima_digest_list.h +++ b/security/integrity/ima/ima_digest_list.h @@ -23,7 +23,7 @@ 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); +bool ima_check_measured_appraised(struct file *file); bool ima_check_current_is_parser(void); void ima_set_parser(void); void ima_unset_parser(void); diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index dd577ae68381343eeb72c2582b3c5d0970c864c3..c0bc4c8693c20bc40fa83f18cb6d843de3765238 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -386,11 +386,11 @@ static ssize_t ima_read_policy(char *path) rc = -ENOMEM; break; } - /* - * Disable usage of digest lists if not measured - * or appraised. - */ - ima_check_measured_appraised(file); + + if (!ima_check_measured_appraised(file)) { + rc = -EACCES; + break; + } if (dentry == digest_list_data_del) op = DIGEST_LIST_OP_DEL; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 0a202a4f07c1cf3c3d7fd3db3d6187867284710f..c93626aa3eb5641ce8303feed2ad271c6394f211 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -620,7 +620,7 @@ int ima_file_check(struct file *file, int mask) mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); if (ima_current_is_parser() && !rc) - ima_check_measured_appraised(file); + rc = ima_check_measured_appraised(file) ? 0 : -EACCES; return rc; #else return process_measurement(file, current_cred(), secid, NULL, 0,