Commit e9085e0a authored by Lakshmi Ramasubramanian's avatar Lakshmi Ramasubramanian Committed by Mimi Zohar
Browse files

IMA: Add support to limit measuring keys



Limit measuring keys to those keys being loaded onto a given set of
keyrings only and when the user id (uid) matches if uid is specified
in the policy.

This patch defines a new IMA policy option namely "keyrings=" that
can be used to specify a set of keyrings. If this option is specified
in the policy for "measure func=KEY_CHECK" then only the keys
loaded onto a keyring given in the "keyrings=" option are measured.

If uid is specified in the policy then the key is measured only if
the current user id matches the one specified in the policy.

Added a new parameter namely "keyring" (name of the keyring) to
process_buffer_measurement(). The keyring name is passed to
ima_get_action() to determine the required action.
ima_match_rules() is updated to check keyring in the policy, if
specified, for KEY_CHECK function.

Signed-off-by: default avatarLakshmi Ramasubramanian <nramas@linux.microsoft.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent cb1aa382
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ Description:
			lsm:	[[subj_user=] [subj_role=] [subj_type=]
				 [obj_user=] [obj_role=] [obj_type=]]
			option:	[[appraise_type=]] [template=] [permit_directio]
				[appraise_flag=]
				[appraise_flag=] [keyrings=]
		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
				[FIRMWARE_CHECK]
				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
@@ -42,6 +42,9 @@ Description:
			appraise_flag:= [check_blacklist]
			Currently, blacklist check is only for files signed with appended
			signature.
			keyrings:= list of keyrings
			(eg, .builtin_trusted_keys|.ima). Only valid
			when action is "measure" and func is KEY_CHECK.
			template:= name of a defined IMA template type
			(eg, ima-ng). Only valid when action is "measure".
			pcr:= decimal value
@@ -117,3 +120,8 @@ Description:
		Example of measure rule using KEY_CHECK to measure all keys:

			measure func=KEY_CHECK

		Example of measure rule using KEY_CHECK to only measure
		keys added to .builtin_trusted_keys or .ima keyring:

			measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima
+5 −3
Original line number Diff line number Diff line
@@ -208,7 +208,8 @@ struct modsig;
/* 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,
		   struct ima_template_desc **template_desc);
		   struct ima_template_desc **template_desc,
		   const char *keyring);
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,
@@ -220,7 +221,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   struct ima_template_desc *template_desc);
void process_buffer_measurement(const void *buf, int size,
				const char *eventname, enum ima_hooks func,
				int pcr);
				int pcr, const char *keyring);
void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename);
int ima_alloc_init_template(struct ima_event_data *event_data,
@@ -235,7 +236,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,
		     struct ima_template_desc **template_desc);
		     struct ima_template_desc **template_desc,
		     const char *keyring);
void ima_init_policy(void);
void ima_update_policy(void);
void ima_update_policy_flag(void);
+5 −3
Original line number Diff line number Diff line
@@ -169,12 +169,13 @@ err_out:
 * @func: caller identifier
 * @pcr: pointer filled in if matched measure policy sets pcr=
 * @template_desc: pointer filled in if matched measure policy sets template=
 * @keyring: keyring name used to determine the action
 *
 * The policy is defined in terms of keypairs:
 *		subj=, obj=, type=, func=, mask=, fsmagic=
 *	subj,obj, and type: are LSM specific.
 *	func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK
 *	| KEXEC_CMDLINE
 *	| KEXEC_CMDLINE | KEY_CHECK
 *	mask: contains the permission mask
 *	fsmagic: hex value
 *
@@ -183,14 +184,15 @@ err_out:
 */
int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
		   int mask, enum ima_hooks func, int *pcr,
		   struct ima_template_desc **template_desc)
		   struct ima_template_desc **template_desc,
		   const char *keyring)
{
	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,
				template_desc);
				template_desc, keyring);
}

/*
+2 −2
Original line number Diff line number Diff line
@@ -55,7 +55,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, NULL);
				IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL);
}

static int ima_fix_xattr(struct dentry *dentry,
@@ -330,7 +330,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint,
		if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
			process_buffer_measurement(digest, digestsize,
						   "blacklisted-hash", NONE,
						   pcr);
						   pcr, NULL);
	}

	return rc;
+7 −1
Original line number Diff line number Diff line
@@ -46,7 +46,13 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
	 * parameter to process_buffer_measurement() and is set
	 * in the "eventname" field in ima_event_data for
	 * the key measurement IMA event.
	 *
	 * The name of the keyring is also passed in the "keyring"
	 * parameter to process_buffer_measurement() to check
	 * if the IMA policy is configured to measure a key linked
	 * to the given keyring.
	 */
	process_buffer_measurement(payload, payload_len,
				   keyring->description, KEY_CHECK, 0);
				   keyring->description, KEY_CHECK, 0,
				   keyring->description);
}
Loading