diff --git a/libselinux/ChangeLog b/libselinux/ChangeLog index 1a761776..984d86a7 100644 --- a/libselinux/ChangeLog +++ b/libselinux/ChangeLog @@ -1,3 +1,12 @@ +1.27.9 2005-10-13 + * Changed selinux_mkload_policy to try downgrading the + latest policy version available to the kernel-supported version. + +1.27.8 2005-10-11 + * Changed selinux_mkload_policy to fall back to the maximum + policy version supported by libsepol if the kernel policy version + falls outside of the supported range. + 1.27.7 2005-10-06 * Changed getseuserbyname to fall back to the Linux username and NULL level if seusers config file doesn't exist unless diff --git a/libselinux/VERSION b/libselinux/VERSION index 127aeda7..2151d61d 100644 --- a/libselinux/VERSION +++ b/libselinux/VERSION @@ -1 +1 @@ -1.27.7 +1.27.9 diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile index 141fbf39..9cb79396 100644 --- a/libselinux/src/Makefile +++ b/libselinux/src/Makefile @@ -2,6 +2,7 @@ PREFIX ?= $(DESTDIR)/usr LIBDIR ?= $(PREFIX)/lib SHLIBDIR ?= $(DESTDIR)/lib +INCLUDEDIR ?= $(PREFIX)/include LIBVERSION = 1 @@ -12,7 +13,7 @@ LIBSO=$(TARGET).$(LIBVERSION) OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) LOBJS= $(patsubst %.c,%.lo,$(wildcard *.c)) CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -override CFLAGS += -I../include -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 RANLIB=ranlib all: $(LIBA) $(LIBSO) diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c index 3a2b3f8a..ce6828c2 100644 --- a/libselinux/src/load_policy.c +++ b/libselinux/src/load_policy.c @@ -11,6 +11,7 @@ #include #include "selinux_internal.h" #include +#include #include "policy.h" #include @@ -36,20 +37,21 @@ int load_setlocaldefs hidden = 1; int selinux_mkload_policy(int preservebools) { - int vers = security_policyvers(); + int vers = sepol_policy_kern_vers_max(); + int kernvers = security_policyvers(); char path[PATH_MAX], **names; struct stat sb; size_t size; void *map, *data; int fd, rc = -1, *values, len, i, prot; + sepol_policydb_t *policydb; + sepol_policy_file_t *pf; - if (vers < 0) - return -1; - +search: snprintf(path, sizeof(path), "%s.%d", selinux_binary_policy_path(), vers); fd = open(path, O_RDONLY); - while (fd < 0 && errno == ENOENT && --vers > 0) { + while (fd < 0 && errno == ENOENT && --vers >= sepol_policy_kern_vers_min()) { /* Check prior versions to see if old policy is available */ snprintf(path, sizeof(path), "%s.%d", selinux_binary_policy_path(), vers); @@ -70,13 +72,46 @@ int selinux_mkload_policy(int preservebools) if (map == MAP_FAILED) goto close; + if (vers > kernvers) { + /* Need to downgrade to kernel-supported version. */ + if (sepol_policy_file_create(&pf)) + goto unmap; + if (sepol_policydb_create(&policydb)) { + sepol_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); + goto unmap; + } + if (sepol_policydb_set_vers(policydb, kernvers) || + sepol_policydb_to_image(policydb, &data, &size)) { + /* Downgrade failed, keep searching. */ + sepol_policy_file_free(pf); + sepol_policydb_free(policydb); + munmap(map, sb.st_size); + close(fd); + vers--; + goto search; + } + sepol_policy_file_free(pf); + sepol_policydb_free(policydb); + } + if (load_setlocaldefs) { - rc = sepol_genusers(data, size, selinux_users_path(), &data, &size); + void *olddata = data; + size_t oldsize = size; + rc = sepol_genusers(olddata, oldsize, selinux_users_path(), &data, &size); if (rc < 0) { - /* Fall back to the base image if genusers failed. */ - data = map; - size = sb.st_size; + /* Fall back to the prior image if genusers failed. */ + data = olddata; + size = oldsize; rc = 0; + } else { + if (olddata != map) + free(olddata); } }