All of lore.kernel.org
 help / color / mirror / Atom feed
From: Casey Schaufler <casey@schaufler-ca.com>
To: jmorris@namei.org, linux-security-module@vger.kernel.org,
	selinux@vger.kernel.org
Cc: keescook@chromium.org, john.johansen@canonical.com,
	penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com
Subject: [PATCH 76/97] LSM: Use full security context in security_inode_setsecctx
Date: Thu, 28 Feb 2019 14:43:35 -0800	[thread overview]
Message-ID: <20190228224356.2608-7-casey@schaufler-ca.com> (raw)
In-Reply-To: <20190228224356.2608-1-casey@schaufler-ca.com>

The security hooks security_inode_setsecctx and security_inode_getsecctx
need to maintain the context strings for any and all LSMs that
provide contexts. This information is internal to the kernel
and volitile. If only one LSM uses this information the raw form is
used.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 security/security.c | 110 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 2 deletions(-)

diff --git a/security/security.c b/security/security.c
index 16ff98c86414..bb0eea873a7e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -438,6 +438,9 @@ static int lsm_append(char *new, char **result)
 /* Base list of once-only hooks */
 struct lsm_one_hooks lsm_base_one;
 
+/* Count of inode_[gs]etsecctx hooks */
+static int lsm_inode_secctx_count;
+
 /**
  * security_add_hooks - Add a modules hooks to the hook lists.
  * @hooks: the hooks to add
@@ -455,6 +458,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
 		hooks[i].lsm = lsm;
 		hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
 
+		/*
+		 * Keep count of the internal security context using hooks.
+		 * Assume that there is a 1:1 mapping from inode_getsecctx
+		 * to inode_setsecctx in the security modules.
+		 */
+		if (hooks[i].head == &security_hook_heads.inode_getsecctx) {
+			lsm_inode_secctx_count++;
+			continue;
+		}
 		/*
 		 * Check for the special hooks that are restricted to
 		 * a single module to create the base set. Use the hooks
@@ -2162,15 +2174,109 @@ int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
 }
 EXPORT_SYMBOL(security_inode_notifysecctx);
 
+/*
+ * The inode_[gs]etsecctx functions need to proved a context
+ * for multiple security modules. If there is more than one
+ * LSM supplying hooks the format will be
+ *	lsm1='value',lsm2='value'[,lsmN='value']...
+ */
+static void lsm_release_secctx(struct lsm_context *cp)
+{
+	kfree(cp->context);
+}
+
 int security_inode_setsecctx(struct dentry *dentry, struct lsm_context *cp)
 {
-	return call_int_hook(inode_setsecctx, 0, dentry, cp);
+	struct security_hook_list *hp;
+	struct lsm_context lc;
+	char *full;
+	char *ctx;
+	char *quote;
+	int rc = 0;
+
+	if (lsm_inode_secctx_count <= 1)
+		return call_int_hook(inode_setsecctx, 0, dentry, cp);
+
+	full = kstrndup(cp->context, cp->len, GFP_KERNEL);
+	if (full == NULL)
+		return -ENOMEM;
+
+	ctx = full;
+	hlist_for_each_entry(hp, &security_hook_heads.inode_setsecctx, list) {
+		if (strncmp(ctx, hp->lsm, strlen(hp->lsm))) {
+			WARN_ONCE(1, "security_inode_setsecctx form1 error\n");
+			rc = -EINVAL;
+			break;
+		}
+		ctx += strlen(hp->lsm);
+		if (ctx[0] != '=' || ctx[1] != '\'') {
+			WARN_ONCE(1, "security_inode_setsecctx form2 error\n");
+			rc = -EINVAL;
+			break;
+		}
+		ctx += 2;
+		quote = strnchr(ctx, cp->len, '\'');
+		if (quote == NULL) {
+			WARN_ONCE(1, "security_inode_setsecctx form3 error\n");
+			rc = -EINVAL;
+			break;
+		}
+		quote[0] = '\0';
+		if (quote[1] != ',' && quote[1] != '\0') {
+			WARN_ONCE(1, "security_inode_setsecctx form4 error\n");
+			rc = -EINVAL;
+			break;
+		}
+		lc.context = ctx;
+		lc.len = strlen(ctx);
+
+		ctx = quote + 2;
+
+		rc = hp->hook.inode_setsecctx(dentry, &lc);
+		if (rc)
+			break;
+	}
+
+	kfree(full);
+	return rc;
 }
 EXPORT_SYMBOL(security_inode_setsecctx);
 
 int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
 {
-	return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, cp);
+	struct security_hook_list *hp;
+	struct lsm_context lc;
+	char *final = NULL;
+	char *tp;
+	int rc;
+
+	if (lsm_inode_secctx_count <= 1)
+		return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, cp);
+
+	hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) {
+		rc = hp->hook.inode_getsecctx(inode, &lc);
+		if (rc) {
+			kfree(final);
+			return rc;
+		}
+		if (final) {
+			tp = kasprintf(GFP_KERNEL, "%s,%s='%s'", final,
+				       hp->lsm, lc.context);
+			kfree(final);
+		} else
+			tp = kasprintf(GFP_KERNEL, "%s='%s'", hp->lsm,
+				       lc.context);
+		security_release_secctx(&lc);
+		if (tp == NULL) {
+			kfree(final);
+			return -ENOMEM;
+		}
+		final = tp;
+	}
+	cp->context = final;
+	cp->len = strlen(final);
+	cp->release = lsm_release_secctx;
+	return 0;
 }
 EXPORT_SYMBOL(security_inode_getsecctx);
 
