diff options
Diffstat (limited to 'libselinux/src/init.c')
-rw-r--r-- | libselinux/src/init.c | 128 |
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(); +} |