All of lore.kernel.org
 help / color / mirror / Atom feed
From: Casey Schaufler <casey@schaufler-ca.com>
To: casey@schaufler-ca.com, paul@paul-moore.com,
	linux-security-module@vger.kernel.org
Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org,
	john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp,
	stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org,
	mic@digikod.net
Subject: [PATCH v39 04/42] IMA: avoid label collisions with stacked LSMs
Date: Fri, 15 Dec 2023 14:15:58 -0800	[thread overview]
Message-ID: <20231215221636.105680-5-casey@schaufler-ca.com> (raw)
In-Reply-To: <20231215221636.105680-1-casey@schaufler-ca.com>

Integrity measurement may filter on security module information
and needs to be clear in the case of multiple active security
modules which applies. Provide a boot option ima_rules_lsm= to
allow the user to specify an active security module to apply
filters to. If not specified, use the first registered module
that supports the audit_rule_match() LSM hook. Allow the user
to specify in the IMA policy an lsm= option to specify the
security module to use for a particular rule.

This requires adding the LSM of interest as a parameter
to three of the audit hooks.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
To: Mimi Zohar <zohar@linux.ibm.com>
To: linux-integrity@vger.kernel.org
To: audit@vger.kernel.org
---
 Documentation/ABI/testing/ima_policy |  8 +++-
 include/linux/lsm_hook_defs.h        |  7 +--
 include/linux/security.h             | 26 +++++++---
 security/apparmor/audit.c            | 15 ++++--
 security/apparmor/include/audit.h    |  7 +--
 security/integrity/ima/ima_policy.c  | 71 ++++++++++++++++++++++++----
 security/security.c                  | 64 +++++++++++++++++++++----
 security/selinux/include/audit.h     | 10 ++--
 security/selinux/ss/services.c       | 15 ++++--
 security/smack/smack_lsm.c           | 12 ++++-
 10 files changed, 192 insertions(+), 43 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index c2385183826c..a59291b97c24 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -26,7 +26,7 @@ Description:
 				[uid=] [euid=] [gid=] [egid=]
 				[fowner=] [fgroup=]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
-				 [obj_user=] [obj_role=] [obj_type=]]
+				 [obj_user=] [obj_role=] [obj_type=] [lsm=]]
 			option:	[digest_type=] [template=] [permit_directio]
 				[appraise_type=] [appraise_flag=]
 				[appraise_algos=] [keyrings=]
@@ -138,6 +138,12 @@ Description:
 
 			measure subj_user=_ func=FILE_CHECK mask=MAY_READ
 
+		It is possible to explicitly specify which security
+		module a rule applies to using lsm=.  If the security
+		module specified is not active on the system the rule
+		will be rejected.  If lsm= is not specified the first
+		security module registered on the system will be assumed.
+
 		Example of measure rules using alternate PCRs::
 
 			measure func=KEXEC_KERNEL_CHECK pcr=4
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index c925a0d26edf..2159013890aa 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -392,10 +392,11 @@ LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer)
 
 #ifdef CONFIG_AUDIT
 LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr,
-	 void **lsmrule)
+	 void **lsmrule, int lsmid)
 LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule)
-LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule)
-LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule)
+LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule,
+	 int lsmid)
+LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule, int lsmid)
 #endif /* CONFIG_AUDIT */
 
 #ifdef CONFIG_BPF_SYSCALL
diff --git a/include/linux/security.h b/include/linux/security.h
index d4103b6cd3fc..2320ed78c4de 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -286,6 +286,8 @@ int unregister_blocking_lsm_notifier(struct notifier_block *nb);
 extern int security_init(void);
 extern int early_security_init(void);
 extern u64 lsm_name_to_attr(const char *name);
+extern u64 lsm_name_to_id(const char *name);
+extern const char *lsm_id_to_name(u64 id);
 
 /* Security operations */
 int security_binder_set_context_mgr(const struct cred *mgr);
@@ -536,6 +538,16 @@ static inline u64 lsm_name_to_attr(const char *name)
 	return LSM_ATTR_UNDEF;
 }
 
+static inline u64 lsm_name_to_id(const char *name)
+{
+	return LSM_ID_UNDEF;
+}
+
+static inline const char *lsm_id_to_name(u64 id)
+{
+	return NULL;
+}
+
 static inline void security_free_mnt_opts(void **mnt_opts)
 {
 }
