aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/condition.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/condition.c')
-rw-r--r--security/tomoyo/condition.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index 8a05f71eaf67..986330b8c73e 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -348,6 +348,7 @@ static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
348 a->numbers_count == b->numbers_count && 348 a->numbers_count == b->numbers_count &&
349 a->names_count == b->names_count && 349 a->names_count == b->names_count &&
350 a->argc == b->argc && a->envc == b->envc && 350 a->argc == b->argc && a->envc == b->envc &&
351 a->grant_log == b->grant_log && a->transit == b->transit &&
351 !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 352 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
352} 353}
353 354
@@ -399,8 +400,9 @@ static struct tomoyo_condition *tomoyo_commit_condition
399 found = true; 400 found = true;
400 goto out; 401 goto out;
401 } 402 }
402 list_for_each_entry_rcu(ptr, &tomoyo_condition_list, head.list) { 403 list_for_each_entry(ptr, &tomoyo_condition_list, head.list) {
403 if (!tomoyo_same_condition(ptr, entry)) 404 if (!tomoyo_same_condition(ptr, entry) ||
405 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
404 continue; 406 continue;
405 /* Same entry found. Share this entry. */ 407 /* Same entry found. Share this entry. */
406 atomic_inc(&ptr->head.users); 408 atomic_inc(&ptr->head.users);
@@ -410,8 +412,7 @@ static struct tomoyo_condition *tomoyo_commit_condition
410 if (!found) { 412 if (!found) {
411 if (tomoyo_memory_ok(entry)) { 413 if (tomoyo_memory_ok(entry)) {
412 atomic_set(&entry->head.users, 1); 414 atomic_set(&entry->head.users, 1);
413 list_add_rcu(&entry->head.list, 415 list_add(&entry->head.list, &tomoyo_condition_list);
414 &tomoyo_condition_list);
415 } else { 416 } else {
416 found = true; 417 found = true;
417 ptr = NULL; 418 ptr = NULL;
@@ -428,6 +429,46 @@ out:
428} 429}
429 430
430/** 431/**
432 * tomoyo_get_transit_preference - Parse domain transition preference for execve().
433 *
434 * @param: Pointer to "struct tomoyo_acl_param".
435 * @e: Pointer to "struct tomoyo_condition".
436 *
437 * Returns the condition string part.
438 */
439static char *tomoyo_get_transit_preference(struct tomoyo_acl_param *param,
440 struct tomoyo_condition *e)
441{
442 char * const pos = param->data;
443 bool flag;
444 if (*pos == '<') {
445 e->transit = tomoyo_get_domainname(param);
446 goto done;
447 }
448 {
449 char *cp = strchr(pos, ' ');
450 if (cp)
451 *cp = '\0';
452 flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") ||
453 !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
454 !strcmp(pos, "child") || !strcmp(pos, "parent");
455 if (cp)
456 *cp = ' ';
457 }
458 if (!flag)
459 return pos;
460 e->transit = tomoyo_get_name(tomoyo_read_token(param));
461done:
462 if (e->transit)
463 return param->data;
464 /*
465 * Return a bad read-only condition string that will let
466 * tomoyo_get_condition() return NULL.
467 */
468 return "/";
469}
470
471/**
431 * tomoyo_get_condition - Parse condition part. 472 * tomoyo_get_condition - Parse condition part.
432 * 473 *
433 * @param: Pointer to "struct tomoyo_acl_param". 474 * @param: Pointer to "struct tomoyo_acl_param".
@@ -443,7 +484,8 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
443 struct tomoyo_argv *argv = NULL; 484 struct tomoyo_argv *argv = NULL;
444 struct tomoyo_envp *envp = NULL; 485 struct tomoyo_envp *envp = NULL;
445 struct tomoyo_condition e = { }; 486 struct tomoyo_condition e = { };
446 char * const start_of_string = param->data; 487 char * const start_of_string =
488 tomoyo_get_transit_preference(param, &e);
447 char * const end_of_string = start_of_string + strlen(start_of_string); 489 char * const end_of_string = start_of_string + strlen(start_of_string);
448 char *pos; 490 char *pos;
449rerun: 491rerun:
@@ -486,6 +528,20 @@ rerun:
486 goto out; 528 goto out;
487 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word, 529 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
488 is_not ? "!" : "", right_word); 530 is_not ? "!" : "", right_word);
531 if (!strcmp(left_word, "grant_log")) {
532 if (entry) {
533 if (is_not ||
534 entry->grant_log != TOMOYO_GRANTLOG_AUTO)
535 goto out;
536 else if (!strcmp(right_word, "yes"))
537 entry->grant_log = TOMOYO_GRANTLOG_YES;
538 else if (!strcmp(right_word, "no"))
539 entry->grant_log = TOMOYO_GRANTLOG_NO;
540 else
541 goto out;
542 }
543 continue;
544 }
489 if (!strncmp(left_word, "exec.argv[", 10)) { 545 if (!strncmp(left_word, "exec.argv[", 10)) {
490 if (!argv) { 546 if (!argv) {
491 e.argc++; 547 e.argc++;
@@ -593,8 +649,9 @@ store_value:
593 + e.envc * sizeof(struct tomoyo_envp); 649 + e.envc * sizeof(struct tomoyo_envp);
594 entry = kzalloc(e.size, GFP_NOFS); 650 entry = kzalloc(e.size, GFP_NOFS);
595 if (!entry) 651 if (!entry)
596 return NULL; 652 goto out2;
597 *entry = e; 653 *entry = e;
654 e.transit = NULL;
598 condp = (struct tomoyo_condition_element *) (entry + 1); 655 condp = (struct tomoyo_condition_element *) (entry + 1);
599 numbers_p = (struct tomoyo_number_union *) (condp + e.condc); 656 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
600 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count); 657 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
@@ -621,6 +678,8 @@ out:
621 tomoyo_del_condition(&entry->head.list); 678 tomoyo_del_condition(&entry->head.list);
622 kfree(entry); 679 kfree(entry);
623 } 680 }
681out2:
682 tomoyo_put_name(e.transit);
624 return NULL; 683 return NULL;
625} 684}
626 685