Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org --- libselinux/libselinux.nm | 97 ----- libselinux/patches/libselinux-rhat.patch2 | 693 ------------------------------ 2 files changed, 790 deletions(-) delete mode 100644 libselinux/libselinux.nm delete mode 100644 libselinux/patches/libselinux-rhat.patch2
diff --git a/libselinux/libselinux.nm b/libselinux/libselinux.nm deleted file mode 100644 index 0be2a67..0000000 --- a/libselinux/libselinux.nm +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# IPFire.org - An Open Source Firewall Solution # -# Copyright (C) - IPFire Development Team info@ipfire.org # -############################################################################### - -name = libselinux -version = 2.1.10 -release = 1 - -groups = System/Libraries -url = http://www.selinuxproject.org -license = Public Domain -summary = SELinux library and simple utilities. - -description - libselinux provides an API for SELinux applications to get and set - process and file security contexts and to obtain security policy - decisions. -end - -sources = %{thisapp}.tgz - -build - requires - libsepol-devel - libsepol-static - python-devel - swig - end - - build - make clean - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" swigify - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" all - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" pywrap - end - - # Install libraries to correct place. - make_install_targets += install-pywrap \ - BINDIR="%{BUILDROOT}%{bindir}" \ - SBINDIR="%{BUILDROOT}%{sbindir}" \ - LIBDIR="%{BUILDROOT}%{libdir}" \ - SHLIBDIR="%{BUILDROOT}%{libdir}" - - install_cmds - # Remove unwanted binaries - rm -f %{BUILDROOT}/usr/sbin/compute_* - rm -f %{BUILDROOT}/usr/sbin/deftype - rm -f %{BUILDROOT}/usr/sbin/execcon - rm -f %{BUILDROOT}/usr/sbin/getenforcemode - rm -f %{BUILDROOT}/usr/sbin/getfilecon - rm -f %{BUILDROOT}/usr/sbin/getpidcon - rm -f %{BUILDROOT}/usr/sbin/mkdircon - rm -f %{BUILDROOT}/usr/sbin/policyvers - rm -f %{BUILDROOT}/usr/sbin/setfilecon - rm -f %{BUILDROOT}/usr/sbin/selinuxconfig - rm -f %{BUILDROOT}/usr/sbin/selinuxdisable - rm -f %{BUILDROOT}/usr/sbin/getseuser - rm -f %{BUILDROOT}/usr/sbin/selinux_check_securetty_context - - # Fix weird symlink. - ln -svf libselinux.so.1 %{BUILDROOT}%{libdir}/libselinux.so - end -end - -packages - package %{name} - - package %{name}-devel - template DEVEL - end - - package %{name}-utils - summary = SELinux libselinux utitlities. - description - The libselinux-utils package contains the utilities. - end - - files - /usr/sbin/* - /usr/share/man/man{5,8} - end - end - - package python-selinux - summary = SELinux python bindings. - description = SELinux python bindings for libselinux. - - def files - %{libdir}/python* - end - end - - package %{name}-debuginfo - template DEBUGINFO - end -end diff --git a/libselinux/patches/libselinux-rhat.patch2 b/libselinux/patches/libselinux-rhat.patch2 deleted file mode 100644 index 4ac818f..0000000 --- a/libselinux/patches/libselinux-rhat.patch2 +++ /dev/null @@ -1,693 +0,0 @@ -diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h -index 1a54307..f6eeb21 100644 ---- a/libselinux/include/selinux/label.h -+++ b/libselinux/include/selinux/label.h -@@ -46,8 +46,10 @@ struct selabel_handle; - #define SELABEL_OPT_PATH 3 - /* select a subset of the search space as an optimization (file backend) */ - #define SELABEL_OPT_SUBSET 4 -+/* like subset, but an array of subsets */ -+#define SELABEL_OPT_PREFIXES 5 - /* total number of options */ --#define SELABEL_NOPT 5 -+#define SELABEL_NOPT 6 - - /* - * Label operations -diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h -index 6f483c9..9756ac9 100644 ---- a/libselinux/include/selinux/selinux.h -+++ b/libselinux/include/selinux/selinux.h -@@ -139,7 +139,10 @@ struct av_decision { - /* Structure for passing options, used by AVC and label subsystems */ - struct selinux_opt { - int type; -- const char *value; -+ union { -+ const char *value; -+ const char **values; -+ }; - }; - - /* Callback facilities */ -@@ -420,6 +423,11 @@ extern int matchpathcon_init(const char *path); - regexes that have stems that are prefixes of 'prefix'. */ - extern int matchpathcon_init_prefix(const char *path, const char *prefix); - -+/* Same as matchpathcon_init, but only load entries with -+ * regexes that have stems that are prefixes of the 'prefixes' -+ * array of entries. The last entry must be NULL. */ -+extern int matchpathcon_init_prefixes(const char *patch, const char **prefixes); -+ - /* Free the memory allocated by matchpathcon_init. */ - extern void matchpathcon_fini(void); - -@@ -488,6 +496,7 @@ extern const char *selinux_policy_root(void); - - /* These functions return the paths to specific files under the - policy root directory. */ -+extern const char *selinux_current_policy_path(void); - extern const char *selinux_binary_policy_path(void); - extern const char *selinux_failsafe_context_path(void); - extern const char *selinux_removable_context_path(void); -@@ -502,10 +511,12 @@ extern const char *selinux_homedir_context_path(void); - extern const char *selinux_media_context_path(void); - extern const char *selinux_virtual_domain_context_path(void); - extern const char *selinux_virtual_image_context_path(void); -+extern const char *selinux_lxc_contexts_path(void); - extern const char *selinux_x_context_path(void); - extern const char *selinux_sepgsql_context_path(void); - extern const char *selinux_contexts_path(void); - extern const char *selinux_securetty_types_path(void); -+extern const char *selinux_booleans_subs_path(void); - extern const char *selinux_booleans_path(void); - extern const char *selinux_customizable_types_path(void); - extern const char *selinux_users_path(void); -diff --git a/libselinux/man/man3/matchpathcon.3 b/libselinux/man/man3/matchpathcon.3 -index cdbb252..b6814ed 100644 ---- a/libselinux/man/man3/matchpathcon.3 -+++ b/libselinux/man/man3/matchpathcon.3 -@@ -8,7 +8,9 @@ matchpathcon, matchpathcon_index - get the default SELinux security context for - - .BI "int matchpathcon_init(const char *" path ");" - --.BI "int matchpathcon_init_prefix(const char *" path ", const char *" subset ");" -+.BI "int matchpathcon_init_prefix(const char *" path ", const char *" prefix ");" -+ -+.BI "int matchpathcon_init_prefixes(const char *" path ", const char **" prefixes ");" - - .BI "int matchpathcon_fini(void);" - .sp -@@ -50,6 +52,14 @@ by - .I prefix. - - .sp -+.B matchpathcon_init_prefixes -+is the same as -+.B matchpathcon_init_prefix -+but takes an array of -+.I prefixes -+instead of a single prefix. The last entry in the array must be NULL. -+ -+.sp - .B matchpathcon_fini - frees the memory allocated by a prior call to - .B matchpathcon_init. -diff --git a/libselinux/man/man3/selabel_open.3 b/libselinux/man/man3/selabel_open.3 -index 8674e37..fc5b120 100644 ---- a/libselinux/man/man3/selabel_open.3 -+++ b/libselinux/man/man3/selabel_open.3 -@@ -37,8 +37,11 @@ structures of length - .ta 4n 16n 24n - .nf - struct selinux_opt { -- int type; -- const char *value; -+ int type; -+ union { -+ const char *value; -+ const char **values; -+ }; - }; - .fi - .ta -@@ -66,6 +69,13 @@ A non-null value for this option enables context validation. By default, - is used; a custom validation function can be provided via - .BR selinux_set_callback (3). - Note that an invalid context may not be treated as an error unless it is actually encountered during a lookup operation. -+.TP -+.B SELABEL_OPT_SUBSET -+A ":" separates string of path prefixes that tell the system to only loads entries with regular expressions that could match this strings. For example "/dev:/var/run:/tmp". This option can cause the system to use less memory and work faster, but you should only use paths that begin with a prefix. -+.TP -+.B SELABEL_OPT_PATH -+A string representing an alternate path the the regular expressions. -+.sp - - .SH "BACKENDS" - -@@ -99,4 +109,3 @@ Eamon Walsh ewalsh@tycho.nsa.gov - .BR selabel_stats (3), - .BR selinux_set_callback (3), - .BR selinux (8) -- -diff --git a/libselinux/man/man3/selinux_binary_policy_path.3 b/libselinux/man/man3/selinux_binary_policy_path.3 -index 8ead1a4..c68ace5 100644 ---- a/libselinux/man/man3/selinux_binary_policy_path.3 -+++ b/libselinux/man/man3/selinux_binary_policy_path.3 -@@ -17,6 +17,8 @@ extern const char *selinux_policy_root(void); - - extern const char *selinux_binary_policy_path(void); - -+extern const char *selinux_current_policy_path(void); -+ - extern const char *selinux_failsafe_context_path(void); - - extern const char *selinux_removable_context_path(void); -@@ -52,7 +54,9 @@ selinux_path() - top-level SELinux configuration directory - .sp - selinux_policy_root() - top-level policy directory - .sp --selinux_binary_policy_path() - binary policy file loaded into kernel -+selinux_current_policy_path() - binary policy file loaded into kernel -+.sp -+selinux_binary_policy_path() - binary policy path on disk - .sp - selinux_default_type_path - context file mapping roles to default types. - .sp -diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c -index 1bf3599..f621de7 100644 ---- a/libselinux/src/audit2why.c -+++ b/libselinux/src/audit2why.c -@@ -214,19 +214,12 @@ static int __policy_init(const char *init_path) - PyErr_SetString( PyExc_ValueError, errormsg); - return 1; - } -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- while (!fp && errno == ENOENT && --vers) { -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- } -+ fp = fopen(selinux_current_policy_path(), "r"); - if (!fp) { - snprintf(errormsg, sizeof(errormsg), -- "unable to open %s.%d: %s\n", -- selinux_binary_policy_path(), -- security_policyvers(), strerror(errno)); -+ "unable to open %s: %s\n", -+ selinux_current_policy_path(), -+ strerror(errno)); - PyErr_SetString( PyExc_ValueError, errormsg); - return 1; - } -diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c -index 802a07f..6ff83a7 100644 ---- a/libselinux/src/avc.c -+++ b/libselinux/src/avc.c -@@ -827,6 +827,7 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid, - errsave = errno; - avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); - errno = errsave; -+ if (!avc_enforcing) return 0; - return rc; - } - -diff --git a/libselinux/src/avc_internal.c b/libselinux/src/avc_internal.c -index be4c0a3..a07aa7f 100644 ---- a/libselinux/src/avc_internal.c -+++ b/libselinux/src/avc_internal.c -@@ -101,7 +101,9 @@ static int avc_netlink_receive(char *buf, unsigned buflen, int blocking) - socklen_t nladdrlen = sizeof nladdr; - struct nlmsghdr *nlh = (struct nlmsghdr *)buf; - -- rc = poll(&pfd, 1, (blocking ? -1 : 0)); -+ do { -+ rc = poll(&pfd, 1, (blocking ? -1 : 0)); -+ } while (rc < 0 && errno == EINTR); - - if (rc == 0 && !blocking) { - errno = EWOULDBLOCK; -diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c -index 1510043..bf526c0 100644 ---- a/libselinux/src/booleans.c -+++ b/libselinux/src/booleans.c -@@ -86,45 +86,131 @@ int security_get_boolean_names(char ***names, int *len) - } - - hidden_def(security_get_boolean_names) --#define STRBUF_SIZE 3 --static int get_bool_value(const char *name, char **buf) -+ -+static char * bool_sub(const char *name) - { -- int fd, len; -+ char *sub = NULL; -+ char *line_buf = NULL; -+ size_t line_len = 0; -+ FILE *cfg; -+ -+ if (!name) -+ return NULL; -+ -+ cfg = fopen(selinux_booleans_subs_path(), "r"); -+ -+ if (!cfg) -+ return NULL; -+ -+ while (getline(&line_buf, &line_len, cfg)) { -+ char *ptr = NULL; -+ char *src = line_buf; -+ char *dst = NULL; -+ -+ while (*src && isspace(*src)) -+ src++; -+ if (src[0] == '#') continue; -+ ptr = src; -+ while (*ptr && ! isspace(*ptr)) -+ ptr++; -+ *ptr++ = '\0'; -+ if (! *src || (strcmp(src, name) != 0)) -+ continue; -+ -+ dst = ptr; -+ while (*dst && isspace(*dst)) -+ dst++; -+ ptr=dst; -+ while (*ptr && ! isspace(*ptr)) -+ ptr++; -+ *ptr='\0'; -+ if (! *dst) -+ continue; -+ -+ sub = strdup(dst); -+ break; -+ } -+ -+ free(line_buf); -+ fclose(cfg); -+ return sub; -+} -+ -+static int bool_open(const char *name, int flag) { - char *fname = NULL; -+ char *alt_name = NULL; -+ int len; -+ int fd = -1; -+ char *ptr; - -- if (!selinux_mnt) { -- errno = ENOENT; -- return -1; -+ if (!name) { -+ errno = EINVAL; -+ return fd; - } - -- *buf = (char *)malloc(sizeof(char) * (STRBUF_SIZE + 1)); -- if (!*buf) -- goto out; -- (*buf)[STRBUF_SIZE] = 0; -- - len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); - fname = (char *)malloc(sizeof(char) * len); - if (!fname) -- goto out; -+ return fd; -+ - snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); - -- fd = open(fname, O_RDONLY); -- if (fd < 0) -+ fd = open(fname, flag); -+ if (fd >= 0 || errno != ENOENT) - goto out; - -- len = read(fd, *buf, STRBUF_SIZE); -- close(fd); -- if (len != STRBUF_SIZE) -+ alt_name = bool_sub(name); -+ if (! alt_name) - goto out; - -+ len = strlen(alt_name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); -+ ptr = realloc(fname, len); -+ if (!ptr) -+ goto out; -+ -+ fname = ptr; -+ snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name); -+ fd = open(fname, flag); -+ -+out: - free(fname); -- return 0; -+ free(alt_name); -+ -+ return fd; -+} -+ -+#define STRBUF_SIZE 3 -+static int get_bool_value(const char *name, char **buf) -+{ -+ int fd, len; -+ int rc = -1; -+ char *bool_buf = NULL; -+ if (!selinux_mnt) { -+ errno = ENOENT; -+ return -1; -+ } -+ -+ fd = bool_open(name, O_RDONLY); -+ if (fd < 0) -+ return -1; -+ -+ bool_buf = malloc(sizeof(char) * (STRBUF_SIZE + 1)); -+ if (!bool_buf) -+ goto out; -+ bool_buf[STRBUF_SIZE] = 0; -+ -+ len = read(fd, bool_buf, STRBUF_SIZE); -+ if (len != STRBUF_SIZE) -+ goto out; -+ rc = 0; - out: -- if (*buf) -- free(*buf); -- if (fname) -- free(fname); -- return -1; -+ close(fd); -+ if (!rc) { -+ *buf = bool_buf; -+ } else { -+ free(bool_buf); -+ } -+ return rc; - } - - int security_get_boolean_pending(const char *name) -@@ -164,8 +250,8 @@ hidden_def(security_get_boolean_active) - - int security_set_boolean(const char *name, int value) - { -- int fd, ret, len; -- char buf[2], *fname; -+ int fd, ret; -+ char buf[2]; - - if (!selinux_mnt) { - errno = ENOENT; -@@ -176,17 +262,9 @@ int security_set_boolean(const char *name, int value) - return -1; - } - -- len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); -- fname = (char *)malloc(sizeof(char) * len); -- if (!fname) -+ fd = bool_open(name, O_WRONLY); -+ if (fd < 0) - return -1; -- snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); -- -- fd = open(fname, O_WRONLY); -- if (fd < 0) { -- ret = -1; -- goto out; -- } - - if (value) - buf[0] = '1'; -@@ -196,8 +274,7 @@ int security_set_boolean(const char *name, int value) - - ret = write(fd, buf, 2); - close(fd); -- out: -- free(fname); -+ - if (ret > 0) - return 0; - else -diff --git a/libselinux/src/callbacks.c b/libselinux/src/callbacks.c -index b245364..7c47222 100644 ---- a/libselinux/src/callbacks.c -+++ b/libselinux/src/callbacks.c -@@ -16,6 +16,7 @@ default_selinux_log(int type __attribute__((unused)), const char *fmt, ...) - { - int rc; - va_list ap; -+ if (is_selinux_enabled() == 0) return 0; - va_start(ap, fmt); - rc = vfprintf(stderr, fmt, ap); - va_end(ap); -diff --git a/libselinux/src/file_path_suffixes.h b/libselinux/src/file_path_suffixes.h -index 0b00156..825f295 100644 ---- a/libselinux/src/file_path_suffixes.h -+++ b/libselinux/src/file_path_suffixes.h -@@ -22,6 +22,8 @@ S_(BINPOLICY, "/policy/policy") - S_(COLORS, "/secolor.conf") - S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context") - S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context") -+ S_(LXC_CONTEXTS, "/contexts/lxc_contexts") - S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs") - S_(FILE_CONTEXT_SUBS_DIST, "/contexts/files/file_contexts.subs_dist") - S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts") -+ S_(BOOLEAN_SUBS, "/booleans.subs") -diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c -index 7bc46cc..82a608c 100644 ---- a/libselinux/src/label_file.c -+++ b/libselinux/src/label_file.c -@@ -27,6 +27,7 @@ - * Internals, mostly moved over from matchpathcon.c - */ - -+#define MAX_PREFIX 100 - /* A file security context specification. */ - typedef struct spec { - struct selabel_lookup_rec lr; /* holds contexts for lookup result */ -@@ -276,7 +277,7 @@ static int compile_regex(struct saved_data *data, spec_t *spec, char **errbuf) - - - static int process_line(struct selabel_handle *rec, -- const char *path, const char *prefix, -+ const char *path, const char **prefix_array, - char *line_buf, int pass, unsigned lineno) - { - int items, len; -@@ -310,12 +311,24 @@ static int process_line(struct selabel_handle *rec, - } - - len = get_stem_from_spec(regex); -- if (len && prefix && strncmp(prefix, regex, len)) { -- /* Stem of regex does not match requested prefix, discard. */ -- free(regex); -- free(type); -- free(context); -- return 0; -+ if (len && prefix_array[0]) { -+ int i = 0; -+ int found = 0; -+ while (i < MAX_PREFIX && prefix_array[i]) { -+ if (strncmp(prefix_array[i], regex, len) == 0) { -+ found = 1; -+ break; -+ } -+ i++; -+ } -+ -+ if (! found) { -+ /* Stem of regex does not match requested prefix, discard. */ -+ free(regex); -+ free(type); -+ free(context); -+ return 0; -+ } - } - - if (pass == 1) { -@@ -397,7 +410,8 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - { - struct saved_data *data = (struct saved_data *)rec->data; - const char *path = NULL; -- const char *prefix = NULL; -+ const char *static_prefix_array[2] = {NULL, }; -+ const char **prefix_array = static_prefix_array; - FILE *fp; - FILE *localfp = NULL; - FILE *homedirfp = NULL; -@@ -418,7 +432,10 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - path = opts[n].value; - break; - case SELABEL_OPT_SUBSET: -- prefix = opts[n].value; -+ static_prefix_array[0] = opts[n].value; -+ break; -+ case SELABEL_OPT_PREFIXES: -+ prefix_array = opts[n].values; - break; - case SELABEL_OPT_BASEONLY: - baseonly = !!opts[n].value; -@@ -481,7 +498,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, fp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -@@ -497,7 +514,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, homedirfp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, homedir_path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, homedir_path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -@@ -507,7 +524,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, localfp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, local_path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, local_path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c -index 8f200d4..c18ea47 100644 ---- a/libselinux/src/matchpathcon.c -+++ b/libselinux/src/matchpathcon.c -@@ -2,6 +2,7 @@ - #include <string.h> - #include <errno.h> - #include <stdio.h> -+#include <syslog.h> - #include "selinux_internal.h" - #include "label_internal.h" - #include "callbacks.h" -@@ -62,7 +63,7 @@ static void - { - va_list ap; - va_start(ap, fmt); -- vfprintf(stderr, fmt, ap); -+ vsyslog(LOG_ERR, fmt, ap); - va_end(ap); - } - -@@ -306,7 +307,7 @@ static void matchpathcon_init_once(void) - destructor_key_initialized = 1; - } - --int matchpathcon_init_prefix(const char *path, const char *subset) -+int matchpathcon_init_prefixes(const char *path, const char **prefixes) - { - if (!mycanoncon) - mycanoncon = default_canoncon; -@@ -314,15 +315,22 @@ int matchpathcon_init_prefix(const char *path, const char *subset) - __selinux_once(once, matchpathcon_init_once); - __selinux_setspecific(destructor_key, (void *)1); - -- options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET; -- options[SELABEL_OPT_SUBSET].value = subset; -+ options[SELABEL_OPT_PREFIXES].type = SELABEL_OPT_PREFIXES; -+ options[SELABEL_OPT_PREFIXES].values = prefixes; - options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH; - options[SELABEL_OPT_PATH].value = path; - - hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT); - return hnd ? 0 : -1; - } -+hidden_def(matchpathcon_init_prefixes) - -+int matchpathcon_init_prefix(const char *path, const char *prefix) -+{ -+ const char *prefixes[2] = { prefix, NULL }; -+ -+ return matchpathcon_init_prefixes(path, prefixes); -+} - hidden_def(matchpathcon_init_prefix) - - int matchpathcon_init(const char *path) -diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c -index f42cb7c..f544ac2 100644 ---- a/libselinux/src/selinux_config.c -+++ b/libselinux/src/selinux_config.c -@@ -9,6 +9,7 @@ - #include <unistd.h> - #include <pthread.h> - #include "selinux_internal.h" -+#include "policy.h" - #include "get_default_type_internal.h" - - #define SELINUXDIR "/etc/selinux/" -@@ -46,7 +47,9 @@ - #define FILE_CONTEXT_SUBS 23 - #define SEPGSQL_CONTEXTS 24 - #define FILE_CONTEXT_SUBS_DIST 25 --#define NEL 26 -+#define BOOLEAN_SUBS 26 -+#define LXC_CONTEXTS 27 -+#define NEL 28 - - /* Part of one-time lazy init */ - static pthread_once_t once = PTHREAD_ONCE_INIT; -@@ -301,6 +304,29 @@ const char *selinux_binary_policy_path(void) - - hidden_def(selinux_binary_policy_path) - -+const char *selinux_current_policy_path(void) -+{ -+ int rc = 0; -+ int vers = 0; -+ static char policy_path[PATH_MAX]; -+ -+ snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt); -+ if (access(policy_path, F_OK) != 0 ) { -+ vers = security_policyvers(); -+ do { -+ /* Check prior versions to see if old policy is available */ -+ snprintf(policy_path, sizeof(policy_path), "%s.%d", -+ selinux_binary_policy_path(), vers); -+ } while ((rc = access(policy_path, F_OK)) && --vers > 0); -+ -+ if (rc) return NULL; -+ } -+ -+ return policy_path; -+} -+ -+hidden_def(selinux_current_policy_path) -+ - const char *selinux_file_context_path(void) - { - return get_path(FILE_CONTEXTS); -@@ -418,6 +444,19 @@ const char *selinux_virtual_image_context_path(void) - - hidden_def(selinux_virtual_image_context_path) - -+const char *selinux_lxc_contexts_path(void) -+{ -+ return get_path(LXC_CONTEXTS); -+} -+ -+hidden_def(selinux_lxc_contexts_path) -+ -+const char * selinux_booleans_subs_path(void) { -+ return get_path(BOOLEAN_SUBS); -+} -+ -+hidden_def(selinux_booleans_subs_path) -+ - const char * selinux_file_context_subs_path(void) { - return get_path(FILE_CONTEXT_SUBS); - } -diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h -index 00df405..8a935d0 100644 ---- a/libselinux/src/selinux_internal.h -+++ b/libselinux/src/selinux_internal.h -@@ -60,12 +60,15 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(security_setenforce) - hidden_proto(security_deny_unknown) - hidden_proto(selinux_binary_policy_path) -+ hidden_proto(selinux_booleans_subs_path) -+ hidden_proto(selinux_current_policy_path) - hidden_proto(selinux_default_context_path) - hidden_proto(selinux_securetty_types_path) - hidden_proto(selinux_failsafe_context_path) - hidden_proto(selinux_removable_context_path) - hidden_proto(selinux_virtual_domain_context_path) - hidden_proto(selinux_virtual_image_context_path) -+ hidden_proto(selinux_lxc_contexts_path) - hidden_proto(selinux_file_context_path) - hidden_proto(selinux_file_context_homedir_path) - hidden_proto(selinux_file_context_local_path) -@@ -82,6 +85,7 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(selinux_path) - hidden_proto(selinux_check_passwd_access) - hidden_proto(selinux_check_securetty_context) -+ hidden_proto(matchpathcon_init_prefixes) - hidden_proto(matchpathcon_init_prefix) - hidden_proto(selinux_users_path) - hidden_proto(selinux_usersconf_path);