diff -urp libselinux-2.0.4.orig/src/enabled.c libselinux-2.0.4/src/enabled.c --- libselinux-2.0.4.orig/src/enabled.c 2007-02-25 14:52:16.000000000 -0500 +++ libselinux-2.0.4/src/enabled.c 2007-02-26 11:18:14.000000000 -0500 @@ -10,46 +10,57 @@ int is_selinux_enabled(void) { - char *buf; - size_t size; - int fd; - ssize_t ret; + char *buf=NULL; + FILE *fp; + ssize_t num; + size_t len; int enabled = 0; security_context_t con; - fd = open("/proc/filesystems", O_RDONLY); - if (fd < 0) - return -1; - - size = selinux_page_size; - buf = malloc(size); - if (!buf) { - enabled = -1; - goto out; - } + /* init_selinuxmnt() gets called before this function. We + * will assume that if a selinux file system is mounted, then + * selinux is enabled. */ + if (selinux_mnt) { + + /* Since a file system is mounted, we consider selinux + * enabled. If getcon_raw fails, selinux is still enabled. + * We only consider it disabled if no policy is loaded. */ + enabled = 1; + if (getcon_raw(&con) == 0) { + if (!strcmp(con, "kernel")) + enabled = 0; + freecon(con); + } + return enabled; + } - memset(buf, 0, size); + /* Drop back to detecting it the long way. */ + fp = fopen("/proc/filesystems", "r"); + if (!fp) + return -1; - ret = read(fd, buf, size - 1); - if (ret < 0) { - enabled = -1; - goto out2; + while ((num = getline(&buf, &len, fp)) != -1) { + if (strstr(buf, "selinuxfs")) { + enabled = 1; + break; + } } - if (!strstr(buf, "selinuxfs")) - goto out2; - - enabled = 1; + if (num < 0) + goto out; + /* Since an selinux file system is available, we consider + * selinux enabled. If getcon_raw fails, selinux is still + * enabled. We only consider it disabled if no policy is loaded. */ if (getcon_raw(&con) == 0) { if (!strcmp(con, "kernel")) enabled = 0; freecon(con); } - out2: - free(buf); + out: - close(fd); + free(buf); + fclose(fp); return enabled; } @@ -75,7 +86,9 @@ int is_selinux_mls_enabled(void) memset(buf, 0, sizeof buf); - ret = read(fd, buf, sizeof buf - 1); + do { + ret = read(fd, buf, sizeof buf - 1); + } while (ret < 0 && errno == EINTR); close(fd); if (ret < 0) return enabled; diff -urp libselinux-2.0.4.orig/src/init.c libselinux-2.0.4/src/init.c --- libselinux-2.0.4.orig/src/init.c 2007-02-25 14:52:16.000000000 -0500 +++ libselinux-2.0.4/src/init.c 2007-02-26 11:21:02.000000000 -0500 @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include "dso.h" #include "policy.h" @@ -18,51 +19,57 @@ int selinux_page_size = 0; static void init_selinuxmnt(void) { - char *buf, *bufp, *p; - size_t size; + 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; - size = selinux_page_size; - - buf = malloc(size); - if (!buf) - goto out; - - memset(buf, 0, size); - - while ((bufp = fgets_unlocked(buf, size, fp))) { + while ((num = getline(&buf, &len, fp)) != -1) { char *tmp; p = strchr(buf, ' '); if (!p) - goto out2; + goto out; p++; tmp = strchr(p, ' '); if (!tmp) - goto out2; + goto out; if (!strncmp(tmp + 1, "selinuxfs ", 10)) { *tmp = '\0'; break; } } - if (!bufp) - goto out2; + /* If we found something, dup it */ + if (num > 0) + selinux_mnt = strdup(p); - selinux_mnt = strdup(p); - - out2: - free(buf); out: + free(buf); fclose(fp); return; - } static void fini_selinuxmnt(void) diff -urp libselinux-2.0.4.orig/src/load_policy.c libselinux-2.0.4/src/load_policy.c --- libselinux-2.0.4.orig/src/load_policy.c 2007-02-25 14:52:16.000000000 -0500 +++ libselinux-2.0.4/src/load_policy.c 2007-02-26 11:18:14.000000000 -0500 @@ -165,7 +165,6 @@ hidden_def(selinux_mkload_policy) * We only need the hardcoded definition for the initial mount * required for the initial policy load. */ -#define SELINUXMNT "/selinux/" int selinux_init_load_policy(int *enforce) { int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1; diff -urp libselinux-2.0.4.orig/src/policy.h libselinux-2.0.4/src/policy.h --- libselinux-2.0.4.orig/src/policy.h 2007-02-25 14:52:16.000000000 -0500 +++ libselinux-2.0.4/src/policy.h 2007-02-26 11:18:14.000000000 -0500 @@ -9,6 +9,12 @@ /* Initial length guess for getting contexts. */ #define INITCONTEXTLEN 255 +/* selinuxfs magic number */ +#define SELINUX_MAGIC 0xf97cff8c + +/* Preferred selinux mount location */ +#define SELINUXMNT "/selinux" + /* selinuxfs mount point */ extern char *selinux_mnt;