]>
Commit | Line | Data |
---|---|---|
02274bb5 SS |
1 | diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h |
2 | index 1a54307..f6eeb21 100644 | |
3 | --- a/libselinux/include/selinux/label.h | |
4 | +++ b/libselinux/include/selinux/label.h | |
5 | @@ -46,8 +46,10 @@ struct selabel_handle; | |
9c27a234 SS |
6 | #define SELABEL_OPT_PATH 3 |
7 | /* select a subset of the search space as an optimization (file backend) */ | |
8 | #define SELABEL_OPT_SUBSET 4 | |
9 | +/* like subset, but an array of subsets */ | |
10 | +#define SELABEL_OPT_PREFIXES 5 | |
11 | /* total number of options */ | |
12 | -#define SELABEL_NOPT 5 | |
13 | +#define SELABEL_NOPT 6 | |
14 | ||
15 | /* | |
16 | * Label operations | |
02274bb5 SS |
17 | diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h |
18 | index 2985f6f..826ed71 100644 | |
19 | --- a/libselinux/include/selinux/selinux.h | |
20 | +++ b/libselinux/include/selinux/selinux.h | |
21 | @@ -139,7 +139,10 @@ struct av_decision { | |
9c27a234 SS |
22 | /* Structure for passing options, used by AVC and label subsystems */ |
23 | struct selinux_opt { | |
24 | int type; | |
25 | - const char *value; | |
26 | + union { | |
27 | + const char *value; | |
28 | + const char **values; | |
29 | + }; | |
30 | }; | |
31 | ||
32 | /* Callback facilities */ | |
02274bb5 | 33 | @@ -410,6 +413,11 @@ extern int matchpathcon_init(const char *path); |
9c27a234 SS |
34 | regexes that have stems that are prefixes of 'prefix'. */ |
35 | extern int matchpathcon_init_prefix(const char *path, const char *prefix); | |
36 | ||
37 | +/* Same as matchpathcon_init, but only load entries with | |
38 | + * regexes that have stems that are prefixes of the 'prefixes' | |
39 | + * array of entries. The last entry must be NULL. */ | |
40 | +extern int matchpathcon_init_prefixes(const char *patch, const char **prefixes); | |
41 | + | |
42 | /* Free the memory allocated by matchpathcon_init. */ | |
43 | extern void matchpathcon_fini(void); | |
44 | ||
02274bb5 SS |
45 | diff --git a/libselinux/man/man3/matchpathcon.3 b/libselinux/man/man3/matchpathcon.3 |
46 | index cdbb252..b6814ed 100644 | |
47 | --- a/libselinux/man/man3/matchpathcon.3 | |
48 | +++ b/libselinux/man/man3/matchpathcon.3 | |
49 | @@ -8,7 +8,9 @@ matchpathcon, matchpathcon_index \- get the default SELinux security context for | |
9c27a234 SS |
50 | |
51 | .BI "int matchpathcon_init(const char *" path ");" | |
52 | ||
53 | -.BI "int matchpathcon_init_prefix(const char *" path ", const char *" subset ");" | |
54 | +.BI "int matchpathcon_init_prefix(const char *" path ", const char *" prefix ");" | |
55 | + | |
56 | +.BI "int matchpathcon_init_prefixes(const char *" path ", const char **" prefixes ");" | |
57 | ||
58 | .BI "int matchpathcon_fini(void);" | |
59 | .sp | |
02274bb5 | 60 | @@ -50,6 +52,14 @@ by |
9c27a234 SS |
61 | .I prefix. |
62 | ||
63 | .sp | |
64 | +.B matchpathcon_init_prefixes | |
65 | +is the same as | |
66 | +.B matchpathcon_init_prefix | |
67 | +but takes an array of | |
68 | +.I prefixes | |
69 | +instead of a single prefix. The last entry in the array must be NULL. | |
70 | + | |
71 | +.sp | |
72 | .B matchpathcon_fini | |
73 | frees the memory allocated by a prior call to | |
74 | .B matchpathcon_init. | |
02274bb5 SS |
75 | diff --git a/libselinux/man/man3/selabel_open.3 b/libselinux/man/man3/selabel_open.3 |
76 | index 8674e37..89bb4d3 100644 | |
77 | --- a/libselinux/man/man3/selabel_open.3 | |
78 | +++ b/libselinux/man/man3/selabel_open.3 | |
79 | @@ -66,6 +66,13 @@ A non-null value for this option enables context validation. By default, | |
9c27a234 SS |
80 | is used; a custom validation function can be provided via |
81 | .BR selinux_set_callback (3). | |
82 | Note that an invalid context may not be treated as an error unless it is actually encountered during a lookup operation. | |
83 | +.TP | |
84 | +.B SELABEL_OPT_SUBSET | |
85 | +A ":" separates string of path prefixes that tell the system to only loads entries with regular expressions that could match this strings. For example "/dev:/var/run:/tmp". This option can cause the system to use less memory and work faster, but you should only use paths that begin with a prefix. | |
86 | +.TP | |
87 | +.B SELABEL_OPT_PATH | |
88 | +A string representing an alternate path the the regular expressions. | |
89 | +.sp | |
90 | ||
91 | .SH "BACKENDS" | |
92 | ||
02274bb5 | 93 | @@ -99,4 +106,3 @@ Eamon Walsh <ewalsh@tycho.nsa.gov> |
9c27a234 SS |
94 | .BR selabel_stats (3), |
95 | .BR selinux_set_callback (3), | |
96 | .BR selinux (8) | |
97 | - | |
02274bb5 SS |
98 | diff --git a/libselinux/src/callbacks.c b/libselinux/src/callbacks.c |
99 | index b245364..7c47222 100644 | |
100 | --- a/libselinux/src/callbacks.c | |
101 | +++ b/libselinux/src/callbacks.c | |
102 | @@ -16,6 +16,7 @@ default_selinux_log(int type __attribute__((unused)), const char *fmt, ...) | |
9c27a234 SS |
103 | { |
104 | int rc; | |
105 | va_list ap; | |
106 | + if (is_selinux_enabled() == 0) return 0; | |
107 | va_start(ap, fmt); | |
108 | rc = vfprintf(stderr, fmt, ap); | |
109 | va_end(ap); | |
02274bb5 SS |
110 | diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c |
111 | index ac11b37..42889cf 100644 | |
112 | --- a/libselinux/src/label_file.c | |
113 | +++ b/libselinux/src/label_file.c | |
9c27a234 SS |
114 | @@ -27,6 +27,7 @@ |
115 | * Internals, mostly moved over from matchpathcon.c | |
116 | */ | |
117 | ||
118 | +#define MAX_PREFIX 100 | |
119 | /* A file security context specification. */ | |
120 | typedef struct spec { | |
121 | struct selabel_lookup_rec lr; /* holds contexts for lookup result */ | |
02274bb5 | 122 | @@ -276,7 +277,7 @@ static int compile_regex(struct saved_data *data, spec_t *spec, char **errbuf) |
9c27a234 SS |
123 | |
124 | ||
125 | static int process_line(struct selabel_handle *rec, | |
126 | - const char *path, const char *prefix, | |
127 | + const char *path, const char **prefix_array, | |
128 | char *line_buf, int pass, unsigned lineno) | |
129 | { | |
130 | int items, len; | |
02274bb5 | 131 | @@ -310,12 +311,24 @@ static int process_line(struct selabel_handle *rec, |
9c27a234 SS |
132 | } |
133 | ||
134 | len = get_stem_from_spec(regex); | |
135 | - if (len && prefix && strncmp(prefix, regex, len)) { | |
136 | - /* Stem of regex does not match requested prefix, discard. */ | |
137 | - free(regex); | |
138 | - free(type); | |
139 | - free(context); | |
140 | - return 0; | |
141 | + if (len && prefix_array[0]) { | |
142 | + int i = 0; | |
143 | + int found = 0; | |
144 | + while (i < MAX_PREFIX && prefix_array[i]) { | |
145 | + if (strncmp(prefix_array[i], regex, len) == 0) { | |
146 | + found = 1; | |
147 | + break; | |
148 | + } | |
149 | + i++; | |
150 | + } | |
151 | + | |
152 | + if (! found) { | |
153 | + /* Stem of regex does not match requested prefix, discard. */ | |
154 | + free(regex); | |
155 | + free(type); | |
156 | + free(context); | |
157 | + return 0; | |
158 | + } | |
159 | } | |
160 | ||
161 | if (pass == 1) { | |
02274bb5 | 162 | @@ -397,7 +410,8 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, |
9c27a234 SS |
163 | { |
164 | struct saved_data *data = (struct saved_data *)rec->data; | |
165 | const char *path = NULL; | |
166 | - const char *prefix = NULL; | |
167 | + const char *static_prefix_array[2] = {NULL, }; | |
168 | + const char **prefix_array = static_prefix_array; | |
169 | FILE *fp; | |
170 | FILE *localfp = NULL; | |
171 | FILE *homedirfp = NULL; | |
02274bb5 | 172 | @@ -418,7 +432,10 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, |
9c27a234 SS |
173 | path = opts[n].value; |
174 | break; | |
175 | case SELABEL_OPT_SUBSET: | |
176 | - prefix = opts[n].value; | |
177 | + static_prefix_array[0] = opts[n].value; | |
178 | + break; | |
179 | + case SELABEL_OPT_PREFIXES: | |
180 | + prefix_array = opts[n].values; | |
181 | break; | |
182 | case SELABEL_OPT_BASEONLY: | |
183 | baseonly = !!opts[n].value; | |
02274bb5 | 184 | @@ -480,7 +497,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, |
9c27a234 SS |
185 | while (getline(&line_buf, &line_len, fp) > 0) { |
186 | if (data->nspec >= maxnspec) | |
187 | break; | |
188 | - status = process_line(rec, path, prefix, line_buf, pass, ++lineno); | |
189 | + status = process_line(rec, path, prefix_array, line_buf, pass, ++lineno); | |
190 | if (status) | |
191 | goto finish; | |
192 | } | |
02274bb5 | 193 | @@ -496,7 +513,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, |
9c27a234 SS |
194 | while (getline(&line_buf, &line_len, homedirfp) > 0) { |
195 | if (data->nspec >= maxnspec) | |
196 | break; | |
197 | - status = process_line(rec, homedir_path, prefix, line_buf, pass, ++lineno); | |
198 | + status = process_line(rec, homedir_path, prefix_array, line_buf, pass, ++lineno); | |
199 | if (status) | |
200 | goto finish; | |
201 | } | |
02274bb5 | 202 | @@ -506,7 +523,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, |
9c27a234 SS |
203 | while (getline(&line_buf, &line_len, localfp) > 0) { |
204 | if (data->nspec >= maxnspec) | |
205 | break; | |
206 | - status = process_line(rec, local_path, prefix, line_buf, pass, ++lineno); | |
207 | + status = process_line(rec, local_path, prefix_array, line_buf, pass, ++lineno); | |
208 | if (status) | |
209 | goto finish; | |
210 | } | |
02274bb5 SS |
211 | diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c |
212 | index c396add..489ef3a 100644 | |
213 | --- a/libselinux/src/matchpathcon.c | |
214 | +++ b/libselinux/src/matchpathcon.c | |
9c27a234 SS |
215 | @@ -2,6 +2,7 @@ |
216 | #include <string.h> | |
217 | #include <errno.h> | |
218 | #include <stdio.h> | |
219 | +#include <syslog.h> | |
220 | #include "selinux_internal.h" | |
221 | #include "label_internal.h" | |
222 | #include "callbacks.h" | |
02274bb5 | 223 | @@ -62,7 +63,7 @@ static void |
9c27a234 SS |
224 | { |
225 | va_list ap; | |
226 | va_start(ap, fmt); | |
227 | - vfprintf(stderr, fmt, ap); | |
228 | + vsyslog(LOG_ERR, fmt, ap); | |
229 | va_end(ap); | |
230 | } | |
231 | ||
02274bb5 | 232 | @@ -304,7 +305,7 @@ static void matchpathcon_init_once(void) |
9c27a234 SS |
233 | destructor_key_initialized = 1; |
234 | } | |
235 | ||
236 | -int matchpathcon_init_prefix(const char *path, const char *subset) | |
237 | +int matchpathcon_init_prefixes(const char *path, const char **prefixes) | |
238 | { | |
239 | if (!mycanoncon) | |
240 | mycanoncon = default_canoncon; | |
02274bb5 | 241 | @@ -312,15 +313,22 @@ int matchpathcon_init_prefix(const char *path, const char *subset) |
9c27a234 SS |
242 | __selinux_once(once, matchpathcon_init_once); |
243 | __selinux_setspecific(destructor_key, (void *)1); | |
244 | ||
245 | - options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET; | |
246 | - options[SELABEL_OPT_SUBSET].value = subset; | |
247 | + options[SELABEL_OPT_PREFIXES].type = SELABEL_OPT_PREFIXES; | |
248 | + options[SELABEL_OPT_PREFIXES].values = prefixes; | |
249 | options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH; | |
250 | options[SELABEL_OPT_PATH].value = path; | |
251 | ||
252 | hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT); | |
253 | return hnd ? 0 : -1; | |
254 | } | |
255 | +hidden_def(matchpathcon_init_prefixes) | |
256 | ||
257 | +int matchpathcon_init_prefix(const char *path, const char *prefix) | |
258 | +{ | |
259 | + const char *prefixes[2] = { prefix, NULL }; | |
260 | + | |
261 | + return matchpathcon_init_prefixes(path, prefixes); | |
262 | +} | |
263 | hidden_def(matchpathcon_init_prefix) | |
264 | ||
265 | int matchpathcon_init(const char *path) | |
02274bb5 SS |
266 | diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h |
267 | index 710396a..9a3fc14 100644 | |
268 | --- a/libselinux/src/selinux_internal.h | |
269 | +++ b/libselinux/src/selinux_internal.h | |
270 | @@ -80,6 +80,7 @@ hidden_proto(selinux_mkload_policy) | |
9c27a234 SS |
271 | hidden_proto(selinux_path) |
272 | hidden_proto(selinux_check_passwd_access) | |
273 | hidden_proto(selinux_check_securetty_context) | |
274 | + hidden_proto(matchpathcon_init_prefixes) | |
275 | hidden_proto(matchpathcon_init_prefix) | |
276 | hidden_proto(selinux_users_path) | |
277 | hidden_proto(selinux_usersconf_path); |