All of lore.kernel.org
 help / color / mirror / Atom feed
From: Purushottam Choudhary <purushottamchoudhary29@gmail.com>
To: selinux@vger.kernel.org
Cc: ranjitsinh.rathod@kpit.com,
	purushottam Choudhary <purushottamchoudhary29@gmail.com>
Subject: [libselinux][PATCH] libselinux: make threadsafe for discover_class_cache
Date: Thu, 20 Jan 2022 13:03:29 +0530	[thread overview]
Message-ID: <20220120073329.15234-1-purushottamchoudhary29@gmail.com> (raw)

From: purushottam Choudhary <purushottamchoudhary29@gmail.com>

Crash is observed in process dbus-daemon while accessing name
from discover_class_cache structure variable,
discover_class_cache->name vairable found NULL
during backtrace analysis.
Add mutex lock for the discover_class_cache to handle multiple
threads for the function which uses discover_class_cache
This avoids variable corruption during parallel access
in the multiple thread environment.

Signed-off-by: Purushottam Choudhary <purushottamchoudhary29@gmail.com>
---
 libselinux/src/avc.c       |  7 +++++--
 libselinux/src/stringrep.c | 24 ++++++++++++++++++------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c
index 7493e4b2..4fbaa30d 100644
--- a/libselinux/src/avc.c
+++ b/libselinux/src/avc.c
@@ -685,8 +685,11 @@ static void avc_dump_query(security_id_t ssid, security_id_t tsid,
 		   ssid->ctx, tsid->ctx);
 
 	avc_release_lock(avc_lock);
-	log_append(avc_audit_buf, " tclass=%s",
-		   security_class_to_string(tclass));
+	char *tclass_name = security_class_to_string(tclass);
+	log_append(avc_audit_buf, " tclass=%s", tclass_name);
+	if (tclass_name != NULL) {
+		free(tclass_name);
+	}
 }
 
 void avc_audit(security_id_t ssid, security_id_t tsid,
diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c
index 2fe69f43..52ae3f2d 100644
--- a/libselinux/src/stringrep.c
+++ b/libselinux/src/stringrep.c
@@ -19,6 +19,7 @@
 
 #define MAXVECTORS 8*sizeof(access_vector_t)
 
+pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER;
 struct discover_class_node {
 	char *name;
 	security_class_t value;
@@ -140,9 +141,10 @@ static struct discover_class_node * discover_class(const char *s)
 	}
 	closedir(dir);
 
+	__pthread_mutex_lock(&cache_mutex);
 	node->next = discover_class_cache;
 	discover_class_cache = node;
-
+	__pthread_mutex_unlock(&cache_mutex);
 	return node;
 
 err4:
@@ -160,6 +162,7 @@ err1:
 
 void selinux_flush_class_cache(void)
 {
+	__pthread_mutex_lock(&cache_mutex);
 	struct discover_class_node *cur = discover_class_cache, *prev = NULL;
 	size_t i;
 
@@ -178,6 +181,7 @@ void selinux_flush_class_cache(void)
 	}
 
 	discover_class_cache = NULL;
+	__pthread_mutex_unlock(&cache_mutex);
 }
 
 
@@ -185,6 +189,7 @@ security_class_t string_to_security_class(const char *s)
 {
 	struct discover_class_node *node;
 
+	__pthread_mutex_lock(&cache_mutex);
 	node = get_class_cache_entry_name(s);
 	if (node == NULL) {
 		node = discover_class(s);
@@ -195,7 +200,9 @@ security_class_t string_to_security_class(const char *s)
 		}
 	}
 
-	return map_class(node->value);
+	security_class_t ret_value = map_class(node->name);
+	__pthread_mutex_unlock(&cache_mutex);
+	return ret_value;
 }
 
 security_class_t mode_to_security_class(mode_t m) {
@@ -224,6 +231,7 @@ access_vector_t string_to_av_perm(security_class_t tclass, const char *s)
 	struct discover_class_node *node;
 	security_class_t kclass = unmap_class(tclass);
 
+	__pthread_mutex_lock(&cache_mutex);
 	node = get_class_cache_entry_value(kclass);
 	if (node != NULL) {
 		size_t i;
@@ -233,6 +241,7 @@ access_vector_t string_to_av_perm(security_class_t tclass, const char *s)
 	}
 
 	errno = EINVAL;
+	__pthread_mutex_unlock(&cache_mutex);
 	return 0;
 }
 
@@ -242,11 +251,14 @@ const char *security_class_to_string(security_class_t tclass)
 
 	tclass = unmap_class(tclass);
 
+	__pthread_mutex_lock(&cache_mutex);
+	char *node_name = NULL;
 	node = get_class_cache_entry_value(tclass);
-	if (node == NULL)
-		return NULL;
-	else
-		return node->name;
+	if (node != NULL) {
+		node_name = strdup(node->name);
+	}
+	__pthread_mutex_unlock(&cache_mutex);
+	return node_name;
 }
 
 const char *security_av_perm_to_string(security_class_t tclass,
-- 
2.17.1


                 reply	other threads:[~2022-01-20  7:33 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=20220120073329.15234-1-purushottamchoudhary29@gmail.com \
    --to=purushottamchoudhary29@gmail.com \
    --cc=ranjitsinh.rathod@kpit.com \
    --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.