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

Commit e7c568e0 authored by Peter Moody's avatar Peter Moody Committed by Mimi Zohar
Browse files

ima: audit log hashes



This adds an 'audit' policy action which audit logs file measurements.

Changelog v6:
 - use new action flag handling (Dmitry Kasatkin).
 - removed whitespace (Mimi)

Changelog v5:
 - use audit_log_untrustedstring.

Changelog v4:
 - cleanup digest -> hash conversion.
 - use filename rather than d_path in ima_audit_measurement.

Changelog v3:
 - Use newly exported audit_log_task_info for logging pid/ppid/uid/etc.
 - Update the ima_policy ABI documentation.

Changelog v2:
 - Use 'audit' action rather than 'measure_and_audit' to permit
 auditing in the absence of measuring..

Changelog v1:
 - Initial posting.

Signed-off-by: default avatarPeter Moody <pmoody@google.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent 45e2472e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ Description:

		rule format: action [condition ...]

		action: measure | dont_measure | appraise | dont_appraise
		action: measure | dont_measure | appraise | dont_appraise | audit
		condition:= base | lsm
			base:	[[func=] [mask=] [fsmagic=] [uid=] [fowner]]
			lsm:	[[subj_user=] [subj_role=] [subj_type=]
+2 −0
Original line number Diff line number Diff line
@@ -114,6 +114,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
			    struct file *file);
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   const unsigned char *filename);
void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename);
int ima_store_template(struct ima_template_entry *entry, int violation,
		       struct inode *inode);
void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
+31 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename,
 */
int ima_get_action(struct inode *inode, int mask, int function)
{
	int flags = IMA_MEASURE | IMA_APPRAISE;
	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;

	if (!ima_appraise)
		flags &= ~IMA_APPRAISE;
@@ -207,3 +207,33 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
	if (result < 0)
		kfree(entry);
}

void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename)
{
	struct audit_buffer *ab;
	char hash[(IMA_DIGEST_SIZE * 2) + 1];
	int i;

	if (iint->flags & IMA_AUDITED)
		return;

	for (i = 0; i < IMA_DIGEST_SIZE; i++)
		hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
	hash[i * 2] = '\0';

	ab = audit_log_start(current->audit_context, GFP_KERNEL,
			     AUDIT_INTEGRITY_RULE);
	if (!ab)
		return;

	audit_log_format(ab, "file=");
	audit_log_untrustedstring(ab, filename);
	audit_log_format(ab, " hash=");
	audit_log_untrustedstring(ab, hash);

	audit_log_task_info(ab, current);
	audit_log_end(ab);

	iint->flags |= IMA_AUDITED;
}
+6 −3
Original line number Diff line number Diff line
@@ -156,8 +156,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
	if (!ima_initialized || !S_ISREG(inode->i_mode))
		return 0;

	/* Determine if in appraise/measurement policy,
	 * returns IMA_MEASURE, IMA_APPRAISE bitmask.  */
	/* Determine if in appraise/audit/measurement policy,
	 * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask.  */
	action = ima_get_action(inode, mask, function);
	if (!action)
		return 0;
@@ -171,7 +171,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
		goto out;

	/* Determine if already appraised/measured based on bitmask
	 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */
	 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
	 *  IMA_AUDIT, IMA_AUDITED) */
	iint->flags |= action;
	action &= ~((iint->flags & IMA_DONE_MASK) >> 1);

@@ -202,6 +203,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
	if (action & IMA_APPRAISE)
		rc = ima_appraise_measurement(iint, file,
					      !pathname ? filename : pathname);
	if (action & IMA_AUDIT)
		ima_audit_measurement(iint, !pathname ? filename : pathname);
	kfree(pathbuf);
out:
	mutex_unlock(&inode->i_mutex);
+11 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#define DONT_MEASURE	0x0002
#define APPRAISE	0x0004	/* same as IMA_APPRAISE */
#define DONT_APPRAISE	0x0008
#define AUDIT		0x0040

#define MAX_LSM_RULES 6
enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
@@ -277,6 +278,7 @@ enum {
	Opt_err = -1,
	Opt_measure = 1, Opt_dont_measure,
	Opt_appraise, Opt_dont_appraise,
	Opt_audit,
	Opt_obj_user, Opt_obj_role, Opt_obj_type,
	Opt_subj_user, Opt_subj_role, Opt_subj_type,
	Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner
@@ -287,6 +289,7 @@ static match_table_t policy_tokens = {
	{Opt_dont_measure, "dont_measure"},
	{Opt_appraise, "appraise"},
	{Opt_dont_appraise, "dont_appraise"},
	{Opt_audit, "audit"},
	{Opt_obj_user, "obj_user=%s"},
	{Opt_obj_role, "obj_role=%s"},
	{Opt_obj_type, "obj_type=%s"},
@@ -379,6 +382,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)

			entry->action = DONT_APPRAISE;
			break;
		case Opt_audit:
			ima_log_string(ab, "action", "audit");

			if (entry->action != UNKNOWN)
				result = -EINVAL;

			entry->action = AUDIT;
			break;
		case Opt_func:
			ima_log_string(ab, "func", args[0].from);

Loading