Unverified Commit 7fccdca5 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!10813 ima: dont disable digest_list if the file is not processed

Merge Pull Request from: @HuaxinLuGitee 
 
In the previous implementation, if the digest list file is not measured or
appraised, the whole IMA digest list function will be disabled, and the
system must be rebooted. It is too strict beacuse users may make some
mistakes.

This commit optimizes the processing logic. If the digest list file is not
processed correctly, just deny access to the file without disabling the
entire function.

Fix: https://gitee.com/openeuler/kernel/issues/IAIO9Q 
 
Link:https://gitee.com/openeuler/kernel/pulls/10813

 

Reviewed-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 8fa5de01 7d79ba08
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);
+5 −5
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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,