@@ -2030,25 +2042,27 @@ static inline void security_audit_rule_free(void *lsmrule)
 #endif /* CONFIG_AUDIT */
 
 #if defined(CONFIG_IMA_LSM_RULES) && defined(CONFIG_SECURITY)
-int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
-int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule);
-void ima_filter_rule_free(void *lsmrule);
+int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
+			 int lsmid);
+int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
+			  int lsmid);
+void ima_filter_rule_free(void *lsmrule, int lsmid);
 
 #else
 
 static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr,
-					   void **lsmrule)
+				       void **lsmrule, int lsmid)
 {
 	return 0;
 }
 
 static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op,
-					    void *lsmrule)
+					void *lsmrule, int lsmid)
 {
 	return 0;
 }
 
-static inline void ima_filter_rule_free(void *lsmrule)
+static inline void ima_filter_rule_free(void *lsmrule, int lsmid)
 { }
 
 #endif /* defined(CONFIG_IMA_LSM_RULES) && defined(CONFIG_SECURITY) */
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 45beb1c5f747..0a9f0019355a 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -206,10 +206,12 @@ struct aa_audit_rule {
 	struct aa_label *label;
 };
 
-void aa_audit_rule_free(void *vrule)
+void aa_audit_rule_free(void *vrule, int lsmid)
 {
 	struct aa_audit_rule *rule = vrule;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
+		return;
 	if (rule) {
 		if (!IS_ERR(rule->label))
 			aa_put_label(rule->label);
@@ -217,10 +219,13 @@ void aa_audit_rule_free(void *vrule)
 	}
 }
 
-int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+		       int lsmid)
 {
 	struct aa_audit_rule *rule;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
+		return 0;
 	switch (field) {
 	case AUDIT_SUBJ_ROLE:
 		if (op != Audit_equal && op != Audit_not_equal)
@@ -240,7 +245,7 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 				     GFP_KERNEL, true, false);
 	if (IS_ERR(rule->label)) {
 		int err = PTR_ERR(rule->label);
-		aa_audit_rule_free(rule);
+		aa_audit_rule_free(rule, LSM_ID_APPARMOR);
 		return err;
 	}
 
@@ -264,12 +269,14 @@ int aa_audit_rule_known(struct audit_krule *rule)
 	return 0;
 }
 
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
+int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid)
 {
 	struct aa_audit_rule *rule = vrule;
 	struct aa_label *label;
 	int found = 0;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
+		return 0;
 	label = aa_secid_to_label(sid);
 
 	if (!label)
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index acbb03b9bd25..a75c45dd059f 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -199,9 +199,10 @@ static inline int complain_error(int error)
 	return error;
 }
 
-void aa_audit_rule_free(void *vrule);
-int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
+void aa_audit_rule_free(void *vrule, int lsmid);
+int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+		       int lsmid);
 int aa_audit_rule_known(struct audit_krule *rule);
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule);
+int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid);
 
 #endif /* __AA_AUDIT_H */
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index f69062617754..a563e0478cc6 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -117,6 +117,8 @@ struct ima_rule_entry {
 		void *rule;	/* LSM file metadata specific */
 		char *args_p;	/* audit value */
 		int type;	/* audit type */
+		int lsm_id;	/* which LSM rule applies to */
+		bool lsm_specific;	/* true if lsm is specified */
 	} lsm[MAX_LSM_RULES];
 	char *fsname;
 	struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */
@@ -309,6 +311,25 @@ static int __init default_appraise_policy_setup(char *str)
 }
 __setup("ima_appraise_tcb", default_appraise_policy_setup);
 
+static int default_rules_lsm __ro_after_init = LSM_ID_UNDEF;
+
+static int __init ima_rules_lsm_init(char *str)
+{
+	int newdrl;
+
+	newdrl = lsm_name_to_id(str);
+	if (newdrl >= 0) {
+		default_rules_lsm = newdrl;
+		return 1;
+	}
+
+	pr_err("default ima rule lsm \"%s\" not registered, value unchanged.",
+		str);
+
+	return 1;
+}
+__setup("ima_rules_lsm=", ima_rules_lsm_init);
+
 static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src)
 {
 	struct ima_rule_opt_list *opt_list;
@@ -380,7 +401,8 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry)
 	int i;
 
 	for (i = 0; i < MAX_LSM_RULES; i++) {
-		ima_filter_rule_free(entry->lsm[i].rule);
+		ima_filter_rule_free(entry->lsm[i].rule,
+				     entry->lsm[i].lsm_id);
 		kfree(entry->lsm[i].args_p);
 	}
 }
