aboutsummaryrefslogtreecommitdiffstats
path: root/libselinux/src/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'libselinux/src/init.c')
-rw-r--r--libselinux/src/init.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/libselinux/src/init.c b/libselinux/src/init.c
new file mode 100644
index 00000000..9cdbb06e
--- /dev/null
+++ b/libselinux/src/init.c
@@ -0,0 +1,128 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <dlfcn.h>
+#include <sys/vfs.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include "dso.h"
+#include "policy.h"
+#include "selinux_internal.h"
+#include "setrans_internal.h"
+
+char *selinux_mnt = NULL;
+int selinux_page_size = 0;
+int obj_class_compat = 1;
+
+static void init_selinuxmnt(void)
+{
+ char *buf=NULL, *p;
+ FILE *fp;
+ struct statfs sfbuf;
+ int rc;
+ size_t len;
+ ssize_t num;
+
+ if (selinux_mnt)
+ return;
+
+ /* We check to see if the preferred mount point for selinux file
+ * system has a selinuxfs. */
+ do {
+ rc = statfs(SELINUXMNT, &sfbuf);
+ } while (rc < 0 && errno == EINTR);
+ if (rc == 0) {
+ if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
+ selinux_mnt = strdup(SELINUXMNT);
+ return;
+ }
+ }
+
+ /* At this point, the usual spot doesn't have an selinuxfs so
+ * we look around for it */
+ fp = fopen("/proc/mounts", "r");
+ if (!fp)
+ return;
+
+ __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ while ((num = getline(&buf, &len, fp)) != -1) {
+ char *tmp;
+ p = strchr(buf, ' ');
+ if (!p)
+ goto out;
+ p++;
+ tmp = strchr(p, ' ');
+ if (!tmp)
+ goto out;
+ if (!strncmp(tmp + 1, "selinuxfs ", 10)) {
+ *tmp = '\0';
+ break;
+ }
+ }
+
+ /* If we found something, dup it */
+ if (num > 0)
+ selinux_mnt = strdup(p);
+
+ out:
+ free(buf);
+ fclose(fp);
+ return;
+}
+
+static void fini_selinuxmnt(void)
+{
+ free(selinux_mnt);
+ selinux_mnt = NULL;
+}
+
+void set_selinuxmnt(char *mnt)
+{
+ selinux_mnt = strdup(mnt);
+}
+
+hidden_def(set_selinuxmnt)
+
+static void init_obj_class_compat(void)
+{
+ char path[PATH_MAX];
+ struct stat s;
+
+ if (!selinux_mnt)
+ return;
+
+ snprintf(path,PATH_MAX,"%s/class",selinux_mnt);
+ if (stat(path,&s) < 0)
+ return;
+
+ if (S_ISDIR(s.st_mode))
+ obj_class_compat = 0;
+}
+
+static void fini_obj_class_compat(void)
+{
+ obj_class_compat = 1;
+}
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+ selinux_page_size = sysconf(_SC_PAGE_SIZE);
+ init_selinuxmnt();
+ init_obj_class_compat();
+ init_context_translations();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+ fini_selinuxmnt();
+ fini_obj_class_compat();
+ fini_context_translations();
+}