All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Cashman <dcashman@android.com>
To: selinux@tycho.nsa.gov
Cc: jwcart2@tycho.nsa.gov, jeffv@google.com, sds@tycho.nsa.gov,
	dcashman <dcashman@android.com>
Subject: [PATCH] libsepol: cil: cil_strpool: Allow multiple strpool users.
Date: Tue, 18 Oct 2016 14:31:51 -0700	[thread overview]
Message-ID: <1476826311-31992-1-git-send-email-dcashman@android.com> (raw)

From: dcashman <dcashman@android.com>

cil_strpool currently provides an interface to a statically stored
global data structure.  This interface does not accomodate multiple
consumers, however, as two calls to cil_strpool_init() will lead to a
memory leak and a call to cil_strpool_destroy() by one consumer will
remove data from use by others, and subsequently lead to a segfault on
the next cil_strpool_destroy() invocation.

Add a reference counter so that the strpool is only initialized once and
protect the exported interface with a mutex.

Tested by calling cil_db_init() on two cil_dbs and then calling
cil_db_destroy() on each.

Signed-off-by: Daniel Cashman <dcashman@android.com>
---
 libsepol/cil/src/cil_strpool.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c
index ad2a334..5b7df8c 100644
--- a/libsepol/cil/src/cil_strpool.c
+++ b/libsepol/cil/src/cil_strpool.c
@@ -27,6 +27,7 @@
  * either expressed or implied, of Tresys Technology, LLC.
  */
 
+#include <pthread.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -40,6 +41,8 @@ struct cil_strpool_entry {
 	char *str;
 };
 
+static pthread_mutex_t cil_strpool_mutex = PTHREAD_MUTEX_INITIALIZER;
+static unsigned int cil_strpool_readers = 0;
 static hashtab_t cil_strpool_tab = NULL;
 
 static unsigned int cil_strpool_hash(hashtab_t h, hashtab_key_t key)
@@ -68,16 +71,21 @@ char *cil_strpool_add(const char *str)
 {
 	struct cil_strpool_entry *strpool_ref = NULL;
 
+	pthread_mutex_lock(&cil_strpool_mutex);
+
 	strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str);
 	if (strpool_ref == NULL) {
 		strpool_ref = cil_malloc(sizeof(*strpool_ref));
 		strpool_ref->str = cil_strdup(str);
 		int rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref);
 		if (rc != SEPOL_OK) {
+			pthread_mutex_unlock(&cil_strpool_mutex);
 			(*cil_mem_error_handler)();
+			pthread_mutex_lock(&cil_strpool_mutex);
 		}
 	}
 
+	pthread_mutex_unlock(&cil_strpool_mutex);
 	return strpool_ref->str;
 }
 
@@ -91,14 +99,26 @@ static int cil_strpool_entry_destroy(hashtab_key_t k __attribute__ ((unused)), h
 
 void cil_strpool_init(void)
 {
-	cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE);
+	pthread_mutex_lock(&cil_strpool_mutex);
 	if (cil_strpool_tab == NULL) {
-		(*cil_mem_error_handler)();
+		cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE);
+		if (cil_strpool_tab == NULL) {
+			pthread_mutex_unlock(&cil_strpool_mutex);
+			(*cil_mem_error_handler)();
+			return;
+		}
 	}
+	cil_strpool_readers++;
+	pthread_mutex_unlock(&cil_strpool_mutex);
 }
 
 void cil_strpool_destroy(void)
 {
-	hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL);
-	hashtab_destroy(cil_strpool_tab);
+	pthread_mutex_lock(&cil_strpool_mutex);
+	cil_strpool_readers--;
+	if (cil_strpool_readers == 0) {
+		hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL);
+		hashtab_destroy(cil_strpool_tab);
+	}
+	pthread_mutex_unlock(&cil_strpool_mutex);
 }
-- 
2.8.0.rc3.226.g39d4020

             reply	other threads:[~2016-10-18 21:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-18 21:31 Daniel Cashman [this message]
2016-10-19 14:50 ` [PATCH] libsepol: cil: cil_strpool: Allow multiple strpool users James Carter

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=1476826311-31992-1-git-send-email-dcashman@android.com \
    --to=dcashman@android.com \
    --cc=jeffv@google.com \
    --cc=jwcart2@tycho.nsa.gov \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    /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.