diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 195 |
1 files changed, 121 insertions, 74 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 7cb6c0459d96..30e4b08905e3 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -302,6 +302,124 @@ struct tomoyo_profile *tomoyo_profile(const u8 profile) | |||
302 | return ptr; | 302 | return ptr; |
303 | } | 303 | } |
304 | 304 | ||
305 | static s8 tomoyo_find_yesno(const char *string, const char *find) | ||
306 | { | ||
307 | const char *cp = strstr(string, find); | ||
308 | if (cp) { | ||
309 | cp += strlen(find); | ||
310 | if (!strncmp(cp, "=yes", 4)) | ||
311 | return 1; | ||
312 | else if (!strncmp(cp, "=no", 3)) | ||
313 | return 0; | ||
314 | } | ||
315 | return -1; | ||
316 | } | ||
317 | |||
318 | static void tomoyo_set_bool(bool *b, const char *string, const char *find) | ||
319 | { | ||
320 | switch (tomoyo_find_yesno(string, find)) { | ||
321 | case 1: | ||
322 | *b = true; | ||
323 | break; | ||
324 | case 0: | ||
325 | *b = false; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | static void tomoyo_set_uint(unsigned int *i, const char *string, | ||
331 | const char *find) | ||
332 | { | ||
333 | const char *cp = strstr(string, find); | ||
334 | if (cp) | ||
335 | sscanf(cp + strlen(find), "=%u", i); | ||
336 | } | ||
337 | |||
338 | static void tomoyo_set_pref(const char *name, const char *value, | ||
339 | const bool use_default, | ||
340 | struct tomoyo_profile *profile) | ||
341 | { | ||
342 | struct tomoyo_preference **pref; | ||
343 | bool *verbose; | ||
344 | if (!strcmp(name, "enforcing")) { | ||
345 | if (use_default) { | ||
346 | pref = &profile->enforcing; | ||
347 | goto set_default; | ||
348 | } | ||
349 | profile->enforcing = &profile->preference; | ||
350 | verbose = &profile->preference.enforcing_verbose; | ||
351 | goto set_verbose; | ||
352 | } | ||
353 | if (!strcmp(name, "permissive")) { | ||
354 | if (use_default) { | ||
355 | pref = &profile->permissive; | ||
356 | goto set_default; | ||
357 | } | ||
358 | profile->permissive = &profile->preference; | ||
359 | verbose = &profile->preference.permissive_verbose; | ||
360 | goto set_verbose; | ||
361 | } | ||
362 | if (!strcmp(name, "learning")) { | ||
363 | if (use_default) { | ||
364 | pref = &profile->learning; | ||
365 | goto set_default; | ||
366 | } | ||
367 | profile->learning = &profile->preference; | ||
368 | tomoyo_set_uint(&profile->preference.learning_max_entry, value, | ||
369 | "max_entry"); | ||
370 | verbose = &profile->preference.learning_verbose; | ||
371 | goto set_verbose; | ||
372 | } | ||
373 | return; | ||
374 | set_default: | ||
375 | *pref = &tomoyo_default_profile.preference; | ||
376 | return; | ||
377 | set_verbose: | ||
378 | tomoyo_set_bool(verbose, value, "verbose"); | ||
379 | } | ||
380 | |||
381 | static int tomoyo_set_mode(char *name, const char *value, | ||
382 | const bool use_default, | ||
383 | struct tomoyo_profile *profile) | ||
384 | { | ||
385 | u8 i; | ||
386 | u8 config; | ||
387 | if (!strcmp(name, "CONFIG")) { | ||
388 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; | ||
389 | config = profile->default_config; | ||
390 | } else if (tomoyo_str_starts(&name, "CONFIG::")) { | ||
391 | config = 0; | ||
392 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX | ||
393 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { | ||
394 | if (strcmp(name, tomoyo_mac_keywords[i])) | ||
395 | continue; | ||
396 | config = profile->config[i]; | ||
397 | break; | ||
398 | } | ||
399 | if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) | ||
400 | return -EINVAL; | ||
401 | } else { | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | if (use_default) { | ||
405 | config = TOMOYO_CONFIG_USE_DEFAULT; | ||
406 | } else { | ||
407 | u8 mode; | ||
408 | for (mode = 0; mode < 4; mode++) | ||
409 | if (strstr(value, tomoyo_mode[mode])) | ||
410 | /* | ||
411 | * Update lower 3 bits in order to distinguish | ||
412 | * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. | ||
413 | */ | ||
414 | config = (config & ~7) | mode; | ||
415 | } | ||
416 | if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) | ||
417 | profile->config[i] = config; | ||
418 | else if (config != TOMOYO_CONFIG_USE_DEFAULT) | ||
419 | profile->default_config = config; | ||
420 | return 0; | ||
421 | } | ||
422 | |||
305 | /** | 423 | /** |
306 | * tomoyo_write_profile - Write profile table. | 424 | * tomoyo_write_profile - Write profile table. |
307 | * | 425 | * |
@@ -313,9 +431,6 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
313 | { | 431 | { |
314 | char *data = head->write_buf; | 432 | char *data = head->write_buf; |
315 | unsigned int i; | 433 | unsigned int i; |
316 | int value; | ||
317 | int mode; | ||
318 | u8 config; | ||
319 | bool use_default = false; | 434 | bool use_default = false; |
320 | char *cp; | 435 | char *cp; |
321 | struct tomoyo_profile *profile; | 436 | struct tomoyo_profile *profile; |
@@ -338,45 +453,8 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
338 | *cp++ = '\0'; | 453 | *cp++ = '\0'; |
339 | if (profile != &tomoyo_default_profile) | 454 | if (profile != &tomoyo_default_profile) |
340 | use_default = strstr(cp, "use_default") != NULL; | 455 | use_default = strstr(cp, "use_default") != NULL; |
341 | if (strstr(cp, "verbose=yes")) | 456 | if (tomoyo_str_starts(&data, "PREFERENCE::")) { |
342 | value = 1; | 457 | tomoyo_set_pref(data, cp, use_default, profile); |
343 | else if (strstr(cp, "verbose=no")) | ||
344 | value = 0; | ||
345 | else | ||
346 | value = -1; | ||
347 | if (!strcmp(data, "PREFERENCE::enforcing")) { | ||
348 | if (use_default) { | ||
349 | profile->enforcing = &tomoyo_default_profile.preference; | ||
350 | return 0; | ||
351 | } | ||
352 | profile->enforcing = &profile->preference; | ||
353 | if (value >= 0) | ||
354 | profile->preference.enforcing_verbose = value; | ||
355 | return 0; | ||
356 | } | ||
357 | if (!strcmp(data, "PREFERENCE::permissive")) { | ||
358 | if (use_default) { | ||
359 | profile->permissive = &tomoyo_default_profile.preference; | ||
360 | return 0; | ||
361 | } | ||
362 | profile->permissive = &profile->preference; | ||
363 | if (value >= 0) | ||
364 | profile->preference.permissive_verbose = value; | ||
365 | return 0; | ||
366 | } | ||
367 | if (!strcmp(data, "PREFERENCE::learning")) { | ||
368 | char *cp2; | ||
369 | if (use_default) { | ||
370 | profile->learning = &tomoyo_default_profile.preference; | ||
371 | return 0; | ||
372 | } | ||
373 | profile->learning = &profile->preference; | ||
374 | if (value >= 0) | ||
375 | profile->preference.learning_verbose = value; | ||
376 | cp2 = strstr(cp, "max_entry="); | ||
377 | if (cp2) | ||
378 | sscanf(cp2 + 10, "%u", | ||
379 | &profile->preference.learning_max_entry); | ||
380 | return 0; | 458 | return 0; |
381 | } | 459 | } |
382 | if (profile == &tomoyo_default_profile) | 460 | if (profile == &tomoyo_default_profile) |
@@ -387,38 +465,7 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
387 | tomoyo_put_name(old_comment); | 465 | tomoyo_put_name(old_comment); |
388 | return 0; | 466 | return 0; |
389 | } | 467 | } |
390 | if (!strcmp(data, "CONFIG")) { | 468 | return tomoyo_set_mode(data, cp, use_default, profile); |
391 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; | ||
392 | config = profile->default_config; | ||
393 | } else if (tomoyo_str_starts(&data, "CONFIG::")) { | ||
394 | config = 0; | ||
395 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { | ||
396 | if (strcmp(data, tomoyo_mac_keywords[i])) | ||
397 | continue; | ||
398 | config = profile->config[i]; | ||
399 | break; | ||
400 | } | ||
401 | if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) | ||
402 | return -EINVAL; | ||
403 | } else { | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | if (use_default) { | ||
407 | config = TOMOYO_CONFIG_USE_DEFAULT; | ||
408 | } else { | ||
409 | for (mode = 3; mode >= 0; mode--) | ||
410 | if (strstr(cp, tomoyo_mode[mode])) | ||
411 | /* | ||
412 | * Update lower 3 bits in order to distinguish | ||
413 | * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. | ||
414 | */ | ||
415 | config = (config & ~7) | mode; | ||
416 | } | ||
417 | if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) | ||
418 | profile->config[i] = config; | ||
419 | else if (config != TOMOYO_CONFIG_USE_DEFAULT) | ||
420 | profile->default_config = config; | ||
421 | return 0; | ||
422 | } | 469 | } |
423 | 470 | ||
424 | static void tomoyo_print_preference(struct tomoyo_io_buffer *head, | 471 | static void tomoyo_print_preference(struct tomoyo_io_buffer *head, |