Research Menu

.
Skip Search Box

SELinux Mailing List

Re: [patch] reducing size of libselinux(ver 2)

From: Stephen Smalley <sds_at_tycho.nsa.gov>
Date: Wed, 09 May 2007 15:24:39 -0400


On Mon, 2007-05-07 at 13:34 +0900, Yuichi Nakamura wrote:
> Hello.
>
> I would like to submit patch again
> to reduce size of libselinux for embedded devices, as we discussed before.
> http://marc.info/?t=117609454600002&r=1&w=2
> This patch is for policyrep branch.

<snip>
> Index: libselinux/src/load_policy.c
> ===================================================================
> --- libselinux/src/load_policy.c (revision 2429)
> +++ libselinux/src/load_policy.c (working copy)
> @@ -15,6 +15,21 @@
> #include "policy.h"
> #include <limits.h>
>
> +#ifdef DISABLE_SEPOL
> +#include <sepol/policydb/policydb.h>
> +/* selinux_mkload_policy needs them
> + even when sepol is disabled. */
> +int sepol_policy_kern_vers_min(void)
> +{
> + return POLICYDB_VERSION_MIN;
> +}
> +
> +int sepol_policy_kern_vers_max(void)
> +{
> + return POLICYDB_VERSION_MAX;
> +}
> +#endif

I don't think we want to be including headers from under sepol/policydb/ or replicating these functions here, and it occurs to me that we could all benefit from making the libselinux -> libsepol dependency optional at runtime, i.e. have libselinux dlopen() libsepol and only use its functions if present, as that would eliminate the unnecessary dependency on libsepol for many programs that only need libselinux.

Something like the patch below (compile-tested only).

---

Remove the fixed dependency on libsepol from libselinux by
having it use dlopen() and friends and provide graceful fallbacks
in the absence of libsepol.

---

 libselinux/src/Makefile      |    2 
 libselinux/src/load_policy.c |   97 +++++++++++++++++++++++++++++++++++--------
 libselinux/src/policy.h      |    2 
 libselinux/src/policyvers.c  |    2 
 4 files changed, 83 insertions(+), 20 deletions(-)

Index: policyrep/libselinux/src/policyvers.c
===================================================================
--- policyrep/libselinux/src/policyvers.c	(revision 2429)
+++ policyrep/libselinux/src/policyvers.c	(working copy)
@@ -10,8 +10,6 @@
 #include "dso.h"
 #include <limits.h>
 
