diff --git a/recipes-security/selinux/libselinux/libselinux-pcre-link-order.patch b/recipes-security/selinux/libselinux/libselinux-pcre-link-order.patch deleted file mode 100644 index ac4de7f..0000000 --- a/recipes-security/selinux/libselinux/libselinux-pcre-link-order.patch +++ /dev/null @@ -1,34 +0,0 @@ -Subject: [PATCH] libselinux: Put -lpcre in LDADD for correct linking order - -Upstream-Status: pending - -Signed-off-by: Xin Ouyang ---- - src/Makefile | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/Makefile b/src/Makefile -index ac019df..1907d8c 100644 ---- a/src/Makefile -+++ b/src/Makefile -@@ -20,7 +20,7 @@ RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER)) - RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) - LIBBASE=$(shell basename $(LIBDIR)) - --LDFLAGS ?= -lpcre -+LDADD ?= -lpcre - - VERSION = $(shell cat ../VERSION) - LIBVERSION = 1 -@@ -116,7 +116,7 @@ $(LIBA): $(OBJS) - $(RANLIB) $@ - - $(LIBSO): $(LOBJS) -- $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro -+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro $(LDADD) - ln -sf $@ $(TARGET) - - $(LIBPC): $(LIBPC).in ../VERSION --- -1.7.5.4 - diff --git a/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch b/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch new file mode 100644 index 0000000..2511e9c --- /dev/null +++ b/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch @@ -0,0 +1,959 @@ +From e3016cb009d362235765af8b857ade754a97756f Mon Sep 17 00:00:00 2001 +From: Xin Ouyang +Date: Thu, 23 May 2013 17:12:13 +0800 +Subject: [PATCH] libselinux: Revert libpcre for old refpolicy compatible + +This reverts upstream libpcre commits. + +libselinux 2.1.12 uses libpcre to do file path matching instead of glibc +regex. Because there are some differences between glibc regex and pcre +functions, this will cause wrong security contexts for files while using +old refpolicy. + +This patch should be dropped while refpolicy is upreved to 2.20120725+. + +Upstream-Status: Inappropriate [for old refpolicy] + +Signed-off-by: Xin Ouyang +--- + src/Makefile | 2 - + src/label_file.c | 481 ++++++++++++++++++++++++++++++++------------ + src/label_file.h | 273 ------------------------- + 3 files changed, 347 insertions(+), 409 deletions(-) + delete mode 100644 src/label_file.h + +diff --git a/src/Makefile b/src/Makefile +index ac019df..74e53bb 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -20,8 +20,6 @@ RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER)) + RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) + LIBBASE=$(shell basename $(LIBDIR)) + +-LDFLAGS ?= -lpcre +- + VERSION = $(shell cat ../VERSION) + LIBVERSION = 1 + +diff --git a/src/label_file.c b/src/label_file.c +index 02b3cd2..7bc46cc 100644 +--- a/src/label_file.c ++++ b/src/label_file.c +@@ -16,18 +16,71 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include + #include "callbacks.h" + #include "label_internal.h" +-#include "label_file.h" + + /* + * Internals, mostly moved over from matchpathcon.c + */ + ++/* A file security context specification. */ ++typedef struct spec { ++ struct selabel_lookup_rec lr; /* holds contexts for lookup result */ ++ char *regex_str; /* regular expession string for diagnostics */ ++ char *type_str; /* type string for diagnostic messages */ ++ regex_t regex; /* compiled regular expression */ ++ char regcomp; /* regex_str has been compiled to regex */ ++ mode_t mode; /* mode format value */ ++ int matches; /* number of matching pathnames */ ++ int hasMetaChars; /* regular expression has meta-chars */ ++ int stem_id; /* indicates which stem-compression item */ ++} spec_t; ++ ++/* A regular expression stem */ ++typedef struct stem { ++ char *buf; ++ int len; ++} stem_t; ++ ++/* Our stored configuration */ ++struct saved_data { ++ /* ++ * The array of specifications, initially in the same order as in ++ * the specification file. Sorting occurs based on hasMetaChars. ++ */ ++ spec_t *spec_arr; ++ unsigned int nspec; ++ unsigned int ncomp; ++ ++ /* ++ * The array of regular expression stems. ++ */ ++ stem_t *stem_arr; ++ int num_stems; ++ int alloc_stems; ++}; ++ ++/* Return the length of the text that can be considered the stem, returns 0 ++ * if there is no identifiable stem */ ++static int get_stem_from_spec(const char *const buf) ++{ ++ const char *tmp = strchr(buf + 1, '/'); ++ const char *ind; ++ ++ if (!tmp) ++ return 0; ++ ++ for (ind = buf; ind < tmp; ind++) { ++ if (strchr(".^$?*+|[({", (int)*ind)) ++ return 0; ++ } ++ return tmp - buf; ++} ++ + /* return the length of the text that is the stem of a file name */ + static int get_stem_from_file_name(const char *const buf) + { +@@ -38,6 +91,41 @@ static int get_stem_from_file_name(const char *const buf) + return tmp - buf; + } + ++/* find the stem of a file spec, returns the index into stem_arr for a new ++ * or existing stem, (or -1 if there is no possible stem - IE for a file in ++ * the root directory or a regex that is too complex for us). */ ++static int find_stem_from_spec(struct saved_data *data, const char *buf) ++{ ++ int i, num = data->num_stems; ++ int stem_len = get_stem_from_spec(buf); ++ ++ if (!stem_len) ++ return -1; ++ for (i = 0; i < num; i++) { ++ if (stem_len == data->stem_arr[i].len ++ && !strncmp(buf, data->stem_arr[i].buf, stem_len)) ++ return i; ++ } ++ if (data->alloc_stems == num) { ++ stem_t *tmp_arr; ++ data->alloc_stems = data->alloc_stems * 2 + 16; ++ tmp_arr = realloc(data->stem_arr, ++ sizeof(stem_t) * data->alloc_stems); ++ if (!tmp_arr) ++ return -1; ++ data->stem_arr = tmp_arr; ++ } ++ data->stem_arr[num].len = stem_len; ++ data->stem_arr[num].buf = malloc(stem_len + 1); ++ if (!data->stem_arr[num].buf) ++ return -1; ++ memcpy(data->stem_arr[num].buf, buf, stem_len); ++ data->stem_arr[num].buf[stem_len] = '\0'; ++ data->num_stems++; ++ buf += stem_len; ++ return num; ++} ++ + /* find the stem of a file name, returns the index into stem_arr (or -1 if + * there is no match - IE for a file in the root directory or a regex that is + * too complex for us). Makes buf point to the text AFTER the stem. */ +@@ -94,17 +182,59 @@ static int nodups_specs(struct saved_data *data, const char *path) + return rc; + } + +-static int compile_regex(struct saved_data *data, struct spec *spec, const char **errbuf) ++/* Determine if the regular expression specification has any meta characters. */ ++static void spec_hasMetaChars(struct spec *spec) ++{ ++ char *c; ++ int len; ++ char *end; ++ ++ c = spec->regex_str; ++ len = strlen(spec->regex_str); ++ end = c + len; ++ ++ spec->hasMetaChars = 0; ++ ++ /* Look at each character in the RE specification string for a ++ * meta character. Return when any meta character reached. */ ++ while (c != end) { ++ switch (*c) { ++ case '.': ++ case '^': ++ case '$': ++ case '?': ++ case '*': ++ case '+': ++ case '|': ++ case '[': ++ case '(': ++ case '{': ++ spec->hasMetaChars = 1; ++ return; ++ case '\\': /* skip the next character */ ++ c++; ++ break; ++ default: ++ break; ++ ++ } ++ c++; ++ } ++ return; ++} ++ ++static int compile_regex(struct saved_data *data, spec_t *spec, char **errbuf) + { +- const char *tmperrbuf; + char *reg_buf, *anchored_regex, *cp; +- struct stem *stem_arr = data->stem_arr; ++ stem_t *stem_arr = data->stem_arr; + size_t len; +- int erroff; ++ int regerr; + + if (spec->regcomp) + return 0; /* already done */ + ++ data->ncomp++; /* how many compiled regexes required */ ++ + /* Skip the fixed stem. */ + reg_buf = spec->regex_str; + if (spec->stem_id >= 0) +@@ -115,7 +245,6 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char + cp = anchored_regex = malloc(len + 3); + if (!anchored_regex) + return -1; +- + /* Create ^...$ regexp. */ + *cp++ = '^'; + cp = mempcpy(cp, reg_buf, len); +@@ -123,20 +252,21 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char + *cp = '\0'; + + /* Compile the regular expression. */ +- spec->regex = pcre_compile(anchored_regex, 0, &tmperrbuf, &erroff, NULL); +- free(anchored_regex); +- if (!spec->regex) { +- if (errbuf) +- *errbuf=tmperrbuf; +- return -1; +- } +- +- spec->sd = pcre_study(spec->regex, 0, &tmperrbuf); +- if (!spec->sd) { +- if (errbuf) +- *errbuf=tmperrbuf; ++ regerr = regcomp(&spec->regex, anchored_regex, ++ REG_EXTENDED | REG_NOSUB); ++ if (regerr != 0) { ++ size_t errsz = 0; ++ errsz = regerror(regerr, &spec->regex, NULL, 0); ++ if (errsz && errbuf) ++ *errbuf = malloc(errsz); ++ if (errbuf && *errbuf) ++ (void)regerror(regerr, &spec->regex, ++ *errbuf, errsz); ++ ++ free(anchored_regex); + return -1; + } ++ free(anchored_regex); + + /* Done. */ + spec->regcomp = 1; +@@ -144,16 +274,16 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char + return 0; + } + ++ + static int process_line(struct selabel_handle *rec, + const char *path, const char *prefix, +- char *line_buf, unsigned lineno) ++ char *line_buf, int pass, unsigned lineno) + { +- int items, len, rc; ++ int items, len; + char *buf_p, *regex, *type, *context; + struct saved_data *data = (struct saved_data *)rec->data; +- struct spec *spec_arr; ++ spec_t *spec_arr = data->spec_arr; + unsigned int nspec = data->nspec; +- const char *errbuf = NULL; + + len = strlen(line_buf); + if (line_buf[len - 1] == '\n') +@@ -188,91 +318,77 @@ static int process_line(struct selabel_handle *rec, + return 0; + } + +- rc = grow_specs(data); +- if (rc) +- return rc; +- +- spec_arr = data->spec_arr; +- +- /* process and store the specification in spec. */ +- spec_arr[nspec].stem_id = find_stem_from_spec(data, regex); +- spec_arr[nspec].regex_str = regex; +- if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) { +- COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid regex %s: %s\n", +- path, lineno, regex, (errbuf ? errbuf : "out of memory")); +- } +- +- /* Convert the type string to a mode format */ +- spec_arr[nspec].type_str = type; +- spec_arr[nspec].mode = 0; +- if (type) { +- mode_t mode = string_to_mode(type); +- if (mode == -1) { +- COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid file type %s\n", +- path, lineno, type); +- mode = 0; ++ if (pass == 1) { ++ /* On the second pass, process and store the specification in spec. */ ++ char *errbuf = NULL; ++ spec_arr[nspec].stem_id = find_stem_from_spec(data, regex); ++ spec_arr[nspec].regex_str = regex; ++ if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) { ++ COMPAT_LOG(SELINUX_WARNING, ++ "%s: line %d has invalid regex %s: %s\n", ++ path, lineno, regex, ++ (errbuf ? errbuf : "out of memory")); + } +- spec_arr[nspec].mode = mode; +- } +- +- spec_arr[nspec].lr.ctx_raw = context; +- +- /* Determine if specification has +- * any meta characters in the RE */ +- spec_hasMetaChars(&spec_arr[nspec]); + +- if (strcmp(context, "<>") && rec->validating) +- compat_validate(rec, &spec_arr[nspec].lr, path, lineno); +- +- data->nspec = ++nspec; +- +- return 0; +-} +- +-static int process_file(const char *path, const char *suffix, struct selabel_handle *rec, const char *prefix) +-{ +- FILE *fp; +- struct stat sb; +- unsigned int lineno; +- size_t line_len; +- char *line_buf = NULL; +- int rc; +- char stack_path[PATH_MAX + 1]; +- +- /* append the path suffix if we have one */ +- if (suffix) { +- rc = snprintf(stack_path, sizeof(stack_path), "%s.%s", path, suffix); +- if (rc >= sizeof(stack_path)) { +- errno = ENAMETOOLONG; +- return -1; ++ /* Convert the type string to a mode format */ ++ spec_arr[nspec].type_str = type; ++ spec_arr[nspec].mode = 0; ++ if (!type) ++ goto skip_type; ++ len = strlen(type); ++ if (type[0] != '-' || len != 2) { ++ COMPAT_LOG(SELINUX_WARNING, ++ "%s: line %d has invalid file type %s\n", ++ path, lineno, type); ++ return 0; ++ } ++ switch (type[1]) { ++ case 'b': ++ spec_arr[nspec].mode = S_IFBLK; ++ break; ++ case 'c': ++ spec_arr[nspec].mode = S_IFCHR; ++ break; ++ case 'd': ++ spec_arr[nspec].mode = S_IFDIR; ++ break; ++ case 'p': ++ spec_arr[nspec].mode = S_IFIFO; ++ break; ++ case 'l': ++ spec_arr[nspec].mode = S_IFLNK; ++ break; ++ case 's': ++ spec_arr[nspec].mode = S_IFSOCK; ++ break; ++ case '-': ++ spec_arr[nspec].mode = S_IFREG; ++ break; ++ default: ++ COMPAT_LOG(SELINUX_WARNING, ++ "%s: line %d has invalid file type %s\n", ++ path, lineno, type); ++ return 0; + } +- path = stack_path; +- } + +- /* Open the specification file. */ +- if ((fp = fopen(path, "r")) == NULL) +- return -1; +- __fsetlocking(fp, FSETLOCKING_BYCALLER); ++ skip_type: ++ spec_arr[nspec].lr.ctx_raw = context; + +- if (fstat(fileno(fp), &sb) < 0) +- return -1; +- if (!S_ISREG(sb.st_mode)) { +- errno = EINVAL; +- return -1; +- } ++ /* Determine if specification has ++ * any meta characters in the RE */ ++ spec_hasMetaChars(&spec_arr[nspec]); + +- /* +- * The do detailed validation of the input and fill the spec array +- */ +- lineno = 0; +- while (getline(&line_buf, &line_len, fp) > 0) { +- rc = process_line(rec, path, prefix, line_buf, ++lineno); +- if (rc) +- return rc; ++ if (strcmp(context, "<>") && rec->validating) ++ compat_validate(rec, &spec_arr[nspec].lr, path, lineno); + } +- free(line_buf); +- fclose(fp); + ++ data->nspec = ++nspec; ++ if (pass == 0) { ++ free(regex); ++ if (type) ++ free(type); ++ free(context); ++ } + return 0; + } + +@@ -282,8 +398,18 @@ 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; ++ FILE *fp; ++ FILE *localfp = NULL; ++ FILE *homedirfp = NULL; ++ char local_path[PATH_MAX + 1]; ++ char homedir_path[PATH_MAX + 1]; + char subs_file[PATH_MAX + 1]; ++ char *line_buf = NULL; ++ size_t line_len = 0; ++ unsigned int lineno, pass, i, j, maxnspec; ++ spec_t *spec_copy = NULL; + int status = -1, baseonly = 0; ++ struct stat sb; + + /* Process arguments */ + while (n--) +@@ -303,7 +429,6 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, + if (!path) { + rec->subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->subs); + rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs); +- path = selinux_file_context_path(); + } else { + snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path); + rec->subs = selabel_subs_init(subs_file, rec->subs); +@@ -311,37 +436,126 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, + rec->subs = selabel_subs_init(subs_file, rec->subs); + } + ++ /* Open the specification file. */ ++ if (!path) ++ path = selinux_file_context_path(); ++ if ((fp = fopen(path, "r")) == NULL) ++ return -1; ++ __fsetlocking(fp, FSETLOCKING_BYCALLER); ++ ++ if (fstat(fileno(fp), &sb) < 0) ++ return -1; ++ if (!S_ISREG(sb.st_mode)) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (!baseonly) { ++ snprintf(homedir_path, sizeof(homedir_path), "%s.homedirs", ++ path); ++ homedirfp = fopen(homedir_path, "r"); ++ if (homedirfp != NULL) ++ __fsetlocking(homedirfp, FSETLOCKING_BYCALLER); ++ ++ snprintf(local_path, sizeof(local_path), "%s.local", path); ++ localfp = fopen(local_path, "r"); ++ if (localfp != NULL) ++ __fsetlocking(localfp, FSETLOCKING_BYCALLER); ++ } + rec->spec_file = strdup(path); + + /* +- * The do detailed validation of the input and fill the spec array ++ * Perform two passes over the specification file. ++ * The first pass counts the number of specifications and ++ * performs simple validation of the input. At the end ++ * of the first pass, the spec array is allocated. ++ * The second pass performs detailed validation of the input ++ * and fills in the spec array. + */ +- status = process_file(path, NULL, rec, prefix); +- if (status) +- goto finish; ++ maxnspec = UINT_MAX / sizeof(spec_t); ++ for (pass = 0; pass < 2; pass++) { ++ data->nspec = 0; ++ data->ncomp = 0; ++ ++ lineno = 0; ++ while (getline(&line_buf, &line_len, fp) > 0) { ++ if (data->nspec >= maxnspec) ++ break; ++ status = process_line(rec, path, prefix, line_buf, pass, ++lineno); ++ if (status) ++ goto finish; ++ } + +- if (rec->validating) { +- status = nodups_specs(data, path); +- if (status) +- goto finish; +- } ++ if (pass == 1 && rec->validating) { ++ status = nodups_specs(data, path); ++ if (status) ++ goto finish; ++ } + +- if (!baseonly) { +- status = process_file(path, "homedirs", rec, prefix); +- if (status && errno != ENOENT) +- goto finish; ++ lineno = 0; ++ if (homedirfp) ++ while (getline(&line_buf, &line_len, homedirfp) > 0) { ++ if (data->nspec >= maxnspec) ++ break; ++ status = process_line(rec, homedir_path, prefix, line_buf, pass, ++lineno); ++ if (status) ++ goto finish; ++ } + +- status = process_file(path, "local", rec, prefix); +- if (status && errno != ENOENT) +- goto finish; ++ lineno = 0; ++ if (localfp) ++ while (getline(&line_buf, &line_len, localfp) > 0) { ++ if (data->nspec >= maxnspec) ++ break; ++ status = process_line(rec, local_path, prefix, line_buf, pass, ++lineno); ++ if (status) ++ goto finish; ++ } ++ ++ if (pass == 0) { ++ if (data->nspec == 0) { ++ status = 0; ++ goto finish; ++ } ++ data->spec_arr = calloc(data->nspec, sizeof(spec_t)); ++ if (!data->spec_arr) ++ goto finish; ++ ++ maxnspec = data->nspec; ++ rewind(fp); ++ if (homedirfp) ++ rewind(homedirfp); ++ if (localfp) ++ rewind(localfp); ++ } + } ++ free(line_buf); + +- status = sort_specs(data); ++ /* Move exact pathname specifications to the end. */ ++ spec_copy = malloc(sizeof(spec_t) * data->nspec); ++ if (!spec_copy) ++ goto finish; ++ j = 0; ++ for (i = 0; i < data->nspec; i++) ++ if (data->spec_arr[i].hasMetaChars) ++ memcpy(&spec_copy[j++], ++ &data->spec_arr[i], sizeof(spec_t)); ++ for (i = 0; i < data->nspec; i++) ++ if (!data->spec_arr[i].hasMetaChars) ++ memcpy(&spec_copy[j++], ++ &data->spec_arr[i], sizeof(spec_t)); ++ free(data->spec_arr); ++ data->spec_arr = spec_copy; + + status = 0; + finish: +- if (status) ++ fclose(fp); ++ if (data->spec_arr != spec_copy) + free(data->spec_arr); ++ if (homedirfp) ++ fclose(homedirfp); ++ if (localfp) ++ fclose(localfp); + return status; + } + +@@ -361,10 +575,7 @@ static void closef(struct selabel_handle *rec) + free(spec->type_str); + free(spec->lr.ctx_raw); + free(spec->lr.ctx_trans); +- if (spec->regcomp) { +- pcre_free(spec->regex); +- pcre_free_study(spec->sd); +- } ++ regfree(&spec->regex); + } + + for (i = 0; i < (unsigned int)data->num_stems; i++) { +@@ -384,7 +595,7 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec, + const char *key, int type) + { + struct saved_data *data = (struct saved_data *)rec->data; +- struct spec *spec_arr = data->spec_arr; ++ spec_t *spec_arr = data->spec_arr; + int i, rc, file_stem; + mode_t mode = (mode_t)type; + const char *buf; +@@ -423,24 +634,26 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec, + * the last matching specification is used. + */ + for (i = data->nspec - 1; i >= 0; i--) { +- struct spec *spec = &spec_arr[i]; + /* if the spec in question matches no stem or has the same + * stem as the file AND if the spec in question has no mode + * specified or if the mode matches the file mode then we do + * a regex check */ +- if ((spec->stem_id == -1 || spec->stem_id == file_stem) && +- (!mode || !spec->mode || mode == spec->mode)) { +- if (compile_regex(data, spec, NULL) < 0) ++ if ((spec_arr[i].stem_id == -1 ++ || spec_arr[i].stem_id == file_stem) ++ && (!mode || !spec_arr[i].mode ++ || mode == spec_arr[i].mode)) { ++ if (compile_regex(data, &spec_arr[i], NULL) < 0) + goto finish; +- if (spec->stem_id == -1) +- rc = pcre_exec(spec->regex, get_pcre_extra(spec), key, strlen(key), 0, 0, NULL, 0); ++ if (spec_arr[i].stem_id == -1) ++ rc = regexec(&spec_arr[i].regex, key, 0, 0, 0); + else +- rc = pcre_exec(spec->regex, get_pcre_extra(spec), buf, strlen(buf), 0, 0, NULL, 0); ++ rc = regexec(&spec_arr[i].regex, buf, 0, 0, 0); + + if (rc == 0) { +- spec->matches++; ++ spec_arr[i].matches++; + break; +- } else if (rc == PCRE_ERROR_NOMATCH) ++ } ++ if (rc == REG_NOMATCH) + continue; + /* else it's an error */ + goto finish; +@@ -464,7 +677,7 @@ static void stats(struct selabel_handle *rec) + { + struct saved_data *data = (struct saved_data *)rec->data; + unsigned int i, nspec = data->nspec; +- struct spec *spec_arr = data->spec_arr; ++ spec_t *spec_arr = data->spec_arr; + + for (i = 0; i < nspec; i++) { + if (spec_arr[i].matches == 0) { +diff --git a/src/label_file.h b/src/label_file.h +deleted file mode 100644 +index cb5633b..0000000 +--- a/src/label_file.h ++++ /dev/null +@@ -1,273 +0,0 @@ +-#ifndef _SELABEL_FILE_H_ +-#define _SELABEL_FILE_H_ +- +-#include +- +-#include "label_internal.h" +- +-/* A file security context specification. */ +-struct spec { +- struct selabel_lookup_rec lr; /* holds contexts for lookup result */ +- char *regex_str; /* regular expession string for diagnostics */ +- char *type_str; /* type string for diagnostic messages */ +- pcre *regex; /* compiled regular expression */ +- pcre_extra *sd; /* extra compiled stuff */ +- mode_t mode; /* mode format value */ +- int matches; /* number of matching pathnames */ +- int stem_id; /* indicates which stem-compression item */ +- char hasMetaChars; /* regular expression has meta-chars */ +- char regcomp; /* regex_str has been compiled to regex */ +-}; +- +-/* A regular expression stem */ +-struct stem { +- char *buf; +- int len; +-}; +- +-/* Our stored configuration */ +-struct saved_data { +- /* +- * The array of specifications, initially in the same order as in +- * the specification file. Sorting occurs based on hasMetaChars. +- */ +- struct spec *spec_arr; +- unsigned int nspec; +- unsigned int alloc_specs; +- +- /* +- * The array of regular expression stems. +- */ +- struct stem *stem_arr; +- int num_stems; +- int alloc_stems; +-}; +- +-static inline pcre_extra *get_pcre_extra(struct spec *spec) +-{ +- return spec->sd; +-} +- +-static inline mode_t string_to_mode(char *mode) +-{ +- size_t len; +- +- if (!mode) +- return 0; +- len = strlen(mode); +- if (mode[0] != '-' || len != 2) +- return -1; +- switch (mode[1]) { +- case 'b': +- return S_IFBLK; +- case 'c': +- return S_IFCHR; +- case 'd': +- return S_IFDIR; +- case 'p': +- return S_IFIFO; +- case 'l': +- return S_IFLNK; +- case 's': +- return S_IFSOCK; +- case '-': +- return S_IFREG; +- default: +- return -1; +- } +- /* impossible to get here */ +- return 0; +-} +- +-static inline int grow_specs(struct saved_data *data) +-{ +- struct spec *specs; +- size_t new_specs, total_specs; +- +- if (data->nspec < data->alloc_specs) +- return 0; +- +- new_specs = data->nspec + 16; +- total_specs = data->nspec + new_specs; +- +- specs = realloc(data->spec_arr, total_specs * sizeof(*specs)); +- if (!specs) { +- perror("realloc"); +- return -1; +- } +- +- /* blank the new entries */ +- memset(&specs[data->nspec], 0, new_specs * sizeof(*specs)); +- +- data->spec_arr = specs; +- data->alloc_specs = total_specs; +- return 0; +-} +- +-/* Determine if the regular expression specification has any meta characters. */ +-static inline void spec_hasMetaChars(struct spec *spec) +-{ +- char *c; +- int len; +- char *end; +- +- c = spec->regex_str; +- len = strlen(spec->regex_str); +- end = c + len; +- +- spec->hasMetaChars = 0; +- +- /* Look at each character in the RE specification string for a +- * meta character. Return when any meta character reached. */ +- while (c < end) { +- switch (*c) { +- case '.': +- case '^': +- case '$': +- case '?': +- case '*': +- case '+': +- case '|': +- case '[': +- case '(': +- case '{': +- spec->hasMetaChars = 1; +- return; +- case '\\': /* skip the next character */ +- c++; +- break; +- default: +- break; +- +- } +- c++; +- } +- return; +-} +- +-/* Move exact pathname specifications to the end. */ +-static inline int sort_specs(struct saved_data *data) +-{ +- struct spec *spec_copy; +- struct spec spec; +- int i; +- int front, back; +- size_t len = sizeof(*spec_copy); +- +- spec_copy = malloc(len * data->nspec); +- if (!spec_copy) +- return -1; +- +- /* first move the exact pathnames to the back */ +- front = 0; +- back = data->nspec - 1; +- for (i = 0; i < data->nspec; i++) { +- if (data->spec_arr[i].hasMetaChars) +- memcpy(&spec_copy[front++], &data->spec_arr[i], len); +- else +- memcpy(&spec_copy[back--], &data->spec_arr[i], len); +- } +- +- /* +- * now the exact pathnames are at the end, but they are in the reverse order. +- * since 'front' is now the first of the 'exact' we can run that part of the +- * array switching the front and back element. +- */ +- back = data->nspec - 1; +- while (front < back) { +- /* save the front */ +- memcpy(&spec, &spec_copy[front], len); +- /* move the back to the front */ +- memcpy(&spec_copy[front], &spec_copy[back], len); +- /* put the old front in the back */ +- memcpy(&spec_copy[back], &spec, len); +- front++; +- back--; +- } +- +- free(data->spec_arr); +- data->spec_arr = spec_copy; +- +- return 0; +-} +- +-/* Return the length of the text that can be considered the stem, returns 0 +- * if there is no identifiable stem */ +-static inline int get_stem_from_spec(const char *const buf) +-{ +- const char *tmp = strchr(buf + 1, '/'); +- const char *ind; +- +- if (!tmp) +- return 0; +- +- for (ind = buf; ind < tmp; ind++) { +- if (strchr(".^$?*+|[({", (int)*ind)) +- return 0; +- } +- return tmp - buf; +-} +- +-/* +- * return the stemid given a string and a length +- */ +-static inline int find_stem(struct saved_data *data, const char *buf, int stem_len) +-{ +- int i; +- +- for (i = 0; i < data->num_stems; i++) { +- if (stem_len == data->stem_arr[i].len && +- !strncmp(buf, data->stem_arr[i].buf, stem_len)) +- return i; +- } +- +- return -1; +-} +- +-/* returns the index of the new stored object */ +-static inline int store_stem(struct saved_data *data, char *buf, int stem_len) +-{ +- int num = data->num_stems; +- +- if (data->alloc_stems == num) { +- struct stem *tmp_arr; +- +- data->alloc_stems = data->alloc_stems * 2 + 16; +- tmp_arr = realloc(data->stem_arr, +- sizeof(*tmp_arr) * data->alloc_stems); +- if (!tmp_arr) +- return -1; +- data->stem_arr = tmp_arr; +- } +- data->stem_arr[num].len = stem_len; +- data->stem_arr[num].buf = buf; +- data->num_stems++; +- +- return num; +-} +- +-/* find the stem of a file spec, returns the index into stem_arr for a new +- * or existing stem, (or -1 if there is no possible stem - IE for a file in +- * the root directory or a regex that is too complex for us). */ +-static inline int find_stem_from_spec(struct saved_data *data, const char *buf) +-{ +- int stem_len = get_stem_from_spec(buf); +- int stemid; +- char *stem; +- +- if (!stem_len) +- return -1; +- +- stemid = find_stem(data, buf, stem_len); +- if (stemid >= 0) +- return stemid; +- +- /* not found, allocate a new one */ +- stem = strndup(buf, stem_len); +- if (!stem) +- return -1; +- +- return store_stem(data, stem, stem_len); +-} +- +-#endif /* _SELABEL_FILE_H_ */ +-- +1.8.1.2 + diff --git a/recipes-security/selinux/libselinux_2.1.12.bb b/recipes-security/selinux/libselinux_2.1.12.bb index d881534..32fcdcd 100644 --- a/recipes-security/selinux/libselinux_2.1.12.bb +++ b/recipes-security/selinux/libselinux_2.1.12.bb @@ -1,4 +1,4 @@ -PR = "r1" +PR = "r2" include selinux_20120924.inc include ${BPN}.inc @@ -10,6 +10,6 @@ SRC_URI[sha256sum] = "8dad879380e0ce1e4ab67195a08f6052c1396493bcb12fe92a033f49f7 SRC_URI += "\ file://libselinux-fix-init-load-policy.patch \ - file://libselinux-pcre-link-order.patch \ file://libselinux-drop-Wno-unused-but-set-variable.patch \ + file://libselinux-revert-libpcre.patch \ "