-- 
2.17.0


  parent reply	other threads:[~2019-02-28 22:44 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-28 22:43 [PATCH 00/97] LSM: Complete module stacking Casey Schaufler
2019-02-28 22:43 ` [PATCH 71/97] LSM: Add secmark refcounting to call_one list Casey Schaufler
2019-02-28 22:43 ` [PATCH 72/97] LSM: Add secmark refcounting to call_one list - part 2 Casey Schaufler
2019-02-28 22:43 ` [PATCH 73/97] LSM: refactor security_setprocattr Casey Schaufler
2019-02-28 22:43 ` [PATCH 74/97] Smack: Detect if secmarks can be safely used Casey Schaufler
2019-02-28 22:43 ` [PATCH 75/97] LSM: Support multiple LSMs using inode_init_security Casey Schaufler
2019-02-28 22:43 ` Casey Schaufler [this message]
2019-02-28 22:43 ` [PATCH 77/97] LSM: Correct handling of ENOSYS in inode_setxattr Casey Schaufler
2019-02-28 22:43 ` [PATCH 78/97] LSM: Infrastructure security blobs for mount options Casey Schaufler
2019-02-28 22:43 ` [PATCH 79/97] LSM: Fix for security_init_inode_security Casey Schaufler
2019-02-28 22:43 ` [PATCH 80/97] Smack: Advertise the secid to netlabel Casey Schaufler
2019-02-28 22:43 ` [PATCH 81/97] LSM: Change error detection for UDP peer security Casey Schaufler
2019-02-28 22:43 ` [PATCH 82/97] Smack: Fix setting of the CIPSO MLS_CAT flags Casey Schaufler
2019-02-28 22:43 ` [PATCH 83/97] Smack: Set netlabel flags properly on new label import Casey Schaufler
2019-02-28 22:43 ` [PATCH 84/97] Netlabel: Add a secattr comparison API function Casey Schaufler
2019-02-28 22:43 ` [PATCH 85/97] Smack: Let netlabel do the work on the ambient domain Casey Schaufler
2019-02-28 22:43 ` [PATCH 86/97] Smack: Don't set the socket label on each send Casey Schaufler
2019-02-28 22:43 ` [PATCH 87/97] Smack: Let netlabel do the work on connections Casey Schaufler
2019-02-28 22:43 ` [PATCH 88/97] Netlabel: Return the labeling type on socket Casey Schaufler
2019-02-28 22:43 ` [PATCH 89/97] " Casey Schaufler
2019-02-28 22:43 ` [PATCH 90/97] " Casey Schaufler
2019-02-28 22:43 ` [PATCH 91/97] " Casey Schaufler
2019-02-28 22:43 ` [PATCH 92/97] LSM: Remember the NLTYPE of netlabel sockets Casey Schaufler
2019-02-28 22:43 ` [PATCH 93/97] Smack: Use the NLTYPE on output Casey Schaufler
2019-02-28 22:43 ` [PATCH 94/97] LSM: Hook for netlabel reconciliation Casey Schaufler
2019-02-28 22:43 ` [PATCH 95/97] LSM: Avoid network conflicts in SELinux and Smack Casey Schaufler
2019-02-28 22:43 ` [PATCH 96/97] LSM: Apply Netlabel consitancy checks on send and connect Casey Schaufler
2019-02-28 22:43 ` [PATCH 97/97] Smack: Remove the exclusive bit Casey Schaufler

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=20190228224356.2608-7-casey@schaufler-ca.com \
    --to=casey@schaufler-ca.com \
    --cc=jmorris@namei.org \
    --cc=john.johansen@canonical.com \
    --cc=keescook@chromium.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    --cc=selinux@vger.kernel.org \
    /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.