diff options
author | Xin Ouyang <Xin.Ouyang@windriver.com> | 2013-09-23 21:17:56 +0800 |
---|---|---|
committer | Joe MacDonald <joe@deserted.net> | 2013-10-02 13:24:44 -0400 |
commit | 9a6110e95f8231d954205d804856aebc569fdbc5 (patch) | |
tree | 1b324e31aa8cee97b92ea441b83829da509c13c1 | |
parent | d7faa4382668e10407133f800cea728f6b24d953 (diff) | |
download | meta-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.patch | 959 | ||||
-rw-r--r-- | recipes-security/selinux/libselinux_2.1.13.bb | 10 |
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 @@ | |||
1 | From e3016cb009d362235765af8b857ade754a97756f Mon Sep 17 00:00:00 2001 | ||
2 | From: Xin Ouyang <Xin.Ouyang@windriver.com> | ||
3 | Date: Thu, 23 May 2013 17:12:13 +0800 | ||
4 | Subject: [PATCH] libselinux: Revert libpcre for old refpolicy compatible | ||
5 | |||
6 | This reverts upstream libpcre commits. | ||
7 | |||
8 | libselinux 2.1.12 uses libpcre to do file path matching instead of glibc | ||
9 | regex. Because there are some differences between glibc regex and pcre | ||
10 | functions, this will cause wrong security contexts for files while using | ||
11 | old refpolicy. | ||
12 | |||
13 | This patch should be dropped while refpolicy is upreved to 2.20120725+. | ||
14 | |||
15 | Upstream-Status: Inappropriate [for old refpolicy] | ||
16 | |||
17 | Signed-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 | |||
25 | diff --git a/src/Makefile b/src/Makefile | ||
26 | index 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 | |||
38 | diff --git a/src/label_file.c b/src/label_file.c | ||
39 | index 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) { | ||
678 | diff --git a/src/label_file.h b/src/label_file.h | ||
679 | deleted file mode 100644 | ||
680 | index 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 | -- | ||
958 | 1.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 @@ | |||
1 | PR = "r2" | 1 | PR = "r0" |
2 | 2 | ||
3 | include selinux_20120924.inc | 3 | include selinux_20130423.inc |
4 | include ${BPN}.inc | 4 | include ${BPN}.inc |
5 | 5 | ||
6 | LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0" | 6 | LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0" |
7 | 7 | ||
8 | SRC_URI[md5sum] = "73270f384a032fad34b5fe075fa05ce2" | 8 | SRC_URI[md5sum] = "32bf7b5182977a8a9248a1eeefe49a22" |
9 | SRC_URI[sha256sum] = "8dad879380e0ce1e4ab67195a08f6052c1396493bcb12fe92a033f49f7dbca9e" | 9 | SRC_URI[sha256sum] = "57aad47c06b7ec18a76e8d9870539277a84cb40109cfdcf70ed3260bdb04447a" |
10 | 10 | ||
11 | SRC_URI += "\ | 11 | SRC_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 | " |