From: <ssm...@us...> - 2007-02-27 15:06:14
|
Revision: 2273 http://svn.sourceforge.net/selinux/?rev=2273&view=rev Author: ssmalley Date: 2007-02-27 06:57:14 -0800 (Tue, 27 Feb 2007) Log Message: ----------- Author: Steve G Email: lin...@ya... Subject: libselinux patch Date: Mon, 26 Feb 2007 08:40:43 -0800 (PST) OK, I think the attached patch does _everything _ we discussed. It: - removes 8 syscalls for the normal path - ensures /selinux is trully an selinuxfs - drops back to detecting the old way when /selinux is missing - changes the old way in is_enabled to use fopen & getline for glibc internal retries - adds retry for EINTR in mls_enabled - keeps SELINUX_MAGIC private Signed-off-by: Steve Grubb <lin...@ya...> [amended by:] Not sending this to mail list as I've sent so many variations of this. I noticed that I forgot the call to __fsetlocking before the getline() calls. So, the attached patch is updated to have that and should be otherwise identical. Modified Paths: -------------- trunk/libselinux/src/enabled.c trunk/libselinux/src/init.c trunk/libselinux/src/load_policy.c trunk/libselinux/src/policy.h Modified: trunk/libselinux/src/enabled.c =================================================================== --- trunk/libselinux/src/enabled.c 2007-02-27 14:52:46 UTC (rev 2272) +++ trunk/libselinux/src/enabled.c 2007-02-27 14:57:14 UTC (rev 2273) @@ -6,50 +6,63 @@ #include <errno.h> #include <limits.h> #include <stdio.h> +#include <stdio_ext.h> #include "policy.h" 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; + /* 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) { - size = selinux_page_size; - buf = malloc(size); - if (!buf) { - enabled = -1; - goto out; - } + /* 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; + __fsetlocking(fp, FSETLOCKING_BYCALLER); + while ((num = getline(&buf, &len, fp)) != -1) { + if (strstr(buf, "selinuxfs")) { + enabled = 1; + break; + } } - if (!strstr(buf, "selinuxfs")) - goto out2; + if (num < 0) + goto out; - enabled = 1; - + /* 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: + + out: free(buf); - out: - close(fd); + fclose(fp); return enabled; } @@ -75,7 +88,9 @@ 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; Modified: trunk/libselinux/src/init.c =================================================================== --- trunk/libselinux/src/init.c 2007-02-27 14:52:46 UTC (rev 2272) +++ trunk/libselinux/src/init.c 2007-02-27 14:57:14 UTC (rev 2273) @@ -5,8 +5,10 @@ #include <errno.h> #include <ctype.h> #include <stdio.h> +#include <stdio_ext.h> #include <dlfcn.h> -#include <unistd.h> +#include <sys/vfs.h> +#include <stdint.h> #include "dso.h" #include "policy.h" @@ -18,51 +20,58 @@ 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))) { + __fsetlocking(fp, FSETLOCKING_BYCALLER); + 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: + out: free(buf); - out: fclose(fp); return; - } static void fini_selinuxmnt(void) Modified: trunk/libselinux/src/load_policy.c =================================================================== --- trunk/libselinux/src/load_policy.c 2007-02-27 14:52:46 UTC (rev 2272) +++ trunk/libselinux/src/load_policy.c 2007-02-27 14:57:14 UTC (rev 2273) @@ -165,7 +165,6 @@ * 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; Modified: trunk/libselinux/src/policy.h =================================================================== --- trunk/libselinux/src/policy.h 2007-02-27 14:52:46 UTC (rev 2272) +++ trunk/libselinux/src/policy.h 2007-02-27 14:57:14 UTC (rev 2273) @@ -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; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |