linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <krzysztof.struczynski@huawei.com>
To: <linux-integrity@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<containers@lists.linux-foundation.org>,
	<linux-security-module@vger.kernel.org>
Cc: <zohar@linux.ibm.com>, <stefanb@linux.vnet.ibm.com>,
	<sunyuqiong1988@gmail.com>, <mkayaalp@cs.binghamton.edu>,
	<dmitry.kasatkin@gmail.com>, <serge@hallyn.com>,
	<jmorris@namei.org>, <christian@brauner.io>,
	<silviu.vlasceanu@huawei.com>, <roberto.sassu@huawei.com>,
	Krzysztof Struczynski <krzysztof.struczynski@huawei.com>
Subject: [RFC PATCH 28/30] ima: Load per ima namespace x509 certificate
Date: Tue, 18 Aug 2020 17:42:28 +0200	[thread overview]
Message-ID: <20200818154230.14016-19-krzysztof.struczynski@huawei.com> (raw)
In-Reply-To: <20200818154230.14016-1-krzysztof.struczynski@huawei.com>

From: Krzysztof Struczynski <krzysztof.struczynski@huawei.com>

If configured, load the x509 certificate when the first process is
born into the new ima namespace. User can set the path to the
certificate by writing to the x509_for_children entry in the ima
securityfs.

Signed-off-by: Krzysztof Struczynski <krzysztof.struczynski@huawei.com>
---
 security/integrity/digsig.c     |  6 +--
 security/integrity/ima/ima_ns.c | 69 ++++++++++++++++++++++++++++-----
 security/integrity/integrity.h  |  2 +-
 3 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 523fc786c4d7..8cd54bc83892 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -170,8 +170,8 @@ int __init integrity_init_keyring(const unsigned int id)
 	return __integrity_init_keyring(id, perm, restriction);
 }
 
