linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Micah Morton <mortonm@chromium.org>
To: jmorris@namei.org, keescook@chromium.org, casey@schaufler-ca.com,
	linux-security-module@vger.kernel.org
Cc: Jann Horn <jannh@google.com>, Micah Morton <mortonm@chromium.org>
Subject: [PATCH 08/10] LSM: SafeSetID: add read handler
Date: Wed, 10 Apr 2019 09:56:13 -0700	[thread overview]
Message-ID: <20190410165613.212056-1-mortonm@chromium.org> (raw)

From: Jann Horn <jannh@google.com>

For debugging a running system, it is very helpful to be able to see what
policy the system is using. Add a read handler that can dump out a copy of
the loaded policy.

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Micah Morton <mortonm@chromium.org>
---
 security/safesetid/lsm.h        |  3 +++
 security/safesetid/securityfs.c | 38 +++++++++++++++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/security/safesetid/lsm.h b/security/safesetid/lsm.h
index 4a34f558d964..9380329fe30a 100644
--- a/security/safesetid/lsm.h
+++ b/security/safesetid/lsm.h
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/uidgid.h>
 #include <linux/hashtable.h>
+#include <linux/refcount.h>
 
 /* Flag indicating whether initialization completed */
 extern int safesetid_initialized;
@@ -41,7 +42,9 @@ struct setuid_rule {
 
 struct setuid_ruleset {
 	DECLARE_HASHTABLE(rules, SETID_HASH_BITS);
+	char *policy_str;
 	struct rcu_head rcu;
+	refcount_t refcount;
 };
 
 enum sid_policy_type _setuid_policy_lookup(struct setuid_ruleset *policy,
diff --git a/security/safesetid/securityfs.c b/security/safesetid/securityfs.c
index 13fce4c10930..7a08fff2bc14 100644
--- a/security/safesetid/securityfs.c
+++ b/security/safesetid/securityfs.c
@@ -67,12 +67,14 @@ static void __release_ruleset(struct rcu_head *rcu)
 
 	hash_for_each_safe(pol->rules, bucket, tmp, rule, next)
 		kfree(rule);
+	kfree(pol->policy_str);
 	kfree(pol);
 }
 
 static void release_ruleset(struct setuid_ruleset *pol)
 {
-	call_rcu(&pol->rcu, __release_ruleset);
+	if (pol != NULL && refcount_dec_and_test(&pol->refcount))
+		call_rcu(&pol->rcu, __release_ruleset);
 }
 
 static ssize_t handle_policy_update(struct file *file,
@@ -85,6 +87,8 @@ static ssize_t handle_policy_update(struct file *file,
 	pol = kmalloc(sizeof(struct setuid_ruleset), GFP_KERNEL);
 	if (!pol)
 		return -ENOMEM;
+	refcount_set(&pol->refcount, 1);
+	pol->policy_str = NULL;
 	hash_init(pol->rules);
 
 	p = buf = memdup_user_nul(ubuf, len);
@@ -92,6 +96,11 @@ static ssize_t handle_policy_update(struct file *file,
 		err = PTR_ERR(buf);
 		goto out_free_pol;
 	}
+	pol->policy_str = kstrdup(buf, GFP_KERNEL);
+	if (pol->policy_str == NULL) {
+		err = -ENOMEM;
+		goto out_free_buf;
+	}
 
 	/* policy lines, including the last one, end with \n */
 	while (*p != '\0') {
@@ -162,7 +171,32 @@ static ssize_t safesetid_file_write(struct file *file,
 	return handle_policy_update(file, buf, len);
 }
 
+static ssize_t safesetid_file_read(struct file *file, char __user *buf,
+				   size_t len, loff_t *ppos)
+{
+	ssize_t res;
+	struct setuid_ruleset *pol;
+	const char *kbuf;
+
+	rcu_read_lock();
+	pol = rcu_dereference(safesetid_setuid_rules);
+	if (!pol) {
+		rcu_read_unlock();
+		return 0;
+	}
+	if (!refcount_inc_not_zero(&pol->refcount)) {
+		rcu_read_unlock();
+		return -EBUSY;
+	}
+	rcu_read_unlock();
+	kbuf = pol->policy_str;
+	res = simple_read_from_buffer(buf, len, ppos, kbuf, strlen(kbuf));
+	release_ruleset(pol);
+	return res;
+}
+
 static const struct file_operations safesetid_file_fops = {
+	.read = safesetid_file_read,
 	.write = safesetid_file_write,
 };
 
@@ -181,7 +215,7 @@ static int __init safesetid_init_securityfs(void)
 		goto error;
 	}
 
-	policy_file = securityfs_create_file("whitelist_policy", 0200,
+	policy_file = securityfs_create_file("whitelist_policy", 0600,
 			policy_dir, NULL, &safesetid_file_fops);
 	if (IS_ERR(policy_file)) {
 		ret = PTR_ERR(policy_file);
-- 
2.21.0.392.gf8f6787159e-goog


             reply	other threads:[~2019-04-10 16:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-10 16:56 Micah Morton [this message]
2019-04-10 17:26 ` [PATCH 08/10] LSM: SafeSetID: add read handler Kees Cook
2019-04-10 17:42   ` Jann Horn

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=20190410165613.212056-1-mortonm@chromium.org \
    --to=mortonm@chromium.org \
    --cc=casey@schaufler-ca.com \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=linux-security-module@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 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).