aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/condition.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-09-16 09:54:25 -0400
committerJames Morris <jmorris@namei.org>2011-09-18 20:09:59 -0400
commit6bce98edc3365a8f780ff3944ac7992544c194fe (patch)
treeee10abf2345f651d65d7f10fd385c01e0dc891b3 /security/tomoyo/condition.c
parentcc100551b4d92f47abebfa7c7918b2be71263b4a (diff)
TOMOYO: Allow specifying domain transition preference.
I got an opinion that it is difficult to use exception policy's domain transition control directives because they need to match the pathname specified to "file execute" directives. For example, if "file execute /bin/\*\-ls\-cat" is given, corresponding domain transition control directive needs to be like "no_keep_domain /bin/\*\-ls\-cat from any". If we can specify like below, it will become more convenient. file execute /bin/ls keep exec.realpath="/bin/ls" exec.argv[0]="ls" file execute /bin/cat keep exec.realpath="/bin/cat" exec.argv[0]="cat" file execute /bin/\*\-ls\-cat child file execute /usr/sbin/httpd <apache> exec.realpath="/usr/sbin/httpd" exec.argv[0]="/usr/sbin/httpd" In above examples, "keep" works as if keep_domain is specified, "child" works as if "no_reset_domain" and "no_initialize_domain" and "no_keep_domain" are specified, "<apache>" causes domain transition to <apache> domain upon successful execve() operation. Moreover, we can also allow transition to different domains based on conditions like below example. <kernel> /usr/sbin/sshd file execute /bin/bash <kernel> /usr/sbin/sshd //batch-session exec.argc=2 exec.argv[1]="-c" file execute /bin/bash <kernel> /usr/sbin/sshd //root-session task.uid=0 file execute /bin/bash <kernel> /usr/sbin/sshd //nonroot-session task.uid!=0 Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/condition.c')
-rw-r--r--security/tomoyo/condition.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index 3a05eb3e2a64..b854959c0fd4 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -348,7 +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 && 351 a->grant_log == b->grant_log && a->transit == b->transit &&
352 !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 352 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
353} 353}
354 354
@@ -429,6 +429,46 @@ out:
429} 429}
430 430
431/** 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/**
432 * tomoyo_get_condition - Parse condition part. 472 * tomoyo_get_condition - Parse condition part.
433 * 473 *
434 * @param: Pointer to "struct tomoyo_acl_param". 474 * @param: Pointer to "struct tomoyo_acl_param".
@@ -444,7 +484,8 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
444 struct tomoyo_argv *argv = NULL; 484 struct tomoyo_argv *argv = NULL;
445 struct tomoyo_envp *envp = NULL; 485 struct tomoyo_envp *envp = NULL;
446 struct tomoyo_condition e = { }; 486 struct tomoyo_condition e = { };
447 char * const start_of_string = param->data; 487 char * const start_of_string =
488 tomoyo_get_transit_preference(param, &e);
448 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);
449 char *pos; 490 char *pos;
450rerun: 491rerun:
@@ -608,8 +649,9 @@ store_value:
608 + e.envc * sizeof(struct tomoyo_envp); 649 + e.envc * sizeof(struct tomoyo_envp);
609 entry = kzalloc(e.size, GFP_NOFS); 650 entry = kzalloc(e.size, GFP_NOFS);
610 if (!entry) 651 if (!entry)
611 return NULL; 652 goto out2;
612 *entry = e; 653 *entry = e;
654 e.transit = NULL;
613 condp = (struct tomoyo_condition_element *) (entry + 1); 655 condp = (struct tomoyo_condition_element *) (entry + 1);
614 numbers_p = (struct tomoyo_number_union *) (condp + e.condc); 656 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
615 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count); 657 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
@@ -636,6 +678,8 @@ out:
636 tomoyo_del_condition(&entry->head.list); 678 tomoyo_del_condition(&entry->head.list);
637 kfree(entry); 679 kfree(entry);
638 } 680 }
681out2:
682 tomoyo_put_name(e.transit);
639 return NULL; 683 return NULL;
640} 684}
641 685