Security Enhanced Linux
What's New
Frequently Asked Questions
Background
Documents
License
Download
Participating
Mail List
Archives
Remaining Work
Contributors
Related Work
Press Releases
Information Assurance Research
NIARL In-house Research Areas
Mathematical Sciences Program
Sabbaticals
Computer & Information Sciences Research
Technology Transfer
Advanced Computing
Advanced Mathematics
Communications & Networking
Information Processing
Microelectronics
Other Technologies
Technology Fact Sheets
Publications
Related Links
|
SELinux Mailing ListRe: [patch] reducing size of libselinux(ver 2)
From: Stephen Smalley <sds_at_tycho.nsa.gov>
Date: Wed, 09 May 2007 15:24:39 -0400
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 |