diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-07-29 01:29:55 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:38:38 -0400 |
commit | 484ca79c653121d3c79fffb86e1deea724f2e20b (patch) | |
tree | 457aa73e37c9b5e5b4306430f40d1985b59ca226 | |
parent | 4d6ec10bb4461fdc9a9ab94ef32934e13564e873 (diff) |
TOMOYO: Use pathname specified by policy rather than execve()
Commit c9e69318 "TOMOYO: Allow wildcard for execute permission." changed execute
permission and domainname to accept wildcards. But tomoyo_find_next_domain()
was using pathname passed to execve() rather than pathname specified by the
execute permission. As a result, processes were not able to transit to domains
which contain wildcards in their domainnames.
This patch passes pathname specified by the execute permission back to
tomoyo_find_next_domain() so that processes can transit to domains which
contain wildcards in their domainnames.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | security/tomoyo/common.h | 14 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 15 | ||||
-rw-r--r-- | security/tomoyo/file.c | 26 | ||||
-rw-r--r-- | security/tomoyo/group.c | 14 | ||||
-rw-r--r-- | security/tomoyo/mount.c | 2 |
5 files changed, 48 insertions, 23 deletions
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 2ffad6138555..04454cb7b24a 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -246,6 +246,8 @@ struct tomoyo_request_info { | |||
246 | union { | 246 | union { |
247 | struct { | 247 | struct { |
248 | const struct tomoyo_path_info *filename; | 248 | const struct tomoyo_path_info *filename; |
249 | /* For using wildcards at tomoyo_find_next_domain(). */ | ||
250 | const struct tomoyo_path_info *matched_path; | ||
249 | u8 operation; | 251 | u8 operation; |
250 | } path; | 252 | } path; |
251 | struct { | 253 | struct { |
@@ -718,8 +720,9 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r); | |||
718 | /* Print out of memory warning message. */ | 720 | /* Print out of memory warning message. */ |
719 | void tomoyo_warn_oom(const char *function); | 721 | void tomoyo_warn_oom(const char *function); |
720 | /* Check whether the given name matches the given name_union. */ | 722 | /* Check whether the given name matches the given name_union. */ |
721 | bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, | 723 | const struct tomoyo_path_info * |
722 | const struct tomoyo_name_union *ptr); | 724 | tomoyo_compare_name_union(const struct tomoyo_path_info *name, |
725 | const struct tomoyo_name_union *ptr); | ||
723 | /* Check whether the given number matches the given number_union. */ | 726 | /* Check whether the given number matches the given number_union. */ |
724 | bool tomoyo_compare_number_union(const unsigned long value, | 727 | bool tomoyo_compare_number_union(const unsigned long value, |
725 | const struct tomoyo_number_union *ptr); | 728 | const struct tomoyo_number_union *ptr); |
@@ -736,8 +739,9 @@ bool tomoyo_domain_def(const unsigned char *buffer); | |||
736 | bool tomoyo_parse_name_union(const char *filename, | 739 | bool tomoyo_parse_name_union(const char *filename, |
737 | struct tomoyo_name_union *ptr); | 740 | struct tomoyo_name_union *ptr); |
738 | /* Check whether the given filename matches the given path_group. */ | 741 | /* Check whether the given filename matches the given path_group. */ |
739 | bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, | 742 | const struct tomoyo_path_info * |
740 | const struct tomoyo_group *group); | 743 | tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, |
744 | const struct tomoyo_group *group); | ||
741 | /* Check whether the given value matches the given number_group. */ | 745 | /* Check whether the given value matches the given number_group. */ |
742 | bool tomoyo_number_matches_group(const unsigned long min, | 746 | bool tomoyo_number_matches_group(const unsigned long min, |
743 | const unsigned long max, | 747 | const unsigned long max, |
@@ -879,7 +883,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, | |||
879 | const struct tomoyo_acl_head | 883 | const struct tomoyo_acl_head |
880 | *)); | 884 | *)); |
881 | void tomoyo_check_acl(struct tomoyo_request_info *r, | 885 | void tomoyo_check_acl(struct tomoyo_request_info *r, |
882 | bool (*check_entry) (const struct tomoyo_request_info *, | 886 | bool (*check_entry) (struct tomoyo_request_info *, |
883 | const struct tomoyo_acl_info *)); | 887 | const struct tomoyo_acl_info *)); |
884 | 888 | ||
885 | /********** External variable definitions. **********/ | 889 | /********** External variable definitions. **********/ |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 4e0101b0041a..35388408e475 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -110,7 +110,7 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, | |||
110 | } | 110 | } |
111 | 111 | ||
112 | void tomoyo_check_acl(struct tomoyo_request_info *r, | 112 | void tomoyo_check_acl(struct tomoyo_request_info *r, |
113 | bool (*check_entry) (const struct tomoyo_request_info *, | 113 | bool (*check_entry) (struct tomoyo_request_info *, |
114 | const struct tomoyo_acl_info *)) | 114 | const struct tomoyo_acl_info *)) |
115 | { | 115 | { |
116 | const struct tomoyo_domain_info *domain = r->domain; | 116 | const struct tomoyo_domain_info *domain = r->domain; |
@@ -465,6 +465,19 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
465 | goto retry; | 465 | goto retry; |
466 | if (retval < 0) | 466 | if (retval < 0) |
467 | goto out; | 467 | goto out; |
468 | /* | ||
469 | * To be able to specify domainnames with wildcards, use the | ||
470 | * pathname specified in the policy (which may contain | ||
471 | * wildcard) rather than the pathname passed to execve() | ||
472 | * (which never contains wildcard). | ||
473 | */ | ||
474 | if (r.param.path.matched_path) { | ||
475 | if (need_kfree) | ||
476 | kfree(rn.name); | ||
477 | need_kfree = false; | ||
478 | /* This is OK because it is read only. */ | ||
479 | rn = *r.param.path.matched_path; | ||
480 | } | ||
468 | 481 | ||
469 | /* Calculate domain to transit to. */ | 482 | /* Calculate domain to transit to. */ |
470 | switch (tomoyo_transition_type(old_domain->domainname, &rn)) { | 483 | switch (tomoyo_transition_type(old_domain->domainname, &rn)) { |
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index f7877fa80f14..9d32f182301e 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -95,12 +95,15 @@ void tomoyo_put_name_union(struct tomoyo_name_union *ptr) | |||
95 | tomoyo_put_name(ptr->filename); | 95 | tomoyo_put_name(ptr->filename); |
96 | } | 96 | } |
97 | 97 | ||
98 | bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, | 98 | const struct tomoyo_path_info * |
99 | const struct tomoyo_name_union *ptr) | 99 | tomoyo_compare_name_union(const struct tomoyo_path_info *name, |
100 | const struct tomoyo_name_union *ptr) | ||
100 | { | 101 | { |
101 | if (ptr->is_group) | 102 | if (ptr->is_group) |
102 | return tomoyo_path_matches_group(name, ptr->group); | 103 | return tomoyo_path_matches_group(name, ptr->group); |
103 | return tomoyo_path_matches_pattern(name, ptr->filename); | 104 | if (tomoyo_path_matches_pattern(name, ptr->filename)) |
105 | return ptr->filename; | ||
106 | return NULL; | ||
104 | } | 107 | } |
105 | 108 | ||
106 | void tomoyo_put_number_union(struct tomoyo_number_union *ptr) | 109 | void tomoyo_put_number_union(struct tomoyo_number_union *ptr) |
@@ -504,16 +507,21 @@ int tomoyo_write_no_rewrite(char *data, const bool is_delete) | |||
504 | return tomoyo_update_no_rewrite_entry(data, is_delete); | 507 | return tomoyo_update_no_rewrite_entry(data, is_delete); |
505 | } | 508 | } |
506 | 509 | ||
507 | static bool tomoyo_check_path_acl(const struct tomoyo_request_info *r, | 510 | static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, |
508 | const struct tomoyo_acl_info *ptr) | 511 | const struct tomoyo_acl_info *ptr) |
509 | { | 512 | { |
510 | const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), | 513 | const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), |
511 | head); | 514 | head); |
512 | return (acl->perm & (1 << r->param.path.operation)) && | 515 | if (acl->perm & (1 << r->param.path.operation)) { |
513 | tomoyo_compare_name_union(r->param.path.filename, &acl->name); | 516 | r->param.path.matched_path = |
517 | tomoyo_compare_name_union(r->param.path.filename, | ||
518 | &acl->name); | ||
519 | return r->param.path.matched_path != NULL; | ||
520 | } | ||
521 | return false; | ||
514 | } | 522 | } |
515 | 523 | ||
516 | static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r, | 524 | static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, |
517 | const struct tomoyo_acl_info *ptr) | 525 | const struct tomoyo_acl_info *ptr) |
518 | { | 526 | { |
519 | const struct tomoyo_path_number_acl *acl = | 527 | const struct tomoyo_path_number_acl *acl = |
@@ -525,7 +533,7 @@ static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r, | |||
525 | &acl->name); | 533 | &acl->name); |
526 | } | 534 | } |
527 | 535 | ||
528 | static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r, | 536 | static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, |
529 | const struct tomoyo_acl_info *ptr) | 537 | const struct tomoyo_acl_info *ptr) |
530 | { | 538 | { |
531 | const struct tomoyo_path2_acl *acl = | 539 | const struct tomoyo_path2_acl *acl = |
@@ -536,7 +544,7 @@ static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r, | |||
536 | &acl->name2); | 544 | &acl->name2); |
537 | } | 545 | } |
538 | 546 | ||
539 | static bool tomoyo_check_mkdev_acl(const struct tomoyo_request_info *r, | 547 | static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, |
540 | const struct tomoyo_acl_info *ptr) | 548 | const struct tomoyo_acl_info *ptr) |
541 | { | 549 | { |
542 | const struct tomoyo_mkdev_acl *acl = | 550 | const struct tomoyo_mkdev_acl *acl = |
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c index 3f0a2abf65cc..e94352ce723f 100644 --- a/security/tomoyo/group.c +++ b/security/tomoyo/group.c | |||
@@ -80,24 +80,24 @@ int tomoyo_write_group(char *data, const bool is_delete, const u8 type) | |||
80 | * @pathname: The name of pathname. | 80 | * @pathname: The name of pathname. |
81 | * @group: Pointer to "struct tomoyo_path_group". | 81 | * @group: Pointer to "struct tomoyo_path_group". |
82 | * | 82 | * |
83 | * Returns true if @pathname matches pathnames in @group, false otherwise. | 83 | * Returns matched member's pathname if @pathname matches pathnames in @group, |
84 | * NULL otherwise. | ||
84 | * | 85 | * |
85 | * Caller holds tomoyo_read_lock(). | 86 | * Caller holds tomoyo_read_lock(). |
86 | */ | 87 | */ |
87 | bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, | 88 | const struct tomoyo_path_info * |
88 | const struct tomoyo_group *group) | 89 | tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, |
90 | const struct tomoyo_group *group) | ||
89 | { | 91 | { |
90 | struct tomoyo_path_group *member; | 92 | struct tomoyo_path_group *member; |
91 | bool matched = false; | ||
92 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 93 | list_for_each_entry_rcu(member, &group->member_list, head.list) { |
93 | if (member->head.is_deleted) | 94 | if (member->head.is_deleted) |
94 | continue; | 95 | continue; |
95 | if (!tomoyo_path_matches_pattern(pathname, member->member_name)) | 96 | if (!tomoyo_path_matches_pattern(pathname, member->member_name)) |
96 | continue; | 97 | continue; |
97 | matched = true; | 98 | return member->member_name; |
98 | break; | ||
99 | } | 99 | } |
100 | return matched; | 100 | return NULL; |
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index cfeff871908e..82bf8c2390bc 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c | |||
@@ -60,7 +60,7 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) | |||
60 | flags); | 60 | flags); |
61 | } | 61 | } |
62 | 62 | ||
63 | static bool tomoyo_check_mount_acl(const struct tomoyo_request_info *r, | 63 | static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, |
64 | const struct tomoyo_acl_info *ptr) | 64 | const struct tomoyo_acl_info *ptr) |
65 | { | 65 | { |
66 | const struct tomoyo_mount_acl *acl = | 66 | const struct tomoyo_mount_acl *acl = |