@@ -425,7 +447,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
 
 		ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
 				     nentry->lsm[i].args_p,
-				     &nentry->lsm[i].rule);
+				     &nentry->lsm[i].rule,
+				     entry->lsm[i].lsm_id);
 		if (!nentry->lsm[i].rule)
 			pr_warn("rule for LSM \'%s\' is undefined\n",
 				nentry->lsm[i].args_p);
@@ -451,7 +474,8 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
 	 * be owned by nentry.
 	 */
 	for (i = 0; i < MAX_LSM_RULES; i++)
-		ima_filter_rule_free(entry->lsm[i].rule);
+		ima_filter_rule_free(entry->lsm[i].rule,
+				     entry->lsm[i].lsm_id);
 	kfree(entry);
 
 	return 0;
@@ -650,14 +674,16 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
 			security_inode_getsecid(inode, &osid);
 			rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
 						   Audit_equal,
-						   lsm_rule->lsm[i].rule);
+						   lsm_rule->lsm[i].rule,
+						   lsm_rule->lsm[i].lsm_id);
 			break;
 		case LSM_SUBJ_USER:
 		case LSM_SUBJ_ROLE:
 		case LSM_SUBJ_TYPE:
 			rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
 						   Audit_equal,
-						   lsm_rule->lsm[i].rule);
+						   lsm_rule->lsm[i].rule,
+						   lsm_rule->lsm[i].lsm_id);
 			break;
 		default:
 			break;
@@ -680,7 +706,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
 out:
 	if (rule_reinitialized) {
 		for (i = 0; i < MAX_LSM_RULES; i++)
-			ima_filter_rule_free(lsm_rule->lsm[i].rule);
+			ima_filter_rule_free(lsm_rule->lsm[i].rule,
+					     lsm_rule->lsm[i].lsm_id);
 		kfree(lsm_rule);
 	}
 	return result;
@@ -1073,7 +1100,7 @@ enum policy_opt {
 	Opt_digest_type,
 	Opt_appraise_type, Opt_appraise_flag, Opt_appraise_algos,
 	Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
-	Opt_label, Opt_err
+	Opt_lsm, Opt_label, Opt_err
 };
 
 static const match_table_t policy_tokens = {
@@ -1121,6 +1148,7 @@ static const match_table_t policy_tokens = {
 	{Opt_pcr, "pcr=%s"},
 	{Opt_template, "template=%s"},
 	{Opt_keyrings, "keyrings=%s"},
+	{Opt_lsm, "lsm=%s"},
 	{Opt_label, "label=%s"},
 	{Opt_err, NULL}
 };
@@ -1140,7 +1168,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
 	entry->lsm[lsm_rule].type = audit_type;
 	result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal,
 				      entry->lsm[lsm_rule].args_p,
-				      &entry->lsm[lsm_rule].rule);
+				      &entry->lsm[lsm_rule].rule,
+				      entry->lsm[lsm_rule].lsm_id);
 	if (!entry->lsm[lsm_rule].rule) {
 		pr_warn("rule for LSM \'%s\' is undefined\n",
 			entry->lsm[lsm_rule].args_p);
@@ -1878,6 +1907,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 						 &(template_desc->num_fields));
 			entry->template = template_desc;
 			break;
+		case Opt_lsm: {
+			int i;
+
+			result = lsm_name_to_id(args[0].from);
+			if (result < 0) {
+				for (i = 0; i < MAX_LSM_RULES; i++)
+					entry->lsm[i].args_p = NULL;
+				result = -EINVAL;
+				break;
+			}
+			for (i = 0; i < MAX_LSM_RULES; i++) {
+				entry->lsm[i].lsm_id = result;
+				entry->lsm[i].lsm_specific = true;
+			}
+			result = 0;
+			break;
+			}
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
 			result = -EINVAL;
@@ -1923,6 +1969,7 @@ ssize_t ima_parse_add_rule(char *rule)
 	struct ima_rule_entry *entry;
 	ssize_t result, len;
 	int audit_info = 0;