-#define DEFAULT_POLICY_VERSION 15
-
 int security_policyvers(void)
 {
 	int fd, ret;
Index: policyrep/libselinux/src/policy.h
===================================================================
--- policyrep/libselinux/src/policy.h	(revision 2429)
+++ policyrep/libselinux/src/policy.h	(working copy)
@@ -20,4 +20,6 @@
 
 #define FILECONTEXTS "/etc/security/selinux/file_contexts"
 
+#define DEFAULT_POLICY_VERSION 15
+
 #endif
Index: policyrep/libselinux/src/Makefile
===================================================================
--- policyrep/libselinux/src/Makefile	(revision 2429)
+++ policyrep/libselinux/src/Makefile	(working copy)
@@ -48,7 +48,7 @@
 	$(CC) $(LDFLAGS) -shared -o $@ $< -L. -lselinux -L$(LIBDIR) -Wl,-soname,$@
 
 $(LIBSO): $(LOBJS)
-	$(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -lsepol -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
+	$(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
 	ln -sf $@ $(TARGET) 
 
 %.o:  %.c policy.h
Index: policyrep/libselinux/src/load_policy.c
===================================================================
--- policyrep/libselinux/src/load_policy.c	(revision 2429)
+++ policyrep/libselinux/src/load_policy.c	(working copy)
@@ -12,6 +12,7 @@
 #include "selinux_internal.h"
 #include <sepol/sepol.h>
 #include <sepol/policydb.h>
+#include <dlfcn.h>
 #include "policy.h"
 #include <limits.h>
 
@@ -41,8 +42,8 @@
 
 int selinux_mkload_policy(void)
 {
-	int vers = sepol_policy_kern_vers_max();
 	int kernvers = security_policyvers();
+	int vers = kernvers, minvers = DEFAULT_POLICY_VERSION;
 	char path[PATH_MAX];
 	struct stat sb;
 	size_t size;
@@ -50,20 +51,75 @@
 	int fd, rc = -1;
 	sepol_policydb_t *policydb;
 	sepol_policy_file_t *pf;
+	int (*vers_max)(void) = NULL;
+	int (*vers_min)(void) = NULL;
+	int (*policy_file_create)(sepol_policy_file_t **) = NULL;
+	void (*policy_file_free)(sepol_policy_file_t *) = NULL;
+	void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL;
+	int (*policydb_create)(sepol_policydb_t **) = NULL;
+	void (*policydb_free)(sepol_policydb_t *) = NULL;
+	int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL;
+	int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL;
+	int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL;
+#ifdef SHARED
+	char *errormsg = NULL;
+	void *libsepolh = NULL;
+	libsepolh = dlopen("libsepol.so", RTLD_NOW);
+	if (libsepolh) {
+		dlerror();
+#define DLERR() if ((errormsg = dlerror())) goto dlclose;
+		vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
+		DLERR();
+		vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
+		DLERR();
 
+		policy_file_create = dlsym(libsepolh, "sepol_policy_file_create");
+		DLERR();
+		policy_file_free = dlsym(libsepolh, "sepol_policy_file_free");
+		DLERR();
+		policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem");
+		DLERR();
+		policydb_create = dlsym(libsepolh, "sepol_policydb_create");
+		DLERR();
+		policydb_free = dlsym(libsepolh, "sepol_policydb_free");
+		DLERR();
+		policydb_read = dlsym(libsepolh, "sepol_policydb_read");
+		DLERR();
+		policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers");
+		DLERR();
+		policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image");
+		DLERR();
+#undef DLERR
+	}
+#else
+	vers_max = sepol_policy_kern_vers_max;
+	vers_min = sepol_policy_kern_vers_min;
+	policy_file_create = sepol_policy_file_create;
+	policy_file_free = sepol_policy_file_free;
+	policy_file_set_mem = sepol_policy_file_set_mem;
+	policydb_create = sepol_policydb_create;
+	policydb_free = sepol_policydb_free;
+	policydb_read = sepol_policydb_read;
+	policydb_set_vers = sepol_policydb_set_vers;
+	policydb_to_image = sepol_policydb_to_image;
+#endif
+
+	vers = vers_max();
+	minvers = vers_min();
+
       search:
 	snprintf(path, sizeof(path), "%s.%d",
 		 selinux_binary_policy_path(), vers);
 	fd = open(path, O_RDONLY);
 	while (fd < 0 && errno == ENOENT
-	       && --vers >= sepol_policy_kern_vers_min()) {
+	       && --vers >= minvers) {
 		/* Check prior versions to see if old policy is available */
 		snprintf(path, sizeof(path), "%s.%d",
 			 selinux_binary_policy_path(), vers);
 		fd = open(path, O_RDONLY);
 	}
 	if (fd < 0)
-		return -1;
+		goto dlclose;
 
 	if (fstat(fd, &sb) < 0)
 		goto close;
@@ -73,32 +129,32 @@
 	if (map == MAP_FAILED)
 		goto close;
 
-	if (vers > kernvers) {
+	if (vers > kernvers && policydb_to_image) {
 		/* Need to downgrade to kernel-supported version. */
-		if (sepol_policy_file_create(&pf))
+		if (policy_file_create(&pf))
 			goto unmap;
-		if (sepol_policydb_create(&policydb)) {
-			sepol_policy_file_free(pf);
+		if (policydb_create(&policydb)) {
+			policy_file_free(pf);
 			goto unmap;
 		}
-		sepol_policy_file_set_mem(pf, data, size);
-		if (sepol_policydb_read(policydb, pf)) {
-			sepol_policy_file_free(pf);
-			sepol_policydb_free(policydb);
+		policy_file_set_mem(pf, data, size);
+		if (policydb_read(policydb, pf)) {
+			policy_file_free(pf);
+			policydb_free(policydb);
 			goto unmap;
 		}
-		if (sepol_policydb_set_vers(policydb, kernvers) ||
-		    sepol_policydb_to_image(NULL, policydb, &data, &size)) {
+		if (policydb_set_vers(policydb, kernvers) ||
+		    policydb_to_image(NULL, policydb, &data, &size)) {
 			/* Downgrade failed, keep searching. */
-			sepol_policy_file_free(pf);
-			sepol_policydb_free(policydb);
+			policy_file_free(pf);
+			policydb_free(policydb);
 			munmap(map, sb.st_size);
 			close(fd);
 			vers--;
 			goto search;
 		}
-		sepol_policy_file_free(pf);
-		sepol_policydb_free(policydb);
+		policy_file_free(pf);
+		policydb_free(policydb);
 	}
 
 	rc = security_load_policy(data, size);
@@ -109,6 +165,13 @@
 	munmap(map, sb.st_size);
       close:
 	close(fd);
+      dlclose:
+#ifdef SHARED
+	if (errormsg)
+		fprintf(stderr, "libsepol:  %s\n", errormsg);
+	if (libsepolh)
+		dlclose(libsepolh);
+#endif
 	return rc;
 }
 

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
Received on Wed 9 May 2007 - 15:24:45 EDT
 

Date Posted: Jan 15, 2009 | Last Modified: Jan 15, 2009 | Last Reviewed: Jan 15, 2009

 
bottom

National Security Agency / Central Security Service