lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 24 Jun 2010 14:10:28 -0400
From:	Mimi Zohar <zohar@...ux.vnet.ibm.com>
To:	linux-kernel@...r.kernel.org
Cc:	Mimi Zohar <zohar@...ux.vnet.ibm.com>,
	linux-security-module@...r.kernel.org,
	linux-fsdevel@...r.kernel.org, James Morris <jmorris@...ei.org>,
	David Safford <safford@...son.ibm.com>,
	Dave Hansen <dave@...ux.vnet.ibm.com>,
	Mimi Zohar <zohar@...ibm.com>
Subject: [PATCH 12/15] ima: appraise default rules

Unlike the IMA measurement policy, the appraise policy can not be
dependent on runtime process information, such as the task uid,
as the 'security.ima' xattr is written on file close and must
be updated each time the file changes, regardless of the current
task uid. The appraise default policy appraises all files owned
by root.

Signed-off-by: Mimi Zohar <zohar@...ibm.com>
Acked-by: Serge Hallyn <serue@...ibm.com>
---
 security/integrity/ima/ima.h          |    2 +
 security/integrity/ima/ima_appraise.c |   14 +++++++-
 security/integrity/ima/ima_policy.c   |   61 +++++++++++++++++++++++++++++++-
 3 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index aabd615..7cc028d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -122,6 +122,8 @@ void iint_rcu_free(struct rcu_head *rcu);
 enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
 
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
+int ima_match_appraise_policy(struct inode *inode, enum ima_hooks func,
+			      int mask);
 void ima_init_policy(void);
 void ima_update_policy(void);
 ssize_t ima_parse_add_rule(char *);
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 423a5a4..fb402fa 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -28,7 +28,19 @@ __setup("ima_appraise=", default_appraise_setup);
 int ima_must_appraise(struct integrity_iint_cache *iint, struct inode *inode,
 		      enum ima_hooks func, int mask)
 {
-	return 0;
+	int must_appraise, rc = 0;
+
+	if (!ima_appraise || !inode->i_op->getxattr)
+		return 0;
+	else if (iint->flags & IMA_APPRAISED)
+		return 0;
+
+	must_appraise = ima_match_appraise_policy(inode, func, mask);
+	if (must_appraise) {
+		iint->flags |= IMA_APPRAISE;
+		rc = 1;
+	}
+	return rc;
 }
 
 static void ima_fix_xattr(struct dentry *dentry,
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index aef8c0a..7fd84af 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -24,8 +24,11 @@
 #define IMA_MASK 	0x0002
 #define IMA_FSMAGIC	0x0004
 #define IMA_UID		0x0008
+#define IMA_OWNER	0x0010
 
-enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE };
+enum ima_action { UNKNOWN = -1,
+		  DONT_MEASURE = 0, MEASURE,
+		  DONT_APPRAISE, APPRAISE};
 
 #define MAX_LSM_RULES 6
 enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
@@ -40,6 +43,7 @@ struct ima_measure_rule_entry {
 	int mask;
 	unsigned long fsmagic;
 	uid_t uid;
+	uid_t owner;
 	struct {
 		void *rule;	/* LSM file metadata specific */
 		int type;	/* audit type */
@@ -48,7 +52,7 @@ struct ima_measure_rule_entry {
 
 /*
  * Without LSM specific knowledge, the default policy can only be
- * written in terms of .action, .func, .mask, .fsmagic, and .uid
+ * written in terms of .action, .func, .mask, .fsmagic, .uid, and .owner
  */
 
 /*
@@ -70,6 +74,13 @@ static struct ima_measure_rule_entry default_rules[] = {
 	 .flags = IMA_FUNC | IMA_MASK},
 	{.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0,
 	 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
+	{.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = APPRAISE,.owner = 0,.flags = IMA_OWNER},
 };
 
 static LIST_HEAD(measure_default_rules);
@@ -110,6 +121,8 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
 		return false;
 	if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
 		return false;
+	if ((rule->flags & IMA_OWNER) && rule->owner != inode->i_uid)
+		return false;
 	for (i = 0; i < MAX_LSM_RULES; i++) {
 		int rc = 0;
 		u32 osid, sid;
@@ -166,6 +179,9 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
 	list_for_each_entry(entry, ima_measure, list) {
 		bool rc;
 
+		if ((entry->action == APPRAISE) ||
+		    (entry->action == DONT_APPRAISE))
+			continue;
 		rc = ima_match_rules(entry, inode, func, mask);
 		if (rc)
 			return entry->action;
@@ -173,6 +189,28 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
 	return 0;
 }
 
+int ima_match_appraise_policy(struct inode *inode, enum ima_hooks func,
+			      int mask)
+{
+	struct ima_measure_rule_entry *entry;
+
+	list_for_each_entry(entry, ima_measure, list) {
+		bool rc;
+
+		if ((entry->action == MEASURE) ||
+		    (entry->action == DONT_MEASURE))
+			continue;
+		rc = ima_match_rules(entry, inode, func, mask);
+		if (rc) {
+			if (entry->action == DONT_APPRAISE)
+				return 0;
+			if (entry->action == APPRAISE)
+				return 1;
+		}
+	}
+	return 0;
+}
+
 /**
  * ima_init_policy - initialize the default measure rules.
  *
@@ -220,6 +258,7 @@ void ima_update_policy(void)
 enum {
 	Opt_err = -1,
 	Opt_measure = 1, Opt_dont_measure,
+	Opt_appraise, Opt_dont_appraise,
 	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
@@ -228,6 +267,8 @@ enum {
 static match_table_t policy_tokens = {
 	{Opt_measure, "measure"},
 	{Opt_dont_measure, "dont_measure"},
+	{Opt_appraise, "appraise"},
+	{Opt_dont_appraise, "dont_appraise"},
 	{Opt_obj_user, "obj_user=%s"},
 	{Opt_obj_role, "obj_role=%s"},
 	{Opt_obj_type, "obj_type=%s"},
@@ -300,6 +341,22 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 
 			entry->action = DONT_MEASURE;
 			break;
+		case Opt_appraise:
+			ima_log_string(ab, "%s ", "appraise");
+
+			if (entry->action != UNKNOWN)
+				result = -EINVAL;
+
+			entry->action = APPRAISE;
+			break;
+		case Opt_dont_appraise:
+			ima_log_string(ab, "%s ", "dont_appraise");
+
+			if (entry->action != UNKNOWN)
+				result = -EINVAL;
+
+			entry->action = DONT_APPRAISE;
+			break;
 		case Opt_func:
 			ima_log_string(ab, "func", args[0].from);
 
-- 
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