summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXin Ouyang <Xin.Ouyang@windriver.com>2013-09-23 21:17:56 +0800
committerJoe MacDonald <joe@deserted.net>2013-10-02 13:24:44 -0400
commit9a6110e95f8231d954205d804856aebc569fdbc5 (patch)
tree1b324e31aa8cee97b92ea441b83829da509c13c1
parentd7faa4382668e10407133f800cea728f6b24d953 (diff)
downloadmeta-selinux-9a6110e95f8231d954205d804856aebc569fdbc5.tar.gz
libselinux: migrate SRC_URI and patches to 2.1.13
We will also uprev refpolicy, so remove "revert-libpcre.patch". Signed-off-by: Xin Ouyang <Xin.Ouyang@windriver.com> Signed-off-by: Joe MacDonald <joe@deserted.net>
-rw-r--r--recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch959
-rw-r--r--recipes-security/selinux/libselinux_2.1.13.bb10
2 files changed, 5 insertions, 964 deletions
diff --git a/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch b/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch
deleted file mode 100644
index 2511e9c..0000000
--- a/recipes-security/selinux/libselinux/libselinux-revert-libpcre.patch
+++ /dev/null
@@ -1,959 +0,0 @@
1From e3016cb009d362235765af8b857ade754a97756f Mon Sep 17 00:00:00 2001
2From: Xin Ouyang <Xin.Ouyang@windriver.com>
3Date: Thu, 23 May 2013 17:12:13 +0800
4Subject: [PATCH] libselinux: Revert libpcre for old refpolicy compatible
5
6This reverts upstream libpcre commits.
7
8libselinux 2.1.12 uses libpcre to do file path matching instead of glibc
9regex. Because there are some differences between glibc regex and pcre
10functions, this will cause wrong security contexts for files while using
11old refpolicy.
12
13This patch should be dropped while refpolicy is upreved to 2.20120725+.
14
15Upstream-Status: Inappropriate [for old refpolicy]
16
17Signed-off-by: Xin Ouyang <Xin.Ouyang@windriver.com>
18---
19 src/Makefile | 2 -
20 src/label_file.c | 481 ++++++++++++++++++++++++++++++++------------
21 src/label_file.h | 273 -------------------------
22 3 files changed, 347 insertions(+), 409 deletions(-)
23 delete mode 100644 src/label_file.h
24
25diff --git a/src/Makefile b/src/Makefile
26index ac019df..74e53bb 100644
27--- a/src/Makefile
28+++ b/src/Makefile
29@@ -20,8 +20,6 @@ RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER))
30 RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM)
31 LIBBASE=$(shell basename $(LIBDIR))
32
33-LDFLAGS ?= -lpcre
34-
35 VERSION = $(shell cat ../VERSION)
36 LIBVERSION = 1
37
38diff --git a/src/label_file.c b/src/label_file.c
39index 02b3cd2..7bc46cc 100644
40--- a/src/label_file.c
41+++ b/src/label_file.c
42@@ -16,18 +16,71 @@
43 #include <ctype.h>
44 #include <errno.h>
45 #include <limits.h>
46-#include <pcre.h>
47+#include <regex.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include <unistd.h>
51 #include "callbacks.h"
52 #include "label_internal.h"
53-#include "label_file.h"
54
55 /*
56 * Internals, mostly moved over from matchpathcon.c
57 */
58
59+/* A file security context specification. */
60+typedef struct spec {
61+ struct selabel_lookup_rec lr; /* holds contexts for lookup result */
62+ char *regex_str; /* regular expession string for diagnostics */
63+ char *type_str; /* type string for diagnostic messages */
64+ regex_t regex; /* compiled regular expression */
65+ char regcomp; /* regex_str has been compiled to regex */
66+ mode_t mode; /* mode format value */
67+ int matches; /* number of matching pathnames */
68+ int hasMetaChars; /* regular expression has meta-chars */
69+ int stem_id; /* indicates which stem-compression item */
70+} spec_t;
71+
72+/* A regular expression stem */
73+typedef struct stem {
74+ char *buf;
75+ int len;
76+} stem_t;
77+
78+/* Our stored configuration */
79+struct saved_data {
80+ /*
81+ * The array of specifications, initially in the same order as in
82+ * the specification file. Sorting occurs based on hasMetaChars.
83+ */
84+ spec_t *spec_arr;
85+ unsigned int nspec;
86+ unsigned int ncomp;
87+
88+ /*
89+ * The array of regular expression stems.
90+ */
91+ stem_t *stem_arr;
92+ int num_stems;
93+ int alloc_stems;
94+};
95+
96+/* Return the length of the text that can be considered the stem, returns 0
97+ * if there is no identifiable stem */
98+static int get_stem_from_spec(const char *const buf)
99+{
100+ const char *tmp = strchr(buf + 1, '/');
101+ const char *ind;
102+
103+ if (!tmp)
104+ return 0;
105+
106+ for (ind = buf; ind < tmp; ind++) {
107+ if (strchr(".^$?*+|[({", (int)*ind))
108+ return 0;
109+ }
110+ return tmp - buf;
111+}
112+
113 /* return the length of the text that is the stem of a file name */
114 static int get_stem_from_file_name(const char *const buf)
115 {
116@@ -38,6 +91,41 @@ static int get_stem_from_file_name(const char *const buf)
117 return tmp - buf;
118 }
119
120+/* find the stem of a file spec, returns the index into stem_arr for a new
121+ * or existing stem, (or -1 if there is no possible stem - IE for a file in
122+ * the root directory or a regex that is too complex for us). */
123+static int find_stem_from_spec(struct saved_data *data, const char *buf)
124+{
125+ int i, num = data->num_stems;
126+ int stem_len = get_stem_from_spec(buf);
127+
128+ if (!stem_len)
129+ return -1;
130+ for (i = 0; i < num; i++) {
131+ if (stem_len == data->stem_arr[i].len
132+ && !strncmp(buf, data->stem_arr[i].buf, stem_len))
133+ return i;
134+ }
135+ if (data->alloc_stems == num) {
136+ stem_t *tmp_arr;
137+ data->alloc_stems = data->alloc_stems * 2 + 16;
138+ tmp_arr = realloc(data->stem_arr,
139+ sizeof(stem_t) * data->alloc_stems);
140+ if (!tmp_arr)
141+ return -1;
142+ data->stem_arr = tmp_arr;
143+ }
144+ data->stem_arr[num].len = stem_len;
145+ data->stem_arr[num].buf = malloc(stem_len + 1);
146+ if (!data->stem_arr[num].buf)
147+ return -1;
148+ memcpy(data->stem_arr[num].buf, buf, stem_len);
149+ data->stem_arr[num].buf[stem_len] = '\0';
150+ data->num_stems++;
151+ buf += stem_len;
152+ return num;
153+}
154+
155 /* find the stem of a file name, returns the index into stem_arr (or -1 if
156 * there is no match - IE for a file in the root directory or a regex that is
157 * too complex for us). Makes buf point to the text AFTER the stem. */
158@@ -94,17 +182,59 @@ static int nodups_specs(struct saved_data *data, const char *path)
159 return rc;
160 }
161
162-static int compile_regex(struct saved_data *data, struct spec *spec, const char **errbuf)
163+/* Determine if the regular expression specification has any meta characters. */
164+static void spec_hasMetaChars(struct spec *spec)
165+{
166+ char *c;
167+ int len;
168+ char *end;
169+
170+ c = spec->regex_str;
171+ len = strlen(spec->regex_str);
172+ end = c + len;
173+
174+ spec->hasMetaChars = 0;
175+
176+ /* Look at each character in the RE specification string for a
177+ * meta character. Return when any meta character reached. */
178+ while (c != end) {
179+ switch (*c) {
180+ case '.':
181+ case '^':
182+ case '$':
183+ case '?':
184+ case '*':
185+ case '+':
186+ case '|':
187+ case '[':
188+ case '(':
189+ case '{':
190+ spec->hasMetaChars = 1;
191+ return;
192+ case '\\': /* skip the next character */
193+ c++;
194+ break;
195+ default:
196+ break;
197+
198+ }
199+ c++;
200+ }
201+ return;
202+}
203+
204+static int compile_regex(struct saved_data *data, spec_t *spec, char **errbuf)
205 {
206- const char *tmperrbuf;
207 char *reg_buf, *anchored_regex, *cp;
208- struct stem *stem_arr = data->stem_arr;
209+ stem_t *stem_arr = data->stem_arr;
210 size_t len;
211- int erroff;
212+ int regerr;
213
214 if (spec->regcomp)
215 return 0; /* already done */
216
217+ data->ncomp++; /* how many compiled regexes required */
218+
219 /* Skip the fixed stem. */
220 reg_buf = spec->regex_str;
221 if (spec->stem_id >= 0)
222@@ -115,7 +245,6 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char
223 cp = anchored_regex = malloc(len + 3);
224 if (!anchored_regex)
225 return -1;
226-
227 /* Create ^...$ regexp. */
228 *cp++ = '^';
229 cp = mempcpy(cp, reg_buf, len);
230@@ -123,20 +252,21 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char
231 *cp = '\0';
232
233 /* Compile the regular expression. */
234- spec->regex = pcre_compile(anchored_regex, 0, &tmperrbuf, &erroff, NULL);
235- free(anchored_regex);
236- if (!spec->regex) {
237- if (errbuf)
238- *errbuf=tmperrbuf;
239- return -1;
240- }
241-
242- spec->sd = pcre_study(spec->regex, 0, &tmperrbuf);
243- if (!spec->sd) {
244- if (errbuf)
245- *errbuf=tmperrbuf;
246+ regerr = regcomp(&spec->regex, anchored_regex,
247+ REG_EXTENDED | REG_NOSUB);
248+ if (regerr != 0) {
249+ size_t errsz = 0;
250+ errsz = regerror(regerr, &spec->regex, NULL, 0);
251+ if (errsz && errbuf)
252+ *errbuf = malloc(errsz);
253+ if (errbuf && *errbuf)
254+ (void)regerror(regerr, &spec->regex,
255+ *errbuf, errsz);
256+
257+ free(anchored_regex);
258 return -1;
259 }
260+ free(anchored_regex);
261
262 /* Done. */
263 spec->regcomp = 1;
264@@ -144,16 +274,16 @@ static int compile_regex(struct saved_data *data, struct spec *spec, const char
265 return 0;
266 }
267
268+
269 static int process_line(struct selabel_handle *rec,
270 const char *path, const char *prefix,
271- char *line_buf, unsigned lineno)
272+ char *line_buf, int pass, unsigned lineno)
273 {
274- int items, len, rc;
275+ int items, len;
276 char *buf_p, *regex, *type, *context;
277 struct saved_data *data = (struct saved_data *)rec->data;
278- struct spec *spec_arr;
279+ spec_t *spec_arr = data->spec_arr;
280 unsigned int nspec = data->nspec;
281- const char *errbuf = NULL;
282
283 len = strlen(line_buf);
284 if (line_buf[len - 1] == '\n')
285@@ -188,91 +318,77 @@ static int process_line(struct selabel_handle *rec,
286 return 0;
287 }
288
289- rc = grow_specs(data);
290- if (rc)
291- return rc;
292-
293- spec_arr = data->spec_arr;
294-
295- /* process and store the specification in spec. */
296- spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
297- spec_arr[nspec].regex_str = regex;
298- if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) {
299- COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid regex %s: %s\n",
300- path, lineno, regex, (errbuf ? errbuf : "out of memory"));
301- }
302-
303- /* Convert the type string to a mode format */
304- spec_arr[nspec].type_str = type;
305- spec_arr[nspec].mode = 0;
306- if (type) {
307- mode_t mode = string_to_mode(type);
308- if (mode == -1) {
309- COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid file type %s\n",
310- path, lineno, type);
311- mode = 0;
312+ if (pass == 1) {
313+ /* On the second pass, process and store the specification in spec. */
314+ char *errbuf = NULL;
315+ spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
316+ spec_arr[nspec].regex_str = regex;
317+ if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) {
318+ COMPAT_LOG(SELINUX_WARNING,
319+ "%s: line %d has invalid regex %s: %s\n",
320+ path, lineno, regex,
321+ (errbuf ? errbuf : "out of memory"));
322 }
323- spec_arr[nspec].mode = mode;
324- }
325-
326- spec_arr[nspec].lr.ctx_raw = context;
327-
328- /* Determine if specification has
329- * any meta characters in the RE */
330- spec_hasMetaChars(&spec_arr[nspec]);
331
332- if (strcmp(context, "<<none>>") && rec->validating)
333- compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
334-
335- data->nspec = ++nspec;
336-
337- return 0;
338-}
339-
340-static int process_file(const char *path, const char *suffix, struct selabel_handle *rec, const char *prefix)
341-{
342- FILE *fp;
343- struct stat sb;
344- unsigned int lineno;
345- size_t line_len;
346- char *line_buf = NULL;
347- int rc;
348- char stack_path[PATH_MAX + 1];
349-
350- /* append the path suffix if we have one */
351- if (suffix) {
352- rc = snprintf(stack_path, sizeof(stack_path), "%s.%s", path, suffix);
353- if (rc >= sizeof(stack_path)) {
354- errno = ENAMETOOLONG;
355- return -1;
356+ /* Convert the type string to a mode format */
357+ spec_arr[nspec].type_str = type;
358+ spec_arr[nspec].mode = 0;
359+ if (!type)
360+ goto skip_type;
361+ len = strlen(type);
362+ if (type[0] != '-' || len != 2) {
363+ COMPAT_LOG(SELINUX_WARNING,
364+ "%s: line %d has invalid file type %s\n",
365+ path, lineno, type);
366+ return 0;
367+ }
368+ switch (type[1]) {
369+ case 'b':
370+ spec_arr[nspec].mode = S_IFBLK;
371+ break;
372+ case 'c':
373+ spec_arr[nspec].mode = S_IFCHR;
374+ break;
375+ case 'd':
376+ spec_arr[nspec].mode = S_IFDIR;
377+ break;
378+ case 'p':
379+ spec_arr[nspec].mode = S_IFIFO;
380+ break;
381+ case 'l':
382+ spec_arr[nspec].mode = S_IFLNK;
383+ break;
384+ case 's':
385+ spec_arr[nspec].mode = S_IFSOCK;
386+ break;
387+ case '-':
388+ spec_arr[nspec].mode = S_IFREG;
389+ break;
390+ default:
391+ COMPAT_LOG(SELINUX_WARNING,
392+ "%s: line %d has invalid file type %s\n",
393+ path, lineno, type);
394+ return 0;
395 }
396- path = stack_path;
397- }
398
399- /* Open the specification file. */
400- if ((fp = fopen(path, "r")) == NULL)
401- return -1;
402- __fsetlocking(fp, FSETLOCKING_BYCALLER);
403+ skip_type:
404+ spec_arr[nspec].lr.ctx_raw = context;
405
406- if (fstat(fileno(fp), &sb) < 0)
407- return -1;
408- if (!S_ISREG(sb.st_mode)) {
409- errno = EINVAL;
410- return -1;
411- }
412+ /* Determine if specification has
413+ * any meta characters in the RE */
414+ spec_hasMetaChars(&spec_arr[nspec]);
415
416- /*
417- * The do detailed validation of the input and fill the spec array
418- */
419- lineno = 0;
420- while (getline(&line_buf, &line_len, fp) > 0) {
421- rc = process_line(rec, path, prefix, line_buf, ++lineno);
422- if (rc)
423- return rc;
424+ if (strcmp(context, "<<none>>") && rec->validating)
425+ compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
426 }
427- free(line_buf);
428- fclose(fp);
429
430+ data->nspec = ++nspec;
431+ if (pass == 0) {
432+ free(regex);
433+ if (type)
434+ free(type);
435+ free(context);
436+ }
437 return 0;
438 }
439
440@@ -282,8 +398,18 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
441 struct saved_data *data = (struct saved_data *)rec->data;
442 const char *path = NULL;
443 const char *prefix = NULL;
444+ FILE *fp;
445+ FILE *localfp = NULL;
446+ FILE *homedirfp = NULL;
447+ char local_path[PATH_MAX + 1];
448+ char homedir_path[PATH_MAX + 1];
449 char subs_file[PATH_MAX + 1];
450+ char *line_buf = NULL;
451+ size_t line_len = 0;
452+ unsigned int lineno, pass, i, j, maxnspec;
453+ spec_t *spec_copy = NULL;
454 int status = -1, baseonly = 0;
455+ struct stat sb;
456
457 /* Process arguments */
458 while (n--)
459@@ -303,7 +429,6 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
460 if (!path) {
461 rec->subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->subs);
462 rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs);
463- path = selinux_file_context_path();
464 } else {
465 snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path);
466 rec->subs = selabel_subs_init(subs_file, rec->subs);
467@@ -311,37 +436,126 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
468 rec->subs = selabel_subs_init(subs_file, rec->subs);
469 }
470
471+ /* Open the specification file. */
472+ if (!path)
473+ path = selinux_file_context_path();
474+ if ((fp = fopen(path, "r")) == NULL)
475+ return -1;
476+ __fsetlocking(fp, FSETLOCKING_BYCALLER);
477+
478+ if (fstat(fileno(fp), &sb) < 0)
479+ return -1;
480+ if (!S_ISREG(sb.st_mode)) {
481+ errno = EINVAL;
482+ return -1;
483+ }
484+
485+ if (!baseonly) {
486+ snprintf(homedir_path, sizeof(homedir_path), "%s.homedirs",
487+ path);
488+ homedirfp = fopen(homedir_path, "r");
489+ if (homedirfp != NULL)
490+ __fsetlocking(homedirfp, FSETLOCKING_BYCALLER);
491+
492+ snprintf(local_path, sizeof(local_path), "%s.local", path);
493+ localfp = fopen(local_path, "r");
494+ if (localfp != NULL)
495+ __fsetlocking(localfp, FSETLOCKING_BYCALLER);
496+ }
497 rec->spec_file = strdup(path);
498
499 /*
500- * The do detailed validation of the input and fill the spec array
501+ * Perform two passes over the specification file.
502+ * The first pass counts the number of specifications and
503+ * performs simple validation of the input. At the end
504+ * of the first pass, the spec array is allocated.
505+ * The second pass performs detailed validation of the input
506+ * and fills in the spec array.
507 */
508- status = process_file(path, NULL, rec, prefix);
509- if (status)
510- goto finish;
511+ maxnspec = UINT_MAX / sizeof(spec_t);
512+ for (pass = 0; pass < 2; pass++) {
513+ data->nspec = 0;
514+ data->ncomp = 0;
515+
516+ lineno = 0;
517+ while (getline(&line_buf, &line_len, fp) > 0) {
518+ if (data->nspec >= maxnspec)
519+ break;
520+ status = process_line(rec, path, prefix, line_buf, pass, ++lineno);
521+ if (status)
522+ goto finish;
523+ }
524
525- if (rec->validating) {
526- status = nodups_specs(data, path);
527- if (status)
528- goto finish;
529- }
530+ if (pass == 1 && rec->validating) {
531+ status = nodups_specs(data, path);
532+ if (status)
533+ goto finish;
534+ }
535
536- if (!baseonly) {
537- status = process_file(path, "homedirs", rec, prefix);
538- if (status && errno != ENOENT)
539- goto finish;
540+ lineno = 0;
541+ if (homedirfp)
542+ while (getline(&line_buf, &line_len, homedirfp) > 0) {
543+ if (data->nspec >= maxnspec)
544+ break;
545+ status = process_line(rec, homedir_path, prefix, line_buf, pass, ++lineno);
546+ if (status)
547+ goto finish;
548+ }
549
550- status = process_file(path, "local", rec, prefix);
551- if (status && errno != ENOENT)
552- goto finish;
553+ lineno = 0;
554+ if (localfp)
555+ while (getline(&line_buf, &line_len, localfp) > 0) {
556+ if (data->nspec >= maxnspec)
557+ break;
558+ status = process_line(rec, local_path, prefix, line_buf, pass, ++lineno);
559+ if (status)
560+ goto finish;
561+ }
562+
563+ if (pass == 0) {
564+ if (data->nspec == 0) {
565+ status = 0;
566+ goto finish;
567+ }
568+ data->spec_arr = calloc(data->nspec, sizeof(spec_t));
569+ if (!data->spec_arr)
570+ goto finish;
571+
572+ maxnspec = data->nspec;
573+ rewind(fp);
574+ if (homedirfp)
575+ rewind(homedirfp);
576+ if (localfp)
577+ rewind(localfp);
578+ }
579 }
580+ free(line_buf);
581
582- status = sort_specs(data);
583+ /* Move exact pathname specifications to the end. */
584+ spec_copy = malloc(sizeof(spec_t) * data->nspec);
585+ if (!spec_copy)
586+ goto finish;
587+ j = 0;
588+ for (i = 0; i < data->nspec; i++)
589+ if (data->spec_arr[i].hasMetaChars)
590+ memcpy(&spec_copy[j++],
591+ &data->spec_arr[i], sizeof(spec_t));
592+ for (i = 0; i < data->nspec; i++)
593+ if (!data->spec_arr[i].hasMetaChars)
594+ memcpy(&spec_copy[j++],
595+ &data->spec_arr[i], sizeof(spec_t));
596+ free(data->spec_arr);
597+ data->spec_arr = spec_copy;
598
599 status = 0;
600 finish:
601- if (status)
602+ fclose(fp);
603+ if (data->spec_arr != spec_copy)
604 free(data->spec_arr);
605+ if (homedirfp)
606+ fclose(homedirfp);
607+ if (localfp)
608+ fclose(localfp);
609 return status;
610 }
611
612@@ -361,10 +575,7 @@ static void closef(struct selabel_handle *rec)
613 free(spec->type_str);
614 free(spec->lr.ctx_raw);
615 free(spec->lr.ctx_trans);
616- if (spec->regcomp) {
617- pcre_free(spec->regex);
618- pcre_free_study(spec->sd);
619- }
620+ regfree(&spec->regex);
621 }
622
623 for (i = 0; i < (unsigned int)data->num_stems; i++) {
624@@ -384,7 +595,7 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
625 const char *key, int type)
626 {
627 struct saved_data *data = (struct saved_data *)rec->data;
628- struct spec *spec_arr = data->spec_arr;
629+ spec_t *spec_arr = data->spec_arr;
630 int i, rc, file_stem;
631 mode_t mode = (mode_t)type;
632 const char *buf;
633@@ -423,24 +634,26 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
634 * the last matching specification is used.
635 */
636 for (i = data->nspec - 1; i >= 0; i--) {
637- struct spec *spec = &spec_arr[i];
638 /* if the spec in question matches no stem or has the same
639 * stem as the file AND if the spec in question has no mode
640 * specified or if the mode matches the file mode then we do
641 * a regex check */
642- if ((spec->stem_id == -1 || spec->stem_id == file_stem) &&
643- (!mode || !spec->mode || mode == spec->mode)) {
644- if (compile_regex(data, spec, NULL) < 0)
645+ if ((spec_arr[i].stem_id == -1
646+ || spec_arr[i].stem_id == file_stem)
647+ && (!mode || !spec_arr[i].mode
648+ || mode == spec_arr[i].mode)) {
649+ if (compile_regex(data, &spec_arr[i], NULL) < 0)
650 goto finish;
651- if (spec->stem_id == -1)
652- rc = pcre_exec(spec->regex, get_pcre_extra(spec), key, strlen(key), 0, 0, NULL, 0);
653+ if (spec_arr[i].stem_id == -1)
654+ rc = regexec(&spec_arr[i].regex, key, 0, 0, 0);
655 else
656- rc = pcre_exec(spec->regex, get_pcre_extra(spec), buf, strlen(buf), 0, 0, NULL, 0);
657+ rc = regexec(&spec_arr[i].regex, buf, 0, 0, 0);
658
659 if (rc == 0) {
660- spec->matches++;
661+ spec_arr[i].matches++;
662 break;
663- } else if (rc == PCRE_ERROR_NOMATCH)
664+ }
665+ if (rc == REG_NOMATCH)
666 continue;
667 /* else it's an error */
668 goto finish;
669@@ -464,7 +677,7 @@ static void stats(struct selabel_handle *rec)
670 {
671 struct saved_data *data = (struct saved_data *)rec->data;
672 unsigned int i, nspec = data->nspec;
673- struct spec *spec_arr = data->spec_arr;
674+ spec_t *spec_arr = data->spec_arr;
675
676 for (i = 0; i < nspec; i++) {
677 if (spec_arr[i].matches == 0) {
678diff --git a/src/label_file.h b/src/label_file.h
679deleted file mode 100644
680index cb5633b..0000000
681--- a/src/label_file.h
682+++ /dev/null
683@@ -1,273 +0,0 @@
684-#ifndef _SELABEL_FILE_H_
685-#define _SELABEL_FILE_H_
686-
687-#include <sys/stat.h>
688-
689-#include "label_internal.h"
690-
691-/* A file security context specification. */
692-struct spec {
693- struct selabel_lookup_rec lr; /* holds contexts for lookup result */
694- char *regex_str; /* regular expession string for diagnostics */
695- char *type_str; /* type string for diagnostic messages */
696- pcre *regex; /* compiled regular expression */
697- pcre_extra *sd; /* extra compiled stuff */
698- mode_t mode; /* mode format value */
699- int matches; /* number of matching pathnames */
700- int stem_id; /* indicates which stem-compression item */
701- char hasMetaChars; /* regular expression has meta-chars */
702- char regcomp; /* regex_str has been compiled to regex */
703-};
704-
705-/* A regular expression stem */
706-struct stem {
707- char *buf;
708- int len;
709-};
710-
711-/* Our stored configuration */
712-struct saved_data {
713- /*
714- * The array of specifications, initially in the same order as in
715- * the specification file. Sorting occurs based on hasMetaChars.
716- */
717- struct spec *spec_arr;
718- unsigned int nspec;
719- unsigned int alloc_specs;
720-
721- /*
722- * The array of regular expression stems.
723- */
724- struct stem *stem_arr;
725- int num_stems;
726- int alloc_stems;
727-};
728-
729-static inline pcre_extra *get_pcre_extra(struct spec *spec)
730-{
731- return spec->sd;
732-}
733-
734-static inline mode_t string_to_mode(char *mode)
735-{
736- size_t len;
737-
738- if (!mode)
739- return 0;
740- len = strlen(mode);
741- if (mode[0] != '-' || len != 2)
742- return -1;
743- switch (mode[1]) {
744- case 'b':
745- return S_IFBLK;
746- case 'c':
747- return S_IFCHR;
748- case 'd':
749- return S_IFDIR;
750- case 'p':
751- return S_IFIFO;
752- case 'l':
753- return S_IFLNK;
754- case 's':
755- return S_IFSOCK;
756- case '-':
757- return S_IFREG;
758- default:
759- return -1;
760- }
761- /* impossible to get here */
762- return 0;
763-}
764-
765-static inline int grow_specs(struct saved_data *data)
766-{
767- struct spec *specs;
768- size_t new_specs, total_specs;
769-
770- if (data->nspec < data->alloc_specs)
771- return 0;
772-
773- new_specs = data->nspec + 16;
774- total_specs = data->nspec + new_specs;
775-
776- specs = realloc(data->spec_arr, total_specs * sizeof(*specs));
777- if (!specs) {
778- perror("realloc");
779- return -1;
780- }
781-
782- /* blank the new entries */
783- memset(&specs[data->nspec], 0, new_specs * sizeof(*specs));
784-
785- data->spec_arr = specs;
786- data->alloc_specs = total_specs;
787- return 0;
788-}
789-
790-/* Determine if the regular expression specification has any meta characters. */
791-static inline void spec_hasMetaChars(struct spec *spec)
792-{
793- char *c;
794- int len;
795- char *end;
796-
797- c = spec->regex_str;
798- len = strlen(spec->regex_str);
799- end = c + len;
800-
801- spec->hasMetaChars = 0;
802-
803- /* Look at each character in the RE specification string for a
804- * meta character. Return when any meta character reached. */
805- while (c < end) {
806- switch (*c) {
807- case '.':
808- case '^':
809- case '$':
810- case '?':
811- case '*':
812- case '+':
813- case '|':
814- case '[':
815- case '(':
816- case '{':
817- spec->hasMetaChars = 1;
818- return;
819- case '\\': /* skip the next character */
820- c++;
821- break;
822- default:
823- break;
824-
825- }
826- c++;
827- }
828- return;
829-}
830-
831-/* Move exact pathname specifications to the end. */
832-static inline int sort_specs(struct saved_data *data)
833-{
834- struct spec *spec_copy;
835- struct spec spec;
836- int i;
837- int front, back;
838- size_t len = sizeof(*spec_copy);
839-
840- spec_copy = malloc(len * data->nspec);
841- if (!spec_copy)
842- return -1;
843-
844- /* first move the exact pathnames to the back */
845- front = 0;
846- back = data->nspec - 1;
847- for (i = 0; i < data->nspec; i++) {
848- if (data->spec_arr[i].hasMetaChars)
849- memcpy(&spec_copy[front++], &data->spec_arr[i], len);
850- else
851- memcpy(&spec_copy[back--], &data->spec_arr[i], len);
852- }
853-
854- /*
855- * now the exact pathnames are at the end, but they are in the reverse order.
856- * since 'front' is now the first of the 'exact' we can run that part of the
857- * array switching the front and back element.
858- */
859- back = data->nspec - 1;
860- while (front < back) {
861- /* save the front */
862- memcpy(&spec, &spec_copy[front], len);
863- /* move the back to the front */
864- memcpy(&spec_copy[front], &spec_copy[back], len);
865- /* put the old front in the back */
866- memcpy(&spec_copy[back], &spec, len);
867- front++;
868- back--;
869- }
870-
871- free(data->spec_arr);
872- data->spec_arr = spec_copy;
873-
874- return 0;
875-}
876-
877-/* Return the length of the text that can be considered the stem, returns 0
878- * if there is no identifiable stem */
879-static inline int get_stem_from_spec(const char *const buf)
880-{
881- const char *tmp = strchr(buf + 1, '/');
882- const char *ind;
883-
884- if (!tmp)
885- return 0;
886-
887- for (ind = buf; ind < tmp; ind++) {
888- if (strchr(".^$?*+|[({", (int)*ind))
889- return 0;
890- }
891- return tmp - buf;
892-}
893-
894-/*
895- * return the stemid given a string and a length
896- */
897-static inline int find_stem(struct saved_data *data, const char *buf, int stem_len)
898-{
899- int i;
900-
901- for (i = 0; i < data->num_stems; i++) {
902- if (stem_len == data->stem_arr[i].len &&
903- !strncmp(buf, data->stem_arr[i].buf, stem_len))
904- return i;
905- }
906-
907- return -1;
908-}
909-
910-/* returns the index of the new stored object */
911-static inline int store_stem(struct saved_data *data, char *buf, int stem_len)
912-{
913- int num = data->num_stems;
914-
915- if (data->alloc_stems == num) {
916- struct stem *tmp_arr;
917-
918- data->alloc_stems = data->alloc_stems * 2 + 16;
919- tmp_arr = realloc(data->stem_arr,
920- sizeof(*tmp_arr) * data->alloc_stems);
921- if (!tmp_arr)
922- return -1;
923- data->stem_arr = tmp_arr;
924- }
925- data->stem_arr[num].len = stem_len;
926- data->stem_arr[num].buf = buf;
927- data->num_stems++;
928-
929- return num;
930-}
931-
932-/* find the stem of a file spec, returns the index into stem_arr for a new
933- * or existing stem, (or -1 if there is no possible stem - IE for a file in
934- * the root directory or a regex that is too complex for us). */
935-static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
936-{
937- int stem_len = get_stem_from_spec(buf);
938- int stemid;
939- char *stem;
940-
941- if (!stem_len)
942- return -1;
943-
944- stemid = find_stem(data, buf, stem_len);
945- if (stemid >= 0)
946- return stemid;
947-
948- /* not found, allocate a new one */
949- stem = strndup(buf, stem_len);
950- if (!stem)
951- return -1;
952-
953- return store_stem(data, stem, stem_len);
954-}
955-
956-#endif /* _SELABEL_FILE_H_ */
957--
9581.8.1.2
959
diff --git a/recipes-security/selinux/libselinux_2.1.13.bb b/recipes-security/selinux/libselinux_2.1.13.bb
index 32fcdcd..404d6f5 100644
--- a/recipes-security/selinux/libselinux_2.1.13.bb
+++ b/recipes-security/selinux/libselinux_2.1.13.bb
@@ -1,15 +1,15 @@
1PR = "r2" 1PR = "r0"
2 2
3include selinux_20120924.inc 3include selinux_20130423.inc
4include ${BPN}.inc 4include ${BPN}.inc
5 5
6LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0" 6LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0"
7 7
8SRC_URI[md5sum] = "73270f384a032fad34b5fe075fa05ce2" 8SRC_URI[md5sum] = "32bf7b5182977a8a9248a1eeefe49a22"
9SRC_URI[sha256sum] = "8dad879380e0ce1e4ab67195a08f6052c1396493bcb12fe92a033f49f7dbca9e" 9SRC_URI[sha256sum] = "57aad47c06b7ec18a76e8d9870539277a84cb40109cfdcf70ed3260bdb04447a"
10 10
11SRC_URI += "\ 11SRC_URI += "\
12 file://libselinux-fix-init-load-policy.patch \ 12 file://libselinux-fix-init-load-policy.patch \
13 file://libselinux-pcre-link-order.patch \
13 file://libselinux-drop-Wno-unused-but-set-variable.patch \ 14 file://libselinux-drop-Wno-unused-but-set-variable.patch \
14 file://libselinux-revert-libpcre.patch \
15 " 15 "