diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-09-10 02:25:58 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-09-13 18:27:06 -0400 |
commit | 731d37aa70c7b9de3be6bf2c8287366223bf5ce5 (patch) | |
tree | 8ac6028511485862572695eb91e2d461e0636182 /security/tomoyo/common.c | |
parent | 1f067a682a9bd252107ac6f6946b7332fde42344 (diff) |
TOMOYO: Allow domain transition without execve().
To be able to split permissions for Apache's CGI programs which are executed
without execve(), add special domain transition which is performed by writing
a TOMOYO's domainname to /sys/kernel/security/tomoyo/self_domain interface.
This is an API for TOMOYO-aware userland applications. However, since I expect
TOMOYO and other LSM modules to run in parallel, this patch does not use
/proc/self/attr/ interface in order to avoid conflicts with other LSM modules
when it became possible to run multiple LSM modules in parallel.
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/common.c')
-rw-r--r-- | security/tomoyo/common.c | 75 |
1 files changed, 50 insertions, 25 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 2704c384bf1e..1fd0fc1059ba 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1011,6 +1011,48 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, | |||
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | /** | 1013 | /** |
1014 | * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry. | ||
1015 | * | ||
1016 | * @a: Pointer to "struct tomoyo_acl_info". | ||
1017 | * @b: Pointer to "struct tomoyo_acl_info". | ||
1018 | * | ||
1019 | * Returns true if @a == @b, false otherwise. | ||
1020 | */ | ||
1021 | static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, | ||
1022 | const struct tomoyo_acl_info *b) | ||
1023 | { | ||
1024 | const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); | ||
1025 | const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); | ||
1026 | return p1->domainname == p2->domainname; | ||
1027 | } | ||
1028 | |||
1029 | /** | ||
1030 | * tomoyo_write_task - Update task related list. | ||
1031 | * | ||
1032 | * @param: Pointer to "struct tomoyo_acl_param". | ||
1033 | * | ||
1034 | * Returns 0 on success, negative value otherwise. | ||
1035 | * | ||
1036 | * Caller holds tomoyo_read_lock(). | ||
1037 | */ | ||
1038 | static int tomoyo_write_task(struct tomoyo_acl_param *param) | ||
1039 | { | ||
1040 | int error = -EINVAL; | ||
1041 | if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { | ||
1042 | struct tomoyo_task_acl e = { | ||
1043 | .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, | ||
1044 | .domainname = tomoyo_get_domainname(param), | ||
1045 | }; | ||
1046 | if (e.domainname) | ||
1047 | error = tomoyo_update_domain(&e.head, sizeof(e), param, | ||
1048 | tomoyo_same_task_acl, | ||
1049 | NULL); | ||
1050 | tomoyo_put_name(e.domainname); | ||
1051 | } | ||
1052 | return error; | ||
1053 | } | ||
1054 | |||
1055 | /** | ||
1014 | * tomoyo_delete_domain - Delete a domain. | 1056 | * tomoyo_delete_domain - Delete a domain. |
1015 | * | 1057 | * |
1016 | * @domainname: The name of domain. | 1058 | * @domainname: The name of domain. |
@@ -1068,11 +1110,12 @@ static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, | |||
1068 | static const struct { | 1110 | static const struct { |
1069 | const char *keyword; | 1111 | const char *keyword; |
1070 | int (*write) (struct tomoyo_acl_param *); | 1112 | int (*write) (struct tomoyo_acl_param *); |
1071 | } tomoyo_callback[4] = { | 1113 | } tomoyo_callback[5] = { |
1072 | { "file ", tomoyo_write_file }, | 1114 | { "file ", tomoyo_write_file }, |
1073 | { "network inet ", tomoyo_write_inet_network }, | 1115 | { "network inet ", tomoyo_write_inet_network }, |
1074 | { "network unix ", tomoyo_write_unix_network }, | 1116 | { "network unix ", tomoyo_write_unix_network }, |
1075 | { "misc ", tomoyo_write_misc }, | 1117 | { "misc ", tomoyo_write_misc }, |
1118 | { "task ", tomoyo_write_task }, | ||
1076 | }; | 1119 | }; |
1077 | u8 i; | 1120 | u8 i; |
1078 | 1121 | ||
@@ -1343,6 +1386,12 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1343 | if (first) | 1386 | if (first) |
1344 | return true; | 1387 | return true; |
1345 | tomoyo_print_name_union(head, &ptr->name); | 1388 | tomoyo_print_name_union(head, &ptr->name); |
1389 | } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { | ||
1390 | struct tomoyo_task_acl *ptr = | ||
1391 | container_of(acl, typeof(*ptr), head); | ||
1392 | tomoyo_set_group(head, "task "); | ||
1393 | tomoyo_set_string(head, "manual_domain_transition "); | ||
1394 | tomoyo_set_string(head, ptr->domainname->name); | ||
1346 | } else if (head->r.print_transition_related_only) { | 1395 | } else if (head->r.print_transition_related_only) { |
1347 | return true; | 1396 | return true; |
1348 | } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { | 1397 | } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { |
@@ -2178,26 +2227,6 @@ static void tomoyo_read_version(struct tomoyo_io_buffer *head) | |||
2178 | } | 2227 | } |
2179 | } | 2228 | } |
2180 | 2229 | ||
2181 | /** | ||
2182 | * tomoyo_read_self_domain - Get the current process's domainname. | ||
2183 | * | ||
2184 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
2185 | * | ||
2186 | * Returns the current process's domainname. | ||
2187 | */ | ||
2188 | static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head) | ||
2189 | { | ||
2190 | if (!head->r.eof) { | ||
2191 | /* | ||
2192 | * tomoyo_domain()->domainname != NULL | ||
2193 | * because every process belongs to a domain and | ||
2194 | * the domain's name cannot be NULL. | ||
2195 | */ | ||
2196 | tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); | ||
2197 | head->r.eof = true; | ||
2198 | } | ||
2199 | } | ||
2200 | |||
2201 | /* String table for /sys/kernel/security/tomoyo/stat interface. */ | 2230 | /* String table for /sys/kernel/security/tomoyo/stat interface. */ |
2202 | static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = { | 2231 | static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = { |
2203 | [TOMOYO_STAT_POLICY_UPDATES] = "update:", | 2232 | [TOMOYO_STAT_POLICY_UPDATES] = "update:", |
@@ -2328,10 +2357,6 @@ int tomoyo_open_control(const u8 type, struct file *file) | |||
2328 | head->poll = tomoyo_poll_log; | 2357 | head->poll = tomoyo_poll_log; |
2329 | head->read = tomoyo_read_log; | 2358 | head->read = tomoyo_read_log; |
2330 | break; | 2359 | break; |
2331 | case TOMOYO_SELFDOMAIN: | ||
2332 | /* /sys/kernel/security/tomoyo/self_domain */ | ||
2333 | head->read = tomoyo_read_self_domain; | ||
2334 | break; | ||
2335 | case TOMOYO_PROCESS_STATUS: | 2360 | case TOMOYO_PROCESS_STATUS: |
2336 | /* /sys/kernel/security/tomoyo/.process_status */ | 2361 | /* /sys/kernel/security/tomoyo/.process_status */ |
2337 | head->write = tomoyo_write_pid; | 2362 | head->write = tomoyo_write_pid; |