diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-20 20:58:53 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:42 -0400 |
commit | 0617c7ff34dc9b1d641640c3953274bb2dbe21a6 (patch) | |
tree | 6be51af32ad65380aff9b7fa385f65ef15b3d53b /security/tomoyo | |
parent | 7c2ea22e3c5463627ca98924cd65cb9e480dc29c (diff) |
TOMOYO: Remove alias keyword.
Some programs behave differently depending on argv[0] passed to execve().
TOMOYO has "alias" keyword in order to allow administrators to define different
domains if requested pathname passed to execve() is a symlink. But "alias"
keyword is incomplete because this keyword assumes that requested pathname and
argv[0] are identical. Thus, remove "alias" keyword (by this patch) and add
syntax for checking argv[0] (by future patches).
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')
-rw-r--r-- | security/tomoyo/common.c | 12 | ||||
-rw-r--r-- | security/tomoyo/common.h | 30 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 100 | ||||
-rw-r--r-- | security/tomoyo/gc.c | 11 | ||||
-rw-r--r-- | security/tomoyo/realpath.c | 19 |
5 files changed, 8 insertions, 164 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 183fe6513400..0e6b1b598b86 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1177,8 +1177,6 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) | |||
1177 | is_delete); | 1177 | is_delete); |
1178 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_AGGREGATOR)) | 1178 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_AGGREGATOR)) |
1179 | return tomoyo_write_aggregator_policy(data, is_delete); | 1179 | return tomoyo_write_aggregator_policy(data, is_delete); |
1180 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS)) | ||
1181 | return tomoyo_write_alias_policy(data, is_delete); | ||
1182 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ)) | 1180 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ)) |
1183 | return tomoyo_write_globally_readable_policy(data, is_delete); | 1181 | return tomoyo_write_globally_readable_policy(data, is_delete); |
1184 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN)) | 1182 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN)) |
@@ -1334,16 +1332,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | |||
1334 | w[1] = ptr->filename->name; | 1332 | w[1] = ptr->filename->name; |
1335 | } | 1333 | } |
1336 | break; | 1334 | break; |
1337 | case TOMOYO_ID_ALIAS: | ||
1338 | { | ||
1339 | struct tomoyo_alias_entry *ptr = | ||
1340 | container_of(acl, typeof(*ptr), head); | ||
1341 | w[0] = TOMOYO_KEYWORD_ALIAS; | ||
1342 | w[1] = ptr->original_name->name; | ||
1343 | w[2] = " "; | ||
1344 | w[3] = ptr->aliased_name->name; | ||
1345 | } | ||
1346 | break; | ||
1347 | case TOMOYO_ID_AGGREGATOR: | 1335 | case TOMOYO_ID_AGGREGATOR: |
1348 | { | 1336 | { |
1349 | struct tomoyo_aggregator_entry *ptr = | 1337 | struct tomoyo_aggregator_entry *ptr = |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index ec3ed488ee30..12b0c5c46c8d 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -53,7 +53,6 @@ enum tomoyo_policy_id { | |||
53 | TOMOYO_ID_DOMAIN_INITIALIZER, | 53 | TOMOYO_ID_DOMAIN_INITIALIZER, |
54 | TOMOYO_ID_DOMAIN_KEEPER, | 54 | TOMOYO_ID_DOMAIN_KEEPER, |
55 | TOMOYO_ID_AGGREGATOR, | 55 | TOMOYO_ID_AGGREGATOR, |
56 | TOMOYO_ID_ALIAS, | ||
57 | TOMOYO_ID_GLOBALLY_READABLE, | 56 | TOMOYO_ID_GLOBALLY_READABLE, |
58 | TOMOYO_ID_PATTERN, | 57 | TOMOYO_ID_PATTERN, |
59 | TOMOYO_ID_NO_REWRITE, | 58 | TOMOYO_ID_NO_REWRITE, |
@@ -72,7 +71,6 @@ enum tomoyo_group_id { | |||
72 | 71 | ||
73 | /* Keywords for ACLs. */ | 72 | /* Keywords for ACLs. */ |
74 | #define TOMOYO_KEYWORD_AGGREGATOR "aggregator " | 73 | #define TOMOYO_KEYWORD_AGGREGATOR "aggregator " |
75 | #define TOMOYO_KEYWORD_ALIAS "alias " | ||
76 | #define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount " | 74 | #define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount " |
77 | #define TOMOYO_KEYWORD_ALLOW_READ "allow_read " | 75 | #define TOMOYO_KEYWORD_ALLOW_READ "allow_read " |
78 | #define TOMOYO_KEYWORD_DELETE "delete " | 76 | #define TOMOYO_KEYWORD_DELETE "delete " |
@@ -683,20 +681,6 @@ struct tomoyo_aggregator_entry { | |||
683 | }; | 681 | }; |
684 | 682 | ||
685 | /* | 683 | /* |
686 | * tomoyo_alias_entry is a structure which is used for holding "alias" entries. | ||
687 | * It has following fields. | ||
688 | * | ||
689 | * (1) "head" is "struct tomoyo_acl_head". | ||
690 | * (2) "original_name" which is a dereferenced pathname. | ||
691 | * (3) "aliased_name" which is a symlink's pathname. | ||
692 | */ | ||
693 | struct tomoyo_alias_entry { | ||
694 | struct tomoyo_acl_head head; | ||
695 | const struct tomoyo_path_info *original_name; | ||
696 | const struct tomoyo_path_info *aliased_name; | ||
697 | }; | ||
698 | |||
699 | /* | ||
700 | * tomoyo_policy_manager_entry is a structure which is used for holding list of | 684 | * tomoyo_policy_manager_entry is a structure which is used for holding list of |
701 | * domainnames or programs which are permitted to modify configuration via | 685 | * domainnames or programs which are permitted to modify configuration via |
702 | * /sys/kernel/security/tomoyo/ interface. | 686 | * /sys/kernel/security/tomoyo/ interface. |
@@ -809,8 +793,6 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type, | |||
809 | unsigned long flags, void *data_page); | 793 | unsigned long flags, void *data_page); |
810 | /* Create "aggregator" entry in exception policy. */ | 794 | /* Create "aggregator" entry in exception policy. */ |
811 | int tomoyo_write_aggregator_policy(char *data, const bool is_delete); | 795 | int tomoyo_write_aggregator_policy(char *data, const bool is_delete); |
812 | /* Create "alias" entry in exception policy. */ | ||
813 | int tomoyo_write_alias_policy(char *data, const bool is_delete); | ||
814 | /* | 796 | /* |
815 | * Create "initialize_domain" and "no_initialize_domain" entry | 797 | * Create "initialize_domain" and "no_initialize_domain" entry |
816 | * in exception policy. | 798 | * in exception policy. |
@@ -868,16 +850,14 @@ void tomoyo_put_number_union(struct tomoyo_number_union *ptr); | |||
868 | char *tomoyo_encode(const char *str); | 850 | char *tomoyo_encode(const char *str); |
869 | 851 | ||
870 | /* | 852 | /* |
871 | * Returns realpath(3) of the given pathname but ignores chroot'ed root. | 853 | * Returns realpath(3) of the given pathname except that |
872 | * These functions use kzalloc(), so the caller must call kfree() | 854 | * ignores chroot'ed root and does not follow the final symlink. |
873 | * if these functions didn't return NULL. | ||
874 | */ | 855 | */ |
875 | char *tomoyo_realpath(const char *pathname); | 856 | char *tomoyo_realpath_nofollow(const char *pathname); |
876 | /* | 857 | /* |
877 | * Same with tomoyo_realpath() except that it doesn't follow the final symlink. | 858 | * Returns realpath(3) of the given pathname except that |
859 | * ignores chroot'ed root and the pathname is already solved. | ||
878 | */ | 860 | */ |
879 | char *tomoyo_realpath_nofollow(const char *pathname); | ||
880 | /* Same with tomoyo_realpath() except that the pathname is already solved. */ | ||
881 | char *tomoyo_realpath_from_path(struct path *path); | 861 | char *tomoyo_realpath_from_path(struct path *path); |
882 | /* Get patterned pathname. */ | 862 | /* Get patterned pathname. */ |
883 | const char *tomoyo_file_pattern(const struct tomoyo_path_info *filename); | 863 | const char *tomoyo_file_pattern(const struct tomoyo_path_info *filename); |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 038071a8a3d3..273e670acf0c 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -467,72 +467,6 @@ int tomoyo_write_aggregator_policy(char *data, const bool is_delete) | |||
467 | return tomoyo_update_aggregator_entry(data, cp, is_delete); | 467 | return tomoyo_update_aggregator_entry(data, cp, is_delete); |
468 | } | 468 | } |
469 | 469 | ||
470 | static bool tomoyo_same_alias_entry(const struct tomoyo_acl_head *a, | ||
471 | const struct tomoyo_acl_head *b) | ||
472 | { | ||
473 | const struct tomoyo_alias_entry *p1 = container_of(a, typeof(*p1), | ||
474 | head); | ||
475 | const struct tomoyo_alias_entry *p2 = container_of(b, typeof(*p2), | ||
476 | head); | ||
477 | return p1->original_name == p2->original_name && | ||
478 | p1->aliased_name == p2->aliased_name; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list. | ||
483 | * | ||
484 | * @original_name: The original program's real name. | ||
485 | * @aliased_name: The symbolic program's symbolic link's name. | ||
486 | * @is_delete: True if it is a delete request. | ||
487 | * | ||
488 | * Returns 0 on success, negative value otherwise. | ||
489 | * | ||
490 | * Caller holds tomoyo_read_lock(). | ||
491 | */ | ||
492 | static int tomoyo_update_alias_entry(const char *original_name, | ||
493 | const char *aliased_name, | ||
494 | const bool is_delete) | ||
495 | { | ||
496 | struct tomoyo_alias_entry e = { }; | ||
497 | int error = is_delete ? -ENOENT : -ENOMEM; | ||
498 | |||
499 | if (!tomoyo_correct_path(original_name) || | ||
500 | !tomoyo_correct_path(aliased_name)) | ||
501 | return -EINVAL; | ||
502 | e.original_name = tomoyo_get_name(original_name); | ||
503 | e.aliased_name = tomoyo_get_name(aliased_name); | ||
504 | if (!e.original_name || !e.aliased_name || | ||
505 | e.original_name->is_patterned || e.aliased_name->is_patterned) | ||
506 | goto out; /* No patterns allowed. */ | ||
507 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, | ||
508 | &tomoyo_policy_list[TOMOYO_ID_ALIAS], | ||
509 | tomoyo_same_alias_entry); | ||
510 | out: | ||
511 | tomoyo_put_name(e.original_name); | ||
512 | tomoyo_put_name(e.aliased_name); | ||
513 | return error; | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list. | ||
518 | * | ||
519 | * @data: String to parse. | ||
520 | * @is_delete: True if it is a delete request. | ||
521 | * | ||
522 | * Returns 0 on success, negative value otherwise. | ||
523 | * | ||
524 | * Caller holds tomoyo_read_lock(). | ||
525 | */ | ||
526 | int tomoyo_write_alias_policy(char *data, const bool is_delete) | ||
527 | { | ||
528 | char *cp = strchr(data, ' '); | ||
529 | |||
530 | if (!cp) | ||
531 | return -EINVAL; | ||
532 | *cp++ = '\0'; | ||
533 | return tomoyo_update_alias_entry(data, cp, is_delete); | ||
534 | } | ||
535 | |||
536 | /** | 470 | /** |
537 | * tomoyo_find_or_assign_new_domain - Create a domain. | 471 | * tomoyo_find_or_assign_new_domain - Create a domain. |
538 | * | 472 | * |
@@ -606,7 +540,6 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
606 | int retval = -ENOMEM; | 540 | int retval = -ENOMEM; |
607 | bool need_kfree = false; | 541 | bool need_kfree = false; |
608 | struct tomoyo_path_info rn = { }; /* real name */ | 542 | struct tomoyo_path_info rn = { }; /* real name */ |
609 | struct tomoyo_path_info sn = { }; /* symlink name */ | ||
610 | struct tomoyo_path_info ln; /* last name */ | 543 | struct tomoyo_path_info ln; /* last name */ |
611 | 544 | ||
612 | ln.name = tomoyo_get_last_name(old_domain); | 545 | ln.name = tomoyo_get_last_name(old_domain); |
@@ -621,39 +554,14 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
621 | kfree(rn.name); | 554 | kfree(rn.name); |
622 | need_kfree = false; | 555 | need_kfree = false; |
623 | } | 556 | } |
624 | /* Get tomoyo_realpath of program. */ | 557 | /* Get symlink's pathname of program. */ |
625 | retval = -ENOENT; | 558 | retval = -ENOENT; |
626 | rn.name = tomoyo_realpath(original_name); | 559 | rn.name = tomoyo_realpath_nofollow(original_name); |
627 | if (!rn.name) | 560 | if (!rn.name) |
628 | goto out; | 561 | goto out; |
629 | tomoyo_fill_path_info(&rn); | 562 | tomoyo_fill_path_info(&rn); |
630 | need_kfree = true; | 563 | need_kfree = true; |
631 | 564 | ||
632 | /* Get tomoyo_realpath of symbolic link. */ | ||
633 | sn.name = tomoyo_realpath_nofollow(original_name); | ||
634 | if (!sn.name) | ||
635 | goto out; | ||
636 | tomoyo_fill_path_info(&sn); | ||
637 | |||
638 | /* Check 'alias' directive. */ | ||
639 | if (tomoyo_pathcmp(&rn, &sn)) { | ||
640 | struct tomoyo_alias_entry *ptr; | ||
641 | /* Is this program allowed to be called via symbolic links? */ | ||
642 | list_for_each_entry_rcu(ptr, | ||
643 | &tomoyo_policy_list[TOMOYO_ID_ALIAS], | ||
644 | head.list) { | ||
645 | if (ptr->head.is_deleted || | ||
646 | tomoyo_pathcmp(&rn, ptr->original_name) || | ||
647 | tomoyo_pathcmp(&sn, ptr->aliased_name)) | ||
648 | continue; | ||
649 | kfree(rn.name); | ||
650 | need_kfree = false; | ||
651 | /* This is OK because it is read only. */ | ||
652 | rn = *ptr->aliased_name; | ||
653 | break; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | /* Check 'aggregator' directive. */ | 565 | /* Check 'aggregator' directive. */ |
658 | { | 566 | { |
659 | struct tomoyo_aggregator_entry *ptr; | 567 | struct tomoyo_aggregator_entry *ptr; |
@@ -663,8 +571,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
663 | !tomoyo_path_matches_pattern(&rn, | 571 | !tomoyo_path_matches_pattern(&rn, |
664 | ptr->original_name)) | 572 | ptr->original_name)) |
665 | continue; | 573 | continue; |
666 | if (need_kfree) | 574 | kfree(rn.name); |
667 | kfree(rn.name); | ||
668 | need_kfree = false; | 575 | need_kfree = false; |
669 | /* This is OK because it is read only. */ | 576 | /* This is OK because it is read only. */ |
670 | rn = *ptr->aggregated_name; | 577 | rn = *ptr->aggregated_name; |
@@ -729,7 +636,6 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
729 | bprm->cred->security = domain; | 636 | bprm->cred->security = domain; |
730 | if (need_kfree) | 637 | if (need_kfree) |
731 | kfree(rn.name); | 638 | kfree(rn.name); |
732 | kfree(sn.name); | ||
733 | kfree(tmp); | 639 | kfree(tmp); |
734 | return retval; | 640 | return retval; |
735 | } | 641 | } |
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index cf62a4ee79c2..4d4ba84f8749 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c | |||
@@ -77,14 +77,6 @@ static void tomoyo_del_aggregator(struct list_head *element) | |||
77 | tomoyo_put_name(ptr->aggregated_name); | 77 | tomoyo_put_name(ptr->aggregated_name); |
78 | } | 78 | } |
79 | 79 | ||
80 | static void tomoyo_del_alias(struct list_head *element) | ||
81 | { | ||
82 | struct tomoyo_alias_entry *ptr = | ||
83 | container_of(element, typeof(*ptr), head.list); | ||
84 | tomoyo_put_name(ptr->original_name); | ||
85 | tomoyo_put_name(ptr->aliased_name); | ||
86 | } | ||
87 | |||
88 | static void tomoyo_del_manager(struct list_head *element) | 80 | static void tomoyo_del_manager(struct list_head *element) |
89 | { | 81 | { |
90 | struct tomoyo_policy_manager_entry *ptr = | 82 | struct tomoyo_policy_manager_entry *ptr = |
@@ -309,9 +301,6 @@ static void tomoyo_kfree_entry(void) | |||
309 | case TOMOYO_ID_AGGREGATOR: | 301 | case TOMOYO_ID_AGGREGATOR: |
310 | tomoyo_del_aggregator(element); | 302 | tomoyo_del_aggregator(element); |
311 | break; | 303 | break; |
312 | case TOMOYO_ID_ALIAS: | ||
313 | tomoyo_del_alias(element); | ||
314 | break; | ||
315 | case TOMOYO_ID_GLOBALLY_READABLE: | 304 | case TOMOYO_ID_GLOBALLY_READABLE: |
316 | tomoyo_del_allow_read(element); | 305 | tomoyo_del_allow_read(element); |
317 | break; | 306 | break; |
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 153fa23a05cc..ed8ccd680102 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -162,25 +162,6 @@ char *tomoyo_realpath_from_path(struct path *path) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | /** | 164 | /** |
165 | * tomoyo_realpath - Get realpath of a pathname. | ||
166 | * | ||
167 | * @pathname: The pathname to solve. | ||
168 | * | ||
169 | * Returns the realpath of @pathname on success, NULL otherwise. | ||
170 | */ | ||
171 | char *tomoyo_realpath(const char *pathname) | ||
172 | { | ||
173 | struct path path; | ||
174 | |||
175 | if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) { | ||
176 | char *buf = tomoyo_realpath_from_path(&path); | ||
177 | path_put(&path); | ||
178 | return buf; | ||
179 | } | ||
180 | return NULL; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * tomoyo_realpath_nofollow - Get realpath of a pathname. | 165 | * tomoyo_realpath_nofollow - Get realpath of a pathname. |
185 | * | 166 | * |
186 | * @pathname: The pathname to solve. | 167 | * @pathname: The pathname to solve. |