aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c195
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
305static 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
318static 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
330static 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
338static 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
381static 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
424static void tomoyo_print_preference(struct tomoyo_io_buffer *head, 471static void tomoyo_print_preference(struct tomoyo_io_buffer *head,