Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19453ce0 authored by Matthew Garrett's avatar Matthew Garrett Committed by Mimi Zohar
Browse files

IMA: support for per policy rule template formats



Admins may wish to log different measurements using different IMA
templates. Add support for overriding the default template on a per-rule
basis.

Inspired-by: default avatarRoberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: default avatarMatthew Garrett <mjg59@google.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 8c655784
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -24,8 +24,7 @@ Description:
				[euid=] [fowner=] [fsname=]]
			lsm:	[[subj_user=] [subj_role=] [subj_type=]
				 [obj_user=] [obj_role=] [obj_type=]]
			option:	[[appraise_type=]] [permit_directio]

			option:	[[appraise_type=]] [template=] [permit_directio]
		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
				[FIRMWARE_CHECK]
				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
@@ -38,6 +37,8 @@ Description:
			fowner:= decimal value
		lsm:  	are LSM specific
		option:	appraise_type:= [imasig]
			template:= name of a defined IMA template type
			(eg, ima-ng). Only valid when action is "measure".
			pcr:= decimal value

		default policy:
+12 −4
Original line number Diff line number Diff line
@@ -146,7 +146,11 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
int ima_init_crypto(void);
void ima_putc(struct seq_file *m, void *data, int datalen);
void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
int template_desc_init_fields(const char *template_fmt,
			      const struct ima_template_field ***fields,
			      int *num_fields);
struct ima_template_desc *ima_template_desc_current(void);
struct ima_template_desc *lookup_template_desc(const char *name);
int ima_restore_measurement_entry(struct ima_template_entry *entry);
int ima_restore_measurement_list(loff_t bufsize, void *buf);
int ima_measurements_show(struct seq_file *m, void *v);
@@ -195,7 +199,8 @@ enum ima_hooks {

/* LIM API function definitions */
int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
		   int mask, enum ima_hooks func, int *pcr);
		   int mask, enum ima_hooks func, int *pcr,
		   struct ima_template_desc **template_desc);
int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
int ima_collect_measurement(struct integrity_iint_cache *iint,
			    struct file *file, void *buf, loff_t size,
@@ -203,11 +208,13 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   const unsigned char *filename,
			   struct evm_ima_xattr_data *xattr_value,
			   int xattr_len, int pcr);
			   int xattr_len, int pcr,
			   struct ima_template_desc *template_desc);
void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename);
int ima_alloc_init_template(struct ima_event_data *event_data,
			    struct ima_template_entry **entry);
			    struct ima_template_entry **entry,
			    struct ima_template_desc *template_desc);
int ima_store_template(struct ima_template_entry *entry, int violation,
		       struct inode *inode,
		       const unsigned char *filename, int pcr);
@@ -216,7 +223,8 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);

/* IMA policy related functions */
int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
		     enum ima_hooks func, int mask, int flags, int *pcr);
		     enum ima_hooks func, int mask, int flags, int *pcr,
		     struct ima_template_desc **template_desc);
void ima_init_policy(void);
void ima_update_policy(void);
void ima_update_policy_flag(void);
+17 −7
Original line number Diff line number Diff line
@@ -38,11 +38,17 @@ void ima_free_template_entry(struct ima_template_entry *entry)
 * ima_alloc_init_template - create and initialize a new template entry
 */
int ima_alloc_init_template(struct ima_event_data *event_data,
			    struct ima_template_entry **entry)
			    struct ima_template_entry **entry,
			    struct ima_template_desc *desc)
{
	struct ima_template_desc *template_desc = ima_template_desc_current();
	struct ima_template_desc *template_desc;
	int i, result = 0;

	if (desc)
		template_desc = desc;
	else
		template_desc = ima_template_desc_current();

	*entry = kzalloc(sizeof(**entry) + template_desc->num_fields *
			 sizeof(struct ima_field_data), GFP_NOFS);
	if (!*entry)
@@ -143,7 +149,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
	/* can overflow, only indicator */
	atomic_long_inc(&ima_htable.violations);

	result = ima_alloc_init_template(&event_data, &entry);
	result = ima_alloc_init_template(&event_data, &entry, NULL);
	if (result < 0) {
		result = -ENOMEM;
		goto err_out;
@@ -166,6 +172,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 *        MAY_APPEND)
 * @func: caller identifier
 * @pcr: pointer filled in if matched measure policy sets pcr=
 * @template_desc: pointer filled in if matched measure policy sets template=
 *
 * The policy is defined in terms of keypairs:
 *		subj=, obj=, type=, func=, mask=, fsmagic=
@@ -178,13 +185,15 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 *
 */
int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
		   int mask, enum ima_hooks func, int *pcr)
		   int mask, enum ima_hooks func, int *pcr,
		   struct ima_template_desc **template_desc)
{
	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;

	flags &= ima_policy_flag;

	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr);
	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr,
				template_desc);
}

/*
@@ -279,7 +288,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
void ima_store_measurement(struct integrity_iint_cache *iint,
			   struct file *file, const unsigned char *filename,
			   struct evm_ima_xattr_data *xattr_value,
			   int xattr_len, int pcr)
			   int xattr_len, int pcr,
			   struct ima_template_desc *template_desc)
{
	static const char op[] = "add_template_measure";
	static const char audit_cause[] = "ENOMEM";
@@ -296,7 +306,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
	if (iint->measured_pcrs & (0x1 << pcr))
		return;

	result = ima_alloc_init_template(&event_data, &entry);
	result = ima_alloc_init_template(&event_data, &entry, template_desc);
	if (result < 0) {
		integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
				    op, audit_cause, result, 0);
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)

	security_task_getsecid(current, &secid);
	return ima_match_policy(inode, current_cred(), secid, func, mask,
				IMA_APPRAISE | IMA_HASH, NULL);
				IMA_APPRAISE | IMA_HASH, NULL, NULL);
}

static int ima_fix_xattr(struct dentry *dentry,
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ static int __init ima_add_boot_aggregate(void)
		}
	}

	result = ima_alloc_init_template(&event_data, &entry);
	result = ima_alloc_init_template(&event_data, &entry, NULL);
	if (result < 0) {
		audit_cause = "alloc_entry";
		goto err_out;
Loading