aboutsummaryrefslogtreecommitdiffstats
path: root/libselinux/src/selinux_config.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2009-07-01 13:45:40 -0400
committerStephen Smalley <sds@tycho.nsa.gov>2009-07-14 10:55:34 -0400
commit8c372f665db44cf753bb299e2ee7dcf6143b9e9e (patch)
treee952589afb3633a7a216dd0adaf0eaf4278ac712 /libselinux/src/selinux_config.c
parent1ac1ff6382505fa1e245fdc9c91b2448a7843101 (diff)
downloadandroid_external_selinux-8c372f665db44cf753bb299e2ee7dcf6143b9e9e.tar.gz
android_external_selinux-8c372f665db44cf753bb299e2ee7dcf6143b9e9e.tar.bz2
android_external_selinux-8c372f665db44cf753bb299e2ee7dcf6143b9e9e.zip
libselinux: lazy init
Revive Steve Grubb's patch for libselinux lazy init and extend it to address not only the reading of /etc/selinux/config but also probing for /selinux/class and reading of /selinux/mls. This should reduce the need for dontaudit rules for programs that link with libselinux and it should reduce unnecessary overhead. I did not convert init_selinuxmnt over to lazy init since the functions that use selinux_mnt are not localized, and it only requires stat'ing of /selinux in the common case. I couldn't see a valid reason why we needed fini_obj_class_compat(), as the existence of /selinux/class will only change across a reboot with different kernel versions. fini_context_translations() already had a comment saying that it was unnecessary as well. Before: $ strace ls 2> err $ grep selinux err open("/lib/libselinux.so.1", O_RDONLY) = 3 open("/etc/selinux/config", O_RDONLY|O_LARGEFILE) = 3 statfs64("/selinux", 84, {f_type=0xf97cff8c, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0 stat64("/selinux/class", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 open("/selinux/mls", O_RDONLY|O_LARGEFILE) = 3 After: $ strace ls 2> err $ grep selinux err open("/lib/libselinux.so.1", O_RDONLY) = 3 statfs64("/selinux", 84, {f_type=0xf97cff8c, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0 Original-patch-by: Steve Grubb <linux_4ever@yahoo.com> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Diffstat (limited to 'libselinux/src/selinux_config.c')
-rw-r--r--libselinux/src/selinux_config.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c
index 48cb9712..af8731c5 100644
--- a/libselinux/src/selinux_config.c
+++ b/libselinux/src/selinux_config.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
+#include <pthread.h>
#include "selinux_internal.h"
#include "get_default_type_internal.h"
@@ -45,6 +46,10 @@
#define FILE_CONTEXT_SUBS 23
#define NEL 24
+/* Part of one-time lazy init */
+static pthread_once_t once = PTHREAD_ONCE_INIT;
+static void init_selinux_config(void);
+
/* New layout is relative to SELINUXDIR/policytype. */
static char *file_paths[NEL];
#define L1(l) L2(l)
@@ -120,6 +125,7 @@ static char *selinux_policytype;
int selinux_getpolicytype(char **type)
{
+ __selinux_once(once, init_selinux_config);
if (!selinux_policytype)
return -1;
*type = strdup(selinux_policytype);
@@ -129,9 +135,7 @@ int selinux_getpolicytype(char **type)
hidden_def(selinux_getpolicytype)
static char *selinux_policyroot = NULL;
-static char *selinux_rootpath = NULL;
-
-static void init_selinux_config(void) __attribute__ ((constructor));
+static const char *selinux_rootpath = SELINUXDIR;
static void init_selinux_config(void)
{
@@ -144,7 +148,6 @@ static void init_selinux_config(void)
if (selinux_policyroot)
return;
- selinux_rootpath = SELINUXDIR;
fp = fopen(SELINUXCONFIG, "r");
if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER);
@@ -235,6 +238,7 @@ void reset_selinux_config(void)
static const char *get_path(int idx)
{
+ __selinux_once(once, init_selinux_config);
return file_paths[idx];
}
@@ -247,6 +251,7 @@ hidden_def(selinux_default_type_path)
const char *selinux_policy_root()
{
+ __selinux_once(once, init_selinux_config);
return selinux_policyroot;
}