-int __init integrity_add_key(const unsigned int id, const void *data,
-			     off_t size, key_perm_t perm)
+int integrity_add_key(const unsigned int id, const void *data,
+		      off_t size, key_perm_t perm)
 {
 	key_ref_t key;
 	int rc = 0;
@@ -195,7 +195,7 @@ int __init integrity_add_key(const unsigned int id, const void *data,
 
 }
 
-int __init integrity_load_x509(const unsigned int id, const char *path)
+int integrity_load_x509(const unsigned int id, const char *path)
 {
 	void *data;
 	loff_t size;
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c
index 872dc6a96a96..11e1d896f603 100644
--- a/security/integrity/ima/ima_ns.c
+++ b/security/integrity/ima/ima_ns.c
@@ -48,6 +48,30 @@ static void dec_ima_namespaces(struct ucounts *ucounts)
 	return dec_ucount(ucounts, UCOUNT_IMA_NAMESPACES);
 }
 
+#ifdef CONFIG_IMA_LOAD_X509
+static int ima_ns_load_x509(struct ima_namespace *ima_ns)
+{
+	int res = 0;
+	int unset_flags =
+		ima_ns->policy_data->ima_policy_flag & IMA_APPRAISE;
+
+	if (!ima_ns->x509_path_for_children)
+		return res;
+
+	ima_ns->policy_data->ima_policy_flag &= ~unset_flags;
+	res = integrity_load_x509(INTEGRITY_KEYRING_IMA,
+				  ima_ns->x509_path_for_children);
+	ima_ns->policy_data->ima_policy_flag |= unset_flags;
+
+	return res;
+}
+#else
+static inline int ima_ns_load_x509(struct ima_namespace *ima_ns)
+{
+	return 0;
+}
+#endif
+
 static struct ima_namespace *ima_ns_alloc(void)
 {
 	struct ima_namespace *ima_ns;
@@ -365,6 +389,10 @@ static int imans_activate(struct ima_namespace *ima_ns)
 	if (res < 0)
 		goto out;
 
+	res = ima_ns_load_x509(ima_ns);
+	if (res < 0)
+		goto out;
+
 	ima_ns->frozen = true;
 
 	/* Set current last element as list's head */
@@ -388,6 +416,7 @@ static int imans_install(struct nsset *nsset, struct ns_common *new)
 	int res;
 	struct nsproxy *nsproxy = nsset->nsproxy;
 	struct ima_namespace *ns = to_ima_ns(new);
+	struct ima_namespace *old_ns = nsproxy->ima_ns;
 
 	if (!current_is_single_threaded())
 		return -EUSERS;
@@ -396,14 +425,24 @@ static int imans_install(struct nsset *nsset, struct ns_common *new)
 	    !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 
-	res = imans_activate(ns);
-	if (res)
-		return res;
-
 	get_ima_ns(ns);
-	put_ima_ns(nsproxy->ima_ns);
+	put_ima_ns(old_ns);
 	nsproxy->ima_ns = ns;
 
+	/* The activation has to take place, after attaching the new namespace
+	 * to the nsproxy. This is because one part of the activation process,
+	 * is loading the appraisal keys, which temporary disables appraisal in
+	 * the current ima namespace, and it must not happen for the "old" ima
+	 * namespace.
+	 */
+	res = imans_activate(ns);
+	if (res) {
+		get_ima_ns(old_ns);
+		put_ima_ns(ns);
+		nsproxy->ima_ns = old_ns;
+		return res;
+	}
+
 	get_ima_ns(ns);
 	put_ima_ns(nsproxy->ima_ns_for_children);
 	nsproxy->ima_ns_for_children = ns;
@@ -416,6 +455,7 @@ int imans_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk,
 {
 	int res;
 	struct ima_namespace *ima_ns = nsproxy->ima_ns_for_children;
+	struct ima_namespace *old_ima_ns = nsproxy->ima_ns;
 
 	/* create_new_namespaces() already incremented the ref counter */
 	if (nsproxy->ima_ns == ima_ns)
@@ -431,14 +471,23 @@ int imans_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk,
 			return res;
 	}
 
-	res = imans_activate(ima_ns);
-	if (res)
-		return res;
-
 	get_ima_ns(ima_ns);
-	put_ima_ns(nsproxy->ima_ns);
+	put_ima_ns(old_ima_ns);
 	nsproxy->ima_ns = ima_ns;
 
+	/* The activation has to take place, after attaching the new namespace
+	 * to the nsproxy. This is because one part of the activation process,
+	 * is loading the appraisal keys, which temporary disables appraisal in
+	 * the current ima namespace, and it must not happen for the "old" ima
+	 * namespace.
+	 */
+	res = imans_activate(ima_ns);
+	if (res) {
+		get_ima_ns(old_ima_ns);
+		put_ima_ns(ima_ns);
+		nsproxy->ima_ns = old_ima_ns;
+	}
+
 	return res;
 }
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 207a1aef28e4..9b080b9fe242 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -179,7 +179,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 int integrity_modsig_verify(unsigned int id, const struct modsig *modsig);
 
 int __init integrity_init_keyring(const unsigned int id);
-int __init integrity_load_x509(const unsigned int id, const char *path);
+int integrity_load_x509(const unsigned int id, const char *path);
 int __init integrity_load_cert(const unsigned int id, const char *source,
 			       const void *data, size_t len, key_perm_t perm);
 #else
-- 
2.20.1


  parent reply	other threads:[~2020-08-18 15:51 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-18 15:42 [RFC PATCH 10/30] ima: Add ima namespace ID to the ima ML related structures krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 11/30] ima: Keep track of the measurment list per ima namespace krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 12/30] ima: Check ima namespace ID during digest entry lookup krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 13/30] ima: Add a new ima template that includes namespace ID krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 14/30] ima: Add per namespace view of the measurement list krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 15/30] ima: Add a reader counter to the integrity inode data krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 16/30] ima: Extend permissions to the ima securityfs entries krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 17/30] ima: Add the violation counter to the namespace krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 18/30] ima: Change the owning user namespace of the ima namespace if necessary krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 19/30] ima: Configure the new ima namespace from securityfs krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 20/30] ima: Parse per ima namespace policy file krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 21/30] user namespace: Add function that checks if the UID map is defined krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 22/30] ima: Remap IDs of subject based rules if necessary krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 23/30] keys: Add domain tag to the keyring search criteria krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 24/30] keys: Include key domain tag in the iterative search krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 25/30] keys: Allow to set key domain tag separately from the key type krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 26/30] ima: Add key domain to the ima namespace krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 27/30] integrity: Add key domain tag to the search criteria krzysztof.struczynski
2020-08-18 15:42 ` krzysztof.struczynski [this message]
2020-08-18 15:42 ` [RFC PATCH 29/30] ima: Add dummy boot aggregate to per ima namespace measurement list krzysztof.struczynski
2020-08-18 15:42 ` [RFC PATCH 30/30] ima: Set ML template per ima namespace krzysztof.struczynski

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=20200818154230.14016-19-krzysztof.struczynski@huawei.com \
    --to=krzysztof.struczynski@huawei.com \
    --cc=christian@brauner.io \
    --cc=containers@lists.linux-foundation.org \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=jmorris@namei.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mkayaalp@cs.binghamton.edu \
    --cc=roberto.sassu@huawei.com \
    --cc=serge@hallyn.com \
    --cc=silviu.vlasceanu@huawei.com \
    --cc=stefanb@linux.vnet.ibm.com \
    --cc=sunyuqiong1988@gmail.com \
    --cc=zohar@linux.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).