All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian Göttsche" <cgzones@googlemail.com>
To: selinux@vger.kernel.org
Cc: Juraj Marcin <juraj@jurajmarcin.com>,
	Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <stephen.smalley.work@gmail.com>,
	Eric Paris <eparis@parisplace.org>,
	Ondrej Mosnacek <omosnace@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH] selinux: support name based type transitions in conditional policies
Date: Fri,  2 Jun 2023 15:54:26 +0200	[thread overview]
Message-ID: <20230602135427.33897-1-cgzones@googlemail.com> (raw)

With the move of name based type transitions to the avtab structure such
statements are candidate to be used in conditional policies.  They are
already read into the policy database (which might be seen as a mistake
as referencing them after a boolean change causes a use-after-free).

Copy the avtab_trans structures on boolean changes to keep them
available.

CC: Juraj Marcin <juraj@jurajmarcin.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
Based on patcheset by Juraj Marcin [1]

[1]: https://patchwork.kernel.org/project/selinux/list/?series=752711
---
 security/selinux/ss/avtab.c       |  2 +-
 security/selinux/ss/avtab.h       |  2 +
 security/selinux/ss/conditional.c | 96 ++++++++++++++++++++++++++++---
 3 files changed, 92 insertions(+), 8 deletions(-)

diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index d3c027e5c0da..8068c9b4d1e6 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -297,7 +297,7 @@ static int avtab_trans_destroy_helper(void *k, void *d, void *args)
 	return 0;
 }
 
-static void avtab_trans_destroy(struct avtab_trans *trans)
+void avtab_trans_destroy(struct avtab_trans *trans)
 {
 	hashtab_map(&trans->name_trans.table, avtab_trans_destroy_helper, NULL);
 	hashtab_destroy(&trans->name_trans.table);
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 929e322715d1..eb19d7719b72 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -125,6 +125,8 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
 #define MAX_AVTAB_HASH_BITS 16
 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
 
+void avtab_trans_destroy(struct avtab_trans *trans);
+
 /* policydb filename transitions compatibility */
 
 int avtab_filename_trans_read(struct avtab *a, void *fp, struct policydb *p);
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 91392d65563e..48b162dca3f5 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -605,11 +605,36 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
 	}
 }
 
+static int cond_avtab_trans_destroy_helper(void *k, void *d, __always_unused void *args)
+{
+	kfree(k);
+	kfree(d);
+	return 0;
+}
+
+static int cond_avtab_trans_copy(struct hashtab_node *new, const struct hashtab_node *orig,
+				 __always_unused void *args)
+{
+	new->key = kstrdup(orig->key, GFP_KERNEL);
+	if (!new->key)
+		return -ENOMEM;
+
+	new->datum = kmemdup(orig->datum, sizeof(u32), GFP_KERNEL);
+	if (!new->datum) {
+		kfree(new->key);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static int cond_dup_av_list(struct cond_av_list *new,
-			struct cond_av_list *orig,
-			struct avtab *avtab)
+			const struct cond_av_list *orig,
+			struct avtab *avtab,
+			const struct policydb *origp)
 {
 	u32 i;
+	int rc;
 
 	memset(new, 0, sizeof(*new));
 
@@ -618,9 +643,66 @@ static int cond_dup_av_list(struct cond_av_list *new,
 		return -ENOMEM;
 
 	for (i = 0; i < orig->len; i++) {
-		new->nodes[i] = avtab_insert_nonunique(avtab,
-						       &orig->nodes[i]->key,
-						       &orig->nodes[i]->datum);
+		const struct avtab_key *orig_key = &orig->nodes[i]->key;
+		struct avtab_datum datum = orig->nodes[i]->datum;
+
+		if (origp->policyvers >= POLICYDB_VERSION_AVTAB_FTRANS &&
+		    (orig_key->specified & AVTAB_TRANSITION)) {
+			struct avtab_trans trans = {
+				.otype = datum.u.trans->otype,
+			};
+
+			rc = symtab_init(&trans.name_trans,
+					 datum.u.trans->name_trans.table.nel);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+			rc = symtab_init(&trans.prefix_trans,
+					 datum.u.trans->prefix_trans.table.nel);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+			rc = symtab_init(&trans.suffix_trans,
+					 datum.u.trans->suffix_trans.table.nel);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+
+			rc = hashtab_duplicate(&trans.name_trans.table,
+					       &datum.u.trans->name_trans.table,
+					       cond_avtab_trans_copy,
+					       cond_avtab_trans_destroy_helper,
+					       NULL);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+			rc = hashtab_duplicate(&trans.prefix_trans.table,
+					       &datum.u.trans->prefix_trans.table,
+					       cond_avtab_trans_copy,
+					       cond_avtab_trans_destroy_helper,
+					       NULL);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+			rc = hashtab_duplicate(&trans.suffix_trans.table,
+					       &datum.u.trans->suffix_trans.table,
+					       cond_avtab_trans_copy,
+					       cond_avtab_trans_destroy_helper,
+					       NULL);
+			if (rc) {
+				avtab_trans_destroy(&trans);
+				return rc;
+			}
+
+			datum.u.trans = &trans;
+		}
+
+		new->nodes[i] = avtab_insert_nonunique(avtab, orig_key, &datum);
 		if (!new->nodes[i])
 			return -ENOMEM;
 		new->len++;
@@ -662,12 +744,12 @@ static int duplicate_policydb_cond_list(struct policydb *newp,
 		newn->expr.len = orign->expr.len;
 
 		rc = cond_dup_av_list(&newn->true_list, &orign->true_list,
-				&newp->te_cond_avtab);
+				&newp->te_cond_avtab, origp);
 		if (rc)
 			goto error;
 
 		rc = cond_dup_av_list(&newn->false_list, &orign->false_list,
-				&newp->te_cond_avtab);
+				&newp->te_cond_avtab, origp);
 		if (rc)
 			goto error;
 	}
-- 
2.40.1


                 reply	other threads:[~2023-06-02 13:55 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20230602135427.33897-1-cgzones@googlemail.com \
    --to=cgzones@googlemail.com \
    --cc=eparis@parisplace.org \
    --cc=juraj@jurajmarcin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=omosnace@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=selinux@vger.kernel.org \
    --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.