[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] audit logging hashes (v4)



Add 'audit' policy action which audit logs file measurements.

I believe this incorporates all of the comments from v3, including the
comment from eparis about using audit_log_task_info().

This patch is against
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity#next-ima-appraisal

Signed-off-by: Peter Moody <pmoody@xxxxxxxxxx>
---
 security/integrity/ima/ima.h        |    2 ++
 security/integrity/ima/ima_api.c    |   30 +++++++++++++++++++++++++++++-
 security/integrity/ima/ima_main.c   |   12 ++++++++----
 security/integrity/ima/ima_policy.c |   13 ++++++++++++-
 security/integrity/integrity.h      |    2 ++
 5 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d5bf463..ed63054 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -105,6 +105,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,
+			   struct file *file);
 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);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index b5cbef5..1a9a79a 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -114,7 +114,7 @@ err_out:
  */
 int ima_must_appraise_or_measure(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;
@@ -205,3 +205,31 @@ void ima_store_measurement(struct
integrity_iint_cache *iint,
 	if (result < 0)
 		kfree(entry);
 }
+
+void ima_audit_measurement(struct integrity_iint_cache *iint, struct
file *file)
+{
+	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++)
+		snprintf(&(hash[i * 2]), 3, "%02x", iint->ima_xattr.digest[i]);
+
+	ab = audit_log_start(current->audit_context, GFP_KERNEL,
+			     AUDIT_INTEGRITY_RULE);
+	if (!ab)
+		return;
+
+	audit_log_d_path(ab, "path=", &file->f_path);
+	audit_log_format(ab, " hash=");
+	audit_log_untrustedstring(ab, hash);
+
+	audit_log_task_info(ab, current);
+	audit_log_task_context(ab);
+	audit_log_end(ab);
+
+	iint->flags |= IMA_AUDITED;
+}
diff --git a/security/integrity/ima/ima_main.c
b/security/integrity/ima/ima_main.c
index f1b57e5..d4a983d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -139,8 +139,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_must_appraise_or_measure(inode, mask, function);
 	if (!action)
 		return 0;
@@ -154,9 +154,11 @@ 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_MEASURED | IMA_APPRAISED)) >> 1);
+	action &= ~((iint->flags & (IMA_MEASURED | IMA_APPRAISED |
+				    IMA_AUDITED)) >> 1);

 	/* Nothing to do, just return existing appraised status */
 	if (!action) {
@@ -172,6 +174,8 @@ static int process_measurement(struct file *file,
const unsigned char *filename,
 		ima_store_measurement(iint, file, filename);
 	if (action & IMA_APPRAISE)
 		rc = ima_appraise_measurement(iint, file, filename);
+	if (action & IMA_AUDIT)
+		ima_audit_measurement(iint, file);
 out:
 	mutex_unlock(&inode->i_mutex);
 	return (rc && must_appraise) ? -EACCES : 0;
diff --git a/security/integrity/ima/ima_policy.c
b/security/integrity/ima/ima_policy.c
index 238aa2b..d2729a7 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -33,6 +33,7 @@
 #define APPRAISE		4	/* same as IMA_APPRAISE */
 #define DONT_APPRAISE		8
 #define APPRAISE_MASK		12
+#define AUDIT			64

 #define MAX_LSM_RULES 6
 enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
@@ -205,7 +206,7 @@ int ima_match_policy(struct inode *inode, enum
ima_hooks func, int mask,
 		if (!ima_match_rules(entry, inode, func, mask))
 			continue;

-		action |= (entry->action & (IMA_APPRAISE | IMA_MEASURE));
+		action |= (entry->action & (IMA_APPRAISE | IMA_MEASURE | IMA_AUDIT));
 		actmask &= (entry->action & APPRAISE_MASK) ?
 		    ~APPRAISE_MASK : ~MEASURE_MASK;
 		if (!actmask)
@@ -272,6 +273,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
@@ -282,6 +284,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"},
@@ -374,6 +377,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);

diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 0594a57..1dae0b2 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -22,6 +22,8 @@
 #define IMA_APPRAISED		8
 #define IMA_COLLECTED		16
 #define IMA_DIGSIG		32
+#define IMA_AUDIT		64
+#define IMA_AUDITED		128

 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
-- 
1.7.7.3
-- 
Peter Moody      Google    1.650.253.7306
Security Engineer  pgp:0xC3410038
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

Powered by Linux