+	int i;
 
 	p = strsep(&rule, "\n");
 	len = strlen(p) + 1;
@@ -1940,6 +1987,11 @@ ssize_t ima_parse_add_rule(char *rule)
 
 	INIT_LIST_HEAD(&entry->list);
 
+	for (i = 0; i < MAX_LSM_RULES; i++) {
+		entry->lsm[i].lsm_id = default_rules_lsm;
+		entry->lsm[i].lsm_specific = false;
+	}
+
 	result = ima_parse_rule(p, entry);
 	if (result) {
 		ima_free_rule(entry);
@@ -2251,6 +2303,9 @@ int ima_policy_show(struct seq_file *m, void *v)
 					   entry->lsm[i].args_p);
 				break;
 			}
+			if (entry->lsm[i].lsm_specific)
+				seq_printf(m, pt(Opt_lsm),
+				    lsm_id_to_name(entry->lsm[i].lsm_id));
 			seq_puts(m, " ");
 		}
 	}
diff --git a/security/security.c b/security/security.c
index 0a51e3d23570..cdf9ee12b064 100644
--- a/security/security.c
+++ b/security/security.c
@@ -271,6 +271,46 @@ static void __init initialize_lsm(struct lsm_info *lsm)
 u32 lsm_active_cnt __ro_after_init;
 const struct lsm_id *lsm_idlist[LSM_CONFIG_COUNT];
 
+/**
+ * lsm_name_to_id - get the LSM ID for a registered LSM
+ * @name: the name of the LSM
+ *
+ * Returns the LSM ID associated with the named LSM or
+ * LSM_ID_UNDEF if the name isn't recongnized.
+ */
+u64 lsm_name_to_id(const char *name)
+{
+	int i;
+
+	for (i = 0; i < LSM_CONFIG_COUNT; i++) {
+		if (!lsm_idlist[i]->name)
+			return LSM_ID_UNDEF;
+		if (!strcmp(name, lsm_idlist[i]->name))
+			return lsm_idlist[i]->id;
+	}
+	return LSM_ID_UNDEF;
+}
+
+/**
+ * lsm_id_to_name - get the LSM name for a registered LSM ID
+ * @id: the ID of the LSM
+ *
+ * Returns the LSM name associated with the LSM ID or
+ * NULL if the ID isn't recongnized.
+ */
+const char *lsm_id_to_name(u64 id)
+{
+	int i;
+
+	for (i = 0; i < LSM_CONFIG_COUNT; i++) {
+		if (!lsm_idlist[i]->name)
+			return NULL;
+		if (id == lsm_idlist[i]->id)
+			return lsm_idlist[i]->name;
+	}
+	return NULL;
+}
+
 /* Populate ordered LSMs list from comma-separated LSM name list. */
 static void __init ordered_lsm_parse(const char *order, const char *origin)
 {
@@ -5336,7 +5376,8 @@ int security_key_getsecurity(struct key *key, char **buffer)
  */
 int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
 {
-	return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule);
+	return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule,
+			     LSM_ID_UNDEF);
 }
 
 /**
@@ -5362,7 +5403,7 @@ int security_audit_rule_known(struct audit_krule *krule)
  */
 void security_audit_rule_free(void *lsmrule)
 {
-	call_void_hook(audit_rule_free, lsmrule);
+	call_void_hook(audit_rule_free, lsmrule, LSM_ID_UNDEF);
 }
 
 /**
@@ -5380,7 +5421,8 @@ void security_audit_rule_free(void *lsmrule)
  */
 int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
 {
-	return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule);
+	return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule,
+			     LSM_ID_UNDEF);
 }
 #endif /* CONFIG_AUDIT */
 
@@ -5389,19 +5431,23 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
  * The integrity subsystem uses the same hooks as
  * the audit subsystem.
  */
-int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
+int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
+			 int lsmid)
 {
-	return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule);
+	return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule,
+			     lsmid);
 }
 
-void ima_filter_rule_free(void *lsmrule)
+void ima_filter_rule_free(void *lsmrule, int lsmid)
 {
-	call_void_hook(audit_rule_free, lsmrule);
+	call_void_hook(audit_rule_free, lsmrule, lsmid);
 }
 
