diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 431 |
1 files changed, 259 insertions, 172 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index bdf1ed7ca45b..811adb5e9fea 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -9,53 +9,74 @@ | |||
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/security.h> | 11 | #include <linux/security.h> |
12 | #include <linux/hardirq.h> | ||
13 | #include "common.h" | 12 | #include "common.h" |
14 | 13 | ||
14 | static struct tomoyo_profile tomoyo_default_profile = { | ||
15 | .learning = &tomoyo_default_profile.preference, | ||
16 | .permissive = &tomoyo_default_profile.preference, | ||
17 | .enforcing = &tomoyo_default_profile.preference, | ||
18 | .preference.enforcing_verbose = true, | ||
19 | .preference.learning_max_entry = 2048, | ||
20 | .preference.learning_verbose = false, | ||
21 | .preference.permissive_verbose = true | ||
22 | }; | ||
23 | |||
24 | /* Profile version. Currently only 20090903 is defined. */ | ||
25 | static unsigned int tomoyo_profile_version; | ||
26 | |||
27 | /* Profile table. Memory is allocated as needed. */ | ||
28 | static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; | ||
29 | |||
15 | /* String table for functionality that takes 4 modes. */ | 30 | /* String table for functionality that takes 4 modes. */ |
16 | static const char *tomoyo_mode_4[4] = { | 31 | static const char *tomoyo_mode_4[4] = { |
17 | "disabled", "learning", "permissive", "enforcing" | 32 | "disabled", "learning", "permissive", "enforcing" |
18 | }; | 33 | }; |
19 | /* String table for functionality that takes 2 modes. */ | ||
20 | static const char *tomoyo_mode_2[4] = { | ||
21 | "disabled", "enabled", "enabled", "enabled" | ||
22 | }; | ||
23 | 34 | ||
24 | /* | 35 | /* String table for /sys/kernel/security/tomoyo/profile */ |
25 | * tomoyo_control_array is a static data which contains | 36 | static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX |
26 | * | 37 | + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { |
27 | * (1) functionality name used by /sys/kernel/security/tomoyo/profile . | 38 | [TOMOYO_MAC_FILE_EXECUTE] = "file::execute", |
28 | * (2) initial values for "struct tomoyo_profile". | 39 | [TOMOYO_MAC_FILE_OPEN] = "file::open", |
29 | * (3) max values for "struct tomoyo_profile". | 40 | [TOMOYO_MAC_FILE_CREATE] = "file::create", |
30 | */ | 41 | [TOMOYO_MAC_FILE_UNLINK] = "file::unlink", |
31 | static struct { | 42 | [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir", |
32 | const char *keyword; | 43 | [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir", |
33 | unsigned int current_value; | 44 | [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo", |
34 | const unsigned int max_value; | 45 | [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock", |
35 | } tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = { | 46 | [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate", |
36 | [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 }, | 47 | [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink", |
37 | [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX }, | 48 | [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite", |
38 | [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, | 49 | [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock", |
50 | [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar", | ||
51 | [TOMOYO_MAC_FILE_LINK] = "file::link", | ||
52 | [TOMOYO_MAC_FILE_RENAME] = "file::rename", | ||
53 | [TOMOYO_MAC_FILE_CHMOD] = "file::chmod", | ||
54 | [TOMOYO_MAC_FILE_CHOWN] = "file::chown", | ||
55 | [TOMOYO_MAC_FILE_CHGRP] = "file::chgrp", | ||
56 | [TOMOYO_MAC_FILE_IOCTL] = "file::ioctl", | ||
57 | [TOMOYO_MAC_FILE_CHROOT] = "file::chroot", | ||
58 | [TOMOYO_MAC_FILE_MOUNT] = "file::mount", | ||
59 | [TOMOYO_MAC_FILE_UMOUNT] = "file::umount", | ||
60 | [TOMOYO_MAC_FILE_PIVOT_ROOT] = "file::pivot_root", | ||
61 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", | ||
39 | }; | 62 | }; |
40 | 63 | ||
41 | /* | ||
42 | * tomoyo_profile is a structure which is used for holding the mode of access | ||
43 | * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing. | ||
44 | * An administrator can define up to 256 profiles. | ||
45 | * The ->profile of "struct tomoyo_domain_info" is used for remembering | ||
46 | * the profile's number (0 - 255) assigned to that domain. | ||
47 | */ | ||
48 | static struct tomoyo_profile { | ||
49 | unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; | ||
50 | const struct tomoyo_path_info *comment; | ||
51 | } *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; | ||
52 | |||
53 | /* Permit policy management by non-root user? */ | 64 | /* Permit policy management by non-root user? */ |
54 | static bool tomoyo_manage_by_non_root; | 65 | static bool tomoyo_manage_by_non_root; |
55 | 66 | ||
56 | /* Utility functions. */ | 67 | /* Utility functions. */ |
57 | 68 | ||
58 | /** | 69 | /** |
70 | * tomoyo_yesno - Return "yes" or "no". | ||
71 | * | ||
72 | * @value: Bool value. | ||
73 | */ | ||
74 | static const char *tomoyo_yesno(const unsigned int value) | ||
75 | { | ||
76 | return value ? "yes" : "no"; | ||
77 | } | ||
78 | |||
79 | /** | ||
59 | * tomoyo_print_name_union - Print a tomoyo_name_union. | 80 | * tomoyo_print_name_union - Print a tomoyo_name_union. |
60 | * | 81 | * |
61 | * @head: Pointer to "struct tomoyo_io_buffer". | 82 | * @head: Pointer to "struct tomoyo_io_buffer". |
@@ -154,80 +175,62 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) | |||
154 | } | 175 | } |
155 | 176 | ||
156 | /** | 177 | /** |
157 | * tomoyo_check_flags - Check mode for specified functionality. | ||
158 | * | ||
159 | * @domain: Pointer to "struct tomoyo_domain_info". | ||
160 | * @index: The functionality to check mode. | ||
161 | * | ||
162 | * TOMOYO checks only process context. | ||
163 | * This code disables TOMOYO's enforcement in case the function is called from | ||
164 | * interrupt context. | ||
165 | */ | ||
166 | unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, | ||
167 | const u8 index) | ||
168 | { | ||
169 | const u8 profile = domain->profile; | ||
170 | |||
171 | if (WARN_ON(in_interrupt())) | ||
172 | return 0; | ||
173 | return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX | ||
174 | #if TOMOYO_MAX_PROFILES != 256 | ||
175 | && profile < TOMOYO_MAX_PROFILES | ||
176 | #endif | ||
177 | && tomoyo_profile_ptr[profile] ? | ||
178 | tomoyo_profile_ptr[profile]->value[index] : 0; | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode. | ||
183 | * | ||
184 | * @domain: Pointer to "struct tomoyo_domain_info". | ||
185 | * | ||
186 | * Returns true if domain policy violation warning should be printed to | ||
187 | * console. | ||
188 | */ | ||
189 | bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain) | ||
190 | { | ||
191 | return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0; | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * tomoyo_find_or_assign_new_profile - Create a new profile. | 178 | * tomoyo_find_or_assign_new_profile - Create a new profile. |
196 | * | 179 | * |
197 | * @profile: Profile number to create. | 180 | * @profile: Profile number to create. |
198 | * | 181 | * |
199 | * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. | 182 | * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. |
200 | */ | 183 | */ |
201 | static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned | 184 | static struct tomoyo_profile *tomoyo_find_or_assign_new_profile |
202 | int profile) | 185 | (const unsigned int profile) |
203 | { | 186 | { |
204 | struct tomoyo_profile *ptr = NULL; | 187 | struct tomoyo_profile *ptr; |
205 | int i; | 188 | struct tomoyo_profile *entry; |
206 | |||
207 | if (profile >= TOMOYO_MAX_PROFILES) | 189 | if (profile >= TOMOYO_MAX_PROFILES) |
208 | return NULL; | 190 | return NULL; |
209 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | ||
210 | return NULL; | ||
211 | ptr = tomoyo_profile_ptr[profile]; | 191 | ptr = tomoyo_profile_ptr[profile]; |
212 | if (ptr) | 192 | if (ptr) |
213 | goto ok; | 193 | return ptr; |
214 | ptr = kmalloc(sizeof(*ptr), GFP_NOFS); | 194 | entry = kzalloc(sizeof(*entry), GFP_NOFS); |
215 | if (!tomoyo_memory_ok(ptr)) { | 195 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
216 | kfree(ptr); | 196 | goto out; |
217 | ptr = NULL; | 197 | ptr = tomoyo_profile_ptr[profile]; |
218 | goto ok; | 198 | if (!ptr && tomoyo_memory_ok(entry)) { |
199 | ptr = entry; | ||
200 | ptr->learning = &tomoyo_default_profile.preference; | ||
201 | ptr->permissive = &tomoyo_default_profile.preference; | ||
202 | ptr->enforcing = &tomoyo_default_profile.preference; | ||
203 | ptr->default_config = TOMOYO_CONFIG_DISABLED; | ||
204 | memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, | ||
205 | sizeof(ptr->config)); | ||
206 | mb(); /* Avoid out-of-order execution. */ | ||
207 | tomoyo_profile_ptr[profile] = ptr; | ||
208 | entry = NULL; | ||
219 | } | 209 | } |
220 | for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) | ||
221 | ptr->value[i] = tomoyo_control_array[i].current_value; | ||
222 | mb(); /* Avoid out-of-order execution. */ | ||
223 | tomoyo_profile_ptr[profile] = ptr; | ||
224 | ok: | ||
225 | mutex_unlock(&tomoyo_policy_lock); | 210 | mutex_unlock(&tomoyo_policy_lock); |
211 | out: | ||
212 | kfree(entry); | ||
226 | return ptr; | 213 | return ptr; |
227 | } | 214 | } |
228 | 215 | ||
229 | /** | 216 | /** |
230 | * tomoyo_write_profile - Write to profile table. | 217 | * tomoyo_profile - Find a profile. |
218 | * | ||
219 | * @profile: Profile number to find. | ||
220 | * | ||
221 | * Returns pointer to "struct tomoyo_profile". | ||
222 | */ | ||
223 | struct tomoyo_profile *tomoyo_profile(const u8 profile) | ||
224 | { | ||
225 | struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile]; | ||
226 | if (!tomoyo_policy_loaded) | ||
227 | return &tomoyo_default_profile; | ||
228 | BUG_ON(!ptr); | ||
229 | return ptr; | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * tomoyo_write_profile - Write profile table. | ||
231 | * | 234 | * |
232 | * @head: Pointer to "struct tomoyo_io_buffer". | 235 | * @head: Pointer to "struct tomoyo_io_buffer". |
233 | * | 236 | * |
@@ -237,64 +240,116 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
237 | { | 240 | { |
238 | char *data = head->write_buf; | 241 | char *data = head->write_buf; |
239 | unsigned int i; | 242 | unsigned int i; |
240 | unsigned int value; | 243 | int value; |
244 | int mode; | ||
245 | u8 config; | ||
246 | bool use_default = false; | ||
241 | char *cp; | 247 | char *cp; |
242 | struct tomoyo_profile *profile; | 248 | struct tomoyo_profile *profile; |
243 | unsigned long num; | 249 | if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1) |
244 | 250 | return 0; | |
245 | cp = strchr(data, '-'); | 251 | i = simple_strtoul(data, &cp, 10); |
246 | if (cp) | 252 | if (data == cp) { |
247 | *cp = '\0'; | 253 | profile = &tomoyo_default_profile; |
248 | if (strict_strtoul(data, 10, &num)) | 254 | } else { |
249 | return -EINVAL; | 255 | if (*cp != '-') |
250 | if (cp) | 256 | return -EINVAL; |
251 | data = cp + 1; | 257 | data = cp + 1; |
252 | profile = tomoyo_find_or_assign_new_profile(num); | 258 | profile = tomoyo_find_or_assign_new_profile(i); |
253 | if (!profile) | 259 | if (!profile) |
254 | return -EINVAL; | 260 | return -EINVAL; |
261 | } | ||
255 | cp = strchr(data, '='); | 262 | cp = strchr(data, '='); |
256 | if (!cp) | 263 | if (!cp) |
257 | return -EINVAL; | 264 | return -EINVAL; |
258 | *cp = '\0'; | 265 | *cp++ = '\0'; |
266 | if (profile != &tomoyo_default_profile) | ||
267 | use_default = strstr(cp, "use_default") != NULL; | ||
268 | if (strstr(cp, "verbose=yes")) | ||
269 | value = 1; | ||
270 | else if (strstr(cp, "verbose=no")) | ||
271 | value = 0; | ||
272 | else | ||
273 | value = -1; | ||
274 | if (!strcmp(data, "PREFERENCE::enforcing")) { | ||
275 | if (use_default) { | ||
276 | profile->enforcing = &tomoyo_default_profile.preference; | ||
277 | return 0; | ||
278 | } | ||
279 | profile->enforcing = &profile->preference; | ||
280 | if (value >= 0) | ||
281 | profile->preference.enforcing_verbose = value; | ||
282 | return 0; | ||
283 | } | ||
284 | if (!strcmp(data, "PREFERENCE::permissive")) { | ||
285 | if (use_default) { | ||
286 | profile->permissive = &tomoyo_default_profile.preference; | ||
287 | return 0; | ||
288 | } | ||
289 | profile->permissive = &profile->preference; | ||
290 | if (value >= 0) | ||
291 | profile->preference.permissive_verbose = value; | ||
292 | return 0; | ||
293 | } | ||
294 | if (!strcmp(data, "PREFERENCE::learning")) { | ||
295 | char *cp2; | ||
296 | if (use_default) { | ||
297 | profile->learning = &tomoyo_default_profile.preference; | ||
298 | return 0; | ||
299 | } | ||
300 | profile->learning = &profile->preference; | ||
301 | if (value >= 0) | ||
302 | profile->preference.learning_verbose = value; | ||
303 | cp2 = strstr(cp, "max_entry="); | ||
304 | if (cp2) | ||
305 | sscanf(cp2 + 10, "%u", | ||
306 | &profile->preference.learning_max_entry); | ||
307 | return 0; | ||
308 | } | ||
309 | if (profile == &tomoyo_default_profile) | ||
310 | return -EINVAL; | ||
259 | if (!strcmp(data, "COMMENT")) { | 311 | if (!strcmp(data, "COMMENT")) { |
260 | const struct tomoyo_path_info *old_comment = profile->comment; | 312 | const struct tomoyo_path_info *old_comment = profile->comment; |
261 | profile->comment = tomoyo_get_name(cp + 1); | 313 | profile->comment = tomoyo_get_name(cp); |
262 | tomoyo_put_name(old_comment); | 314 | tomoyo_put_name(old_comment); |
263 | return 0; | 315 | return 0; |
264 | } | 316 | } |
265 | for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { | 317 | if (!strcmp(data, "CONFIG")) { |
266 | if (strcmp(data, tomoyo_control_array[i].keyword)) | 318 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; |
267 | continue; | 319 | config = profile->default_config; |
268 | if (sscanf(cp + 1, "%u", &value) != 1) { | 320 | } else if (tomoyo_str_starts(&data, "CONFIG::")) { |
269 | int j; | 321 | config = 0; |
270 | const char **modes; | 322 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { |
271 | switch (i) { | 323 | if (strcmp(data, tomoyo_mac_keywords[i])) |
272 | case TOMOYO_VERBOSE: | 324 | continue; |
273 | modes = tomoyo_mode_2; | 325 | config = profile->config[i]; |
274 | break; | 326 | break; |
275 | default: | ||
276 | modes = tomoyo_mode_4; | ||
277 | break; | ||
278 | } | ||
279 | for (j = 0; j < 4; j++) { | ||
280 | if (strcmp(cp + 1, modes[j])) | ||
281 | continue; | ||
282 | value = j; | ||
283 | break; | ||
284 | } | ||
285 | if (j == 4) | ||
286 | return -EINVAL; | ||
287 | } else if (value > tomoyo_control_array[i].max_value) { | ||
288 | value = tomoyo_control_array[i].max_value; | ||
289 | } | 327 | } |
290 | profile->value[i] = value; | 328 | if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) |
291 | return 0; | 329 | return -EINVAL; |
330 | } else { | ||
331 | return -EINVAL; | ||
292 | } | 332 | } |
293 | return -EINVAL; | 333 | if (use_default) { |
334 | config = TOMOYO_CONFIG_USE_DEFAULT; | ||
335 | } else { | ||
336 | for (mode = 3; mode >= 0; mode--) | ||
337 | if (strstr(cp, tomoyo_mode_4[mode])) | ||
338 | /* | ||
339 | * Update lower 3 bits in order to distinguish | ||
340 | * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. | ||
341 | */ | ||
342 | config = (config & ~7) | mode; | ||
343 | } | ||
344 | if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) | ||
345 | profile->config[i] = config; | ||
346 | else if (config != TOMOYO_CONFIG_USE_DEFAULT) | ||
347 | profile->default_config = config; | ||
348 | return 0; | ||
294 | } | 349 | } |
295 | 350 | ||
296 | /** | 351 | /** |
297 | * tomoyo_read_profile - Read from profile table. | 352 | * tomoyo_read_profile - Read profile table. |
298 | * | 353 | * |
299 | * @head: Pointer to "struct tomoyo_io_buffer". | 354 | * @head: Pointer to "struct tomoyo_io_buffer". |
300 | * | 355 | * |
@@ -302,53 +357,82 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
302 | */ | 357 | */ |
303 | static int tomoyo_read_profile(struct tomoyo_io_buffer *head) | 358 | static int tomoyo_read_profile(struct tomoyo_io_buffer *head) |
304 | { | 359 | { |
305 | static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; | 360 | int index; |
306 | int step; | ||
307 | |||
308 | if (head->read_eof) | 361 | if (head->read_eof) |
309 | return 0; | 362 | return 0; |
310 | for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; | 363 | if (head->read_bit) |
311 | step++) { | 364 | goto body; |
312 | const u8 index = step / total; | 365 | tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); |
313 | u8 type = step % total; | 366 | tomoyo_io_printf(head, "PREFERENCE::learning={ verbose=%s " |
367 | "max_entry=%u }\n", | ||
368 | tomoyo_yesno(tomoyo_default_profile.preference. | ||
369 | learning_verbose), | ||
370 | tomoyo_default_profile.preference.learning_max_entry); | ||
371 | tomoyo_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n", | ||
372 | tomoyo_yesno(tomoyo_default_profile.preference. | ||
373 | permissive_verbose)); | ||
374 | tomoyo_io_printf(head, "PREFERENCE::enforcing={ verbose=%s }\n", | ||
375 | tomoyo_yesno(tomoyo_default_profile.preference. | ||
376 | enforcing_verbose)); | ||
377 | head->read_bit = 1; | ||
378 | body: | ||
379 | for (index = head->read_step; index < TOMOYO_MAX_PROFILES; index++) { | ||
380 | bool done; | ||
381 | u8 config; | ||
382 | int i; | ||
383 | int pos; | ||
314 | const struct tomoyo_profile *profile | 384 | const struct tomoyo_profile *profile |
315 | = tomoyo_profile_ptr[index]; | 385 | = tomoyo_profile_ptr[index]; |
316 | head->read_step = step; | 386 | const struct tomoyo_path_info *comment; |
387 | head->read_step = index; | ||
317 | if (!profile) | 388 | if (!profile) |
318 | continue; | 389 | continue; |
319 | if (!type) { /* Print profile' comment tag. */ | 390 | pos = head->read_avail; |
320 | if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", | 391 | comment = profile->comment; |
321 | index, profile->comment ? | 392 | done = tomoyo_io_printf(head, "%u-COMMENT=%s\n", index, |
322 | profile->comment->name : "")) | 393 | comment ? comment->name : ""); |
323 | break; | 394 | if (!done) |
324 | continue; | 395 | goto out; |
325 | } | 396 | config = profile->default_config; |
326 | type--; | 397 | if (!tomoyo_io_printf(head, "%u-CONFIG={ mode=%s }\n", index, |
327 | if (type < TOMOYO_MAX_CONTROL_INDEX) { | 398 | tomoyo_mode_4[config & 3])) |
328 | const unsigned int value = profile->value[type]; | 399 | goto out; |
329 | const char **modes = NULL; | 400 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX + |
330 | const char *keyword | 401 | TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { |
331 | = tomoyo_control_array[type].keyword; | 402 | config = profile->config[i]; |
332 | switch (tomoyo_control_array[type].max_value) { | 403 | if (config == TOMOYO_CONFIG_USE_DEFAULT) |
333 | case 3: | 404 | continue; |
334 | modes = tomoyo_mode_4; | 405 | if (!tomoyo_io_printf(head, |
335 | break; | 406 | "%u-CONFIG::%s={ mode=%s }\n", |
336 | case 1: | 407 | index, tomoyo_mac_keywords[i], |
337 | modes = tomoyo_mode_2; | 408 | tomoyo_mode_4[config & 3])) |
338 | break; | 409 | goto out; |
339 | } | ||
340 | if (modes) { | ||
341 | if (!tomoyo_io_printf(head, "%u-%s=%s\n", index, | ||
342 | keyword, modes[value])) | ||
343 | break; | ||
344 | } else { | ||
345 | if (!tomoyo_io_printf(head, "%u-%s=%u\n", index, | ||
346 | keyword, value)) | ||
347 | break; | ||
348 | } | ||
349 | } | 410 | } |
411 | if (profile->learning != &tomoyo_default_profile.preference && | ||
412 | !tomoyo_io_printf(head, "%u-PREFERENCE::learning={ " | ||
413 | "verbose=%s max_entry=%u }\n", index, | ||
414 | tomoyo_yesno(profile->preference. | ||
415 | learning_verbose), | ||
416 | profile->preference.learning_max_entry)) | ||
417 | goto out; | ||
418 | if (profile->permissive != &tomoyo_default_profile.preference | ||
419 | && !tomoyo_io_printf(head, "%u-PREFERENCE::permissive={ " | ||
420 | "verbose=%s }\n", index, | ||
421 | tomoyo_yesno(profile->preference. | ||
422 | permissive_verbose))) | ||
423 | goto out; | ||
424 | if (profile->enforcing != &tomoyo_default_profile.preference && | ||
425 | !tomoyo_io_printf(head, "%u-PREFERENCE::enforcing={ " | ||
426 | "verbose=%s }\n", index, | ||
427 | tomoyo_yesno(profile->preference. | ||
428 | enforcing_verbose))) | ||
429 | goto out; | ||
430 | continue; | ||
431 | out: | ||
432 | head->read_avail = pos; | ||
433 | break; | ||
350 | } | 434 | } |
351 | if (step == TOMOYO_MAX_PROFILES * total) | 435 | if (index == TOMOYO_MAX_PROFILES) |
352 | head->read_eof = true; | 436 | head->read_eof = true; |
353 | return 0; | 437 | return 0; |
354 | } | 438 | } |
@@ -1595,7 +1679,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head) | |||
1595 | static int tomoyo_read_version(struct tomoyo_io_buffer *head) | 1679 | static int tomoyo_read_version(struct tomoyo_io_buffer *head) |
1596 | { | 1680 | { |
1597 | if (!head->read_eof) { | 1681 | if (!head->read_eof) { |
1598 | tomoyo_io_printf(head, "2.2.0"); | 1682 | tomoyo_io_printf(head, "2.3.0-pre"); |
1599 | head->read_eof = true; | 1683 | head->read_eof = true; |
1600 | } | 1684 | } |
1601 | return 0; | 1685 | return 0; |
@@ -1915,6 +1999,9 @@ void tomoyo_check_profile(void) | |||
1915 | profile, domain->domainname->name); | 1999 | profile, domain->domainname->name); |
1916 | } | 2000 | } |
1917 | tomoyo_read_unlock(idx); | 2001 | tomoyo_read_unlock(idx); |
1918 | printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n"); | 2002 | if (tomoyo_profile_version != 20090903) |
2003 | panic("Profile version %u is not supported.\n", | ||
2004 | tomoyo_profile_version); | ||
2005 | printk(KERN_INFO "TOMOYO: 2.3.0-pre 2010/06/03\n"); | ||
1919 | printk(KERN_INFO "Mandatory Access Control activated.\n"); | 2006 | printk(KERN_INFO "Mandatory Access Control activated.\n"); |
1920 | } | 2007 | } |