|
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.
|