-int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
+int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
+			  int lsmid)
 {
-	return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule);
+	return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule,
+			     lsmid);
 }
 #endif /* CONFIG_IMA_LSM_RULES */
 
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
index d5495134a5b9..59468baf0c91 100644
--- a/security/selinux/include/audit.h
+++ b/security/selinux/include/audit.h
@@ -21,21 +21,24 @@
  *	@op: the operator the rule uses
  *	@rulestr: the text "target" of the rule
  *	@rule: pointer to the new rule structure returned via this
+ *	@lsmid: the relevant LSM
  *
  *	Returns 0 if successful, -errno if not.  On success, the rule structure
  *	will be allocated internally.  The caller must free this structure with
  *	selinux_audit_rule_free() after use.
  */
-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule,
+			    int lsmid);
 
 /**
  *	selinux_audit_rule_free - free an selinux audit rule structure.
  *	@rule: pointer to the audit rule to be freed
+ *	@lsmid: which LSM this rule relates to
  *
  *	This will free all memory associated with the given rule.
  *	If @rule is NULL, no operation is performed.
  */
-void selinux_audit_rule_free(void *rule);
+void selinux_audit_rule_free(void *rule, int lsmid);
 
 /**
  *	selinux_audit_rule_match - determine if a context ID matches a rule.
@@ -43,11 +46,12 @@ void selinux_audit_rule_free(void *rule);
  *	@field: the field this rule refers to
  *	@op: the operator the rule uses
  *	@rule: pointer to the audit rule to check against
+ *	@lsmid: the relevant LSM
  *
  *	Returns 1 if the context id matches the rule, 0 if it does not, and
  *	-errno on failure.
  */
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
+int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, int lsmid);
 
 /**
  *	selinux_audit_rule_known - check to see if rule contains selinux fields.
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 1eeffc66ea7d..a9fe8d85acae 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3487,17 +3487,20 @@ struct selinux_audit_rule {
 	struct context au_ctxt;
 };
 
-void selinux_audit_rule_free(void *vrule)
+void selinux_audit_rule_free(void *vrule, int lsmid)
 {
 	struct selinux_audit_rule *rule = vrule;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
+		return;
 	if (rule) {
 		context_destroy(&rule->au_ctxt);
 		kfree(rule);
 	}
 }
 
-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+			    int lsmid)
 {
 	struct selinux_state *state = &selinux_state;
 	struct selinux_policy *policy;
@@ -3511,6 +3514,8 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 
 	*rule = NULL;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
+		return 0;
 	if (!selinux_initialized())
 		return -EOPNOTSUPP;
 
@@ -3592,7 +3597,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 
 err:
 	rcu_read_unlock();
-	selinux_audit_rule_free(tmprule);
+	selinux_audit_rule_free(tmprule, LSM_ID_SELINUX);
 	*rule = NULL;
 	return rc;
 }
@@ -3622,7 +3627,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
 	return 0;
 }
 
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
+int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid)
 {
 	struct selinux_state *state = &selinux_state;
 	struct selinux_policy *policy;
@@ -3631,6 +3636,8 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
 	struct selinux_audit_rule *rule = vrule;
 	int match = 0;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
+		return 0;
 	if (unlikely(!rule)) {
 		WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n");
 		return -ENOENT;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index cd44f7f3f393..4342947f51d8 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4672,16 +4672,20 @@ static int smack_post_notification(const struct cred *w_cred,
  * @op: required testing operator (=, !=, >, <, ...)
  * @rulestr: smack label to be audited
  * @vrule: pointer to save our own audit rule representation
+ * @lsmid: the relevant LSM
  *
  * Prepare to audit cases where (@field @op @rulestr) is true.
  * The label to be audited is created if necessay.
  */
-static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+				 int lsmid)
 {
 	struct smack_known *skp;
 	char **rule = (char **)vrule;
 	*rule = NULL;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SMACK)
+		return 0;
 	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
 		return -EINVAL;
 
@@ -4726,15 +4730,19 @@ static int smack_audit_rule_known(struct audit_krule *krule)
  * @field: audit rule flags given from user-space
  * @op: required testing operator
  * @vrule: smack internal rule presentation
+ * @lsmid: the relevant LSM
  *
  * The core Audit hook. It's used to take the decision of
  * whether to audit or not to audit a given object.
  */
-static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
+static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
+				  int lsmid)
 {
 	struct smack_known *skp;
 	char *rule = vrule;
 
+	if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SMACK)
+		return 0;
 	if (unlikely(!rule)) {
 		WARN_ONCE(1, "Smack: missing rule\n");
 		return -ENOENT;
-- 
2.41.0


  parent reply	other threads:[~2023-12-15 22:19 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20231215221636.105680-1-casey.ref@schaufler-ca.com>
2023-12-15 22:15 ` [PATCH v39 00/42] LSM: General module stacking Casey Schaufler
2023-12-15 22:15   ` [PATCH v39 01/42] integrity: disassociate ima_filter_rule from security_audit_rule Casey Schaufler
2024-03-06  9:54     ` Roberto Sassu
2024-03-06 16:56       ` Casey Schaufler
2024-03-07  7:56         ` Roberto Sassu
2023-12-15 22:15   ` [PATCH v39 02/42] SM: Infrastructure management of the sock security Casey Schaufler
2023-12-15 22:15   ` [PATCH v39 03/42] LSM: Add the lsmblob data structure Casey Schaufler
2023-12-15 22:15   ` Casey Schaufler [this message]
2024-03-06 10:09     ` [PATCH v39 04/42] IMA: avoid label collisions with stacked LSMs Roberto Sassu
2024-03-06 17:04       ` Casey Schaufler
2024-03-07  8:15         ` Roberto Sassu
2024-03-07 17:36           ` Casey Schaufler
2023-12-15 22:15   ` [PATCH v39 05/42] LSM: Use lsmblob in security_audit_rule_match Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 06/42] LSM: Add lsmblob_to_secctx hook Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 07/42] Audit: maintain an lsmblob in audit_context Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 08/42] LSM: Use lsmblob in security_ipc_getsecid Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 09/42] Audit: Update shutdown LSM data Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 10/42] LSM: Use lsmblob in security_current_getsecid Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 11/42] LSM: Use lsmblob in security_inode_getsecid Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 12/42] Audit: use an lsmblob in audit_names Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 13/42] LSM: Create new security_cred_getlsmblob LSM hook Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 14/42] Audit: Change context data from secid to lsmblob Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 15/42] Netlabel: Use lsmblob for audit data Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 16/42] LSM: Ensure the correct LSM context releaser Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 17/42] LSM: Use lsmcontext in security_secid_to_secctx Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 18/42] LSM: Use lsmcontext in security_lsmblob_to_secctx Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 19/42] LSM: Use lsmcontext in security_inode_getsecctx Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 20/42] LSM: Use lsmcontext in security_dentry_init_security Casey Schaufler
2023-12-18  2:50     ` Xiubo Li
2023-12-18 16:55       ` Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 21/42] LSM: security_lsmblob_to_secctx module selection Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 22/42] Audit: Create audit_stamp structure Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 23/42] Audit: Allow multiple records in an audit_buffer Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 24/42] Audit: Add record for multiple task security contexts Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 25/42] audit: multiple subject lsm values for netlabel Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 26/42] Audit: Add record for multiple object contexts Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 27/42] LSM: Remove unused lsmcontext_init() Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 28/42] LSM: Improve logic in security_getprocattr Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 29/42] LSM: secctx provider check on release Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 30/42] LSM: Single calls in socket_getpeersec hooks Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 31/42] LSM: Exclusive secmark usage Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 32/42] LSM: Identify which LSM handles the context string Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 33/42] AppArmor: Remove the exclusive flag Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 34/42] LSM: Add mount opts blob size tracking Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 35/42] LSM: allocate mnt_opts blobs instead of module specific data Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 36/42] LSM: Infrastructure management of the key security blob Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 37/42] LSM: Infrastructure management of the mnt_opts " Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 38/42] LSM: Correct handling of ENOSYS in inode_setxattr Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 39/42] LSM: Remove lsmblob scaffolding Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 40/42] LSM: Allow reservation of netlabel Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 41/42] LSM: restrict security_cred_getsecid() to a single LSM Casey Schaufler
2023-12-15 22:16   ` [PATCH v39 42/42] Smack: Remove LSM_FLAG_EXCLUSIVE Casey Schaufler
2023-12-18  2:18     ` Leesoo Ahn
2024-02-02  0:24   ` [PATCH v39 00/42] LSM: General module stacking John Johansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231215221636.105680-5-casey@schaufler-ca.com \
    --to=casey@schaufler-ca.com \
    --cc=jmorris@namei.org \
    --cc=john.johansen@canonical.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    --cc=serge@hallyn.com \
    --cc=stephen.smalley.work@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.