diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 258 |
1 files changed, 215 insertions, 43 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 2e43aec1c36b..c47d3ce6c733 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -20,6 +20,7 @@ const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = { | |||
20 | /* String table for /sys/kernel/security/tomoyo/profile */ | 20 | /* String table for /sys/kernel/security/tomoyo/profile */ |
21 | const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX | 21 | const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX |
22 | + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { | 22 | + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { |
23 | /* CONFIG::file group */ | ||
23 | [TOMOYO_MAC_FILE_EXECUTE] = "execute", | 24 | [TOMOYO_MAC_FILE_EXECUTE] = "execute", |
24 | [TOMOYO_MAC_FILE_OPEN] = "open", | 25 | [TOMOYO_MAC_FILE_OPEN] = "open", |
25 | [TOMOYO_MAC_FILE_CREATE] = "create", | 26 | [TOMOYO_MAC_FILE_CREATE] = "create", |
@@ -43,7 +44,28 @@ const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX | |||
43 | [TOMOYO_MAC_FILE_MOUNT] = "mount", | 44 | [TOMOYO_MAC_FILE_MOUNT] = "mount", |
44 | [TOMOYO_MAC_FILE_UMOUNT] = "unmount", | 45 | [TOMOYO_MAC_FILE_UMOUNT] = "unmount", |
45 | [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", | 46 | [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", |
47 | /* CONFIG::network group */ | ||
48 | [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind", | ||
49 | [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen", | ||
50 | [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect", | ||
51 | [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind", | ||
52 | [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send", | ||
53 | [TOMOYO_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind", | ||
54 | [TOMOYO_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send", | ||
55 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind", | ||
56 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen", | ||
57 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect", | ||
58 | [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind", | ||
59 | [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send", | ||
60 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind", | ||
61 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen", | ||
62 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect", | ||
63 | /* CONFIG::misc group */ | ||
64 | [TOMOYO_MAC_ENVIRON] = "env", | ||
65 | /* CONFIG group */ | ||
46 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", | 66 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", |
67 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network", | ||
68 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc", | ||
47 | }; | 69 | }; |
48 | 70 | ||
49 | /* String table for conditions. */ | 71 | /* String table for conditions. */ |
@@ -130,10 +152,20 @@ const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { | |||
130 | [TOMOYO_TYPE_UMOUNT] = "unmount", | 152 | [TOMOYO_TYPE_UMOUNT] = "unmount", |
131 | }; | 153 | }; |
132 | 154 | ||
155 | /* String table for socket's operation. */ | ||
156 | const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = { | ||
157 | [TOMOYO_NETWORK_BIND] = "bind", | ||
158 | [TOMOYO_NETWORK_LISTEN] = "listen", | ||
159 | [TOMOYO_NETWORK_CONNECT] = "connect", | ||
160 | [TOMOYO_NETWORK_SEND] = "send", | ||
161 | }; | ||
162 | |||
133 | /* String table for categories. */ | 163 | /* String table for categories. */ |
134 | static const char * const tomoyo_category_keywords | 164 | static const char * const tomoyo_category_keywords |
135 | [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { | 165 | [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { |
136 | [TOMOYO_MAC_CATEGORY_FILE] = "file", | 166 | [TOMOYO_MAC_CATEGORY_FILE] = "file", |
167 | [TOMOYO_MAC_CATEGORY_NETWORK] = "network", | ||
168 | [TOMOYO_MAC_CATEGORY_MISC] = "misc", | ||
137 | }; | 169 | }; |
138 | 170 | ||
139 | /* Permit policy management by non-root user? */ | 171 | /* Permit policy management by non-root user? */ |
@@ -230,13 +262,17 @@ static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string) | |||
230 | WARN_ON(1); | 262 | WARN_ON(1); |
231 | } | 263 | } |
232 | 264 | ||
265 | static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, | ||
266 | ...) __printf(2, 3); | ||
267 | |||
233 | /** | 268 | /** |
234 | * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. | 269 | * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. |
235 | * | 270 | * |
236 | * @head: Pointer to "struct tomoyo_io_buffer". | 271 | * @head: Pointer to "struct tomoyo_io_buffer". |
237 | * @fmt: The printf()'s format string, followed by parameters. | 272 | * @fmt: The printf()'s format string, followed by parameters. |
238 | */ | 273 | */ |
239 | void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) | 274 | static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, |
275 | ...) | ||
240 | { | 276 | { |
241 | va_list args; | 277 | va_list args; |
242 | size_t len; | 278 | size_t len; |
@@ -313,7 +349,7 @@ void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) | |||
313 | INIT_LIST_HEAD(&ns->group_list[idx]); | 349 | INIT_LIST_HEAD(&ns->group_list[idx]); |
314 | for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) | 350 | for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) |
315 | INIT_LIST_HEAD(&ns->policy_list[idx]); | 351 | INIT_LIST_HEAD(&ns->policy_list[idx]); |
316 | ns->profile_version = 20100903; | 352 | ns->profile_version = 20110903; |
317 | tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); | 353 | tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); |
318 | list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); | 354 | list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); |
319 | } | 355 | } |
@@ -466,8 +502,10 @@ static struct tomoyo_profile *tomoyo_assign_profile | |||
466 | TOMOYO_CONFIG_WANT_REJECT_LOG; | 502 | TOMOYO_CONFIG_WANT_REJECT_LOG; |
467 | memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, | 503 | memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, |
468 | sizeof(ptr->config)); | 504 | sizeof(ptr->config)); |
469 | ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024; | 505 | ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = |
470 | ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048; | 506 | CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG; |
507 | ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = | ||
508 | CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY; | ||
471 | mb(); /* Avoid out-of-order execution. */ | 509 | mb(); /* Avoid out-of-order execution. */ |
472 | ns->profile_ptr[profile] = ptr; | 510 | ns->profile_ptr[profile] = ptr; |
473 | entry = NULL; | 511 | entry = NULL; |
@@ -928,6 +966,9 @@ static bool tomoyo_manager(void) | |||
928 | return found; | 966 | return found; |
929 | } | 967 | } |
930 | 968 | ||
969 | static struct tomoyo_domain_info *tomoyo_find_domain_by_qid | ||
970 | (unsigned int serial); | ||
971 | |||
931 | /** | 972 | /** |
932 | * tomoyo_select_domain - Parse select command. | 973 | * tomoyo_select_domain - Parse select command. |
933 | * | 974 | * |
@@ -951,18 +992,18 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, | |||
951 | (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { | 992 | (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { |
952 | struct task_struct *p; | 993 | struct task_struct *p; |
953 | rcu_read_lock(); | 994 | rcu_read_lock(); |
954 | read_lock(&tasklist_lock); | ||
955 | if (global_pid) | 995 | if (global_pid) |
956 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 996 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
957 | else | 997 | else |
958 | p = find_task_by_vpid(pid); | 998 | p = find_task_by_vpid(pid); |
959 | if (p) | 999 | if (p) |
960 | domain = tomoyo_real_domain(p); | 1000 | domain = tomoyo_real_domain(p); |
961 | read_unlock(&tasklist_lock); | ||
962 | rcu_read_unlock(); | 1001 | rcu_read_unlock(); |
963 | } else if (!strncmp(data, "domain=", 7)) { | 1002 | } else if (!strncmp(data, "domain=", 7)) { |
964 | if (tomoyo_domain_def(data + 7)) | 1003 | if (tomoyo_domain_def(data + 7)) |
965 | domain = tomoyo_find_domain(data + 7); | 1004 | domain = tomoyo_find_domain(data + 7); |
1005 | } else if (sscanf(data, "Q=%u", &pid) == 1) { | ||
1006 | domain = tomoyo_find_domain_by_qid(pid); | ||
966 | } else | 1007 | } else |
967 | return false; | 1008 | return false; |
968 | head->w.domain = domain; | 1009 | head->w.domain = domain; |
@@ -982,6 +1023,48 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, | |||
982 | } | 1023 | } |
983 | 1024 | ||
984 | /** | 1025 | /** |
1026 | * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry. | ||
1027 | * | ||
1028 | * @a: Pointer to "struct tomoyo_acl_info". | ||
1029 | * @b: Pointer to "struct tomoyo_acl_info". | ||
1030 | * | ||
1031 | * Returns true if @a == @b, false otherwise. | ||
1032 | */ | ||
1033 | static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, | ||
1034 | const struct tomoyo_acl_info *b) | ||
1035 | { | ||
1036 | const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); | ||
1037 | const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); | ||
1038 | return p1->domainname == p2->domainname; | ||
1039 | } | ||
1040 | |||
1041 | /** | ||
1042 | * tomoyo_write_task - Update task related list. | ||
1043 | * | ||
1044 | * @param: Pointer to "struct tomoyo_acl_param". | ||
1045 | * | ||
1046 | * Returns 0 on success, negative value otherwise. | ||
1047 | * | ||
1048 | * Caller holds tomoyo_read_lock(). | ||
1049 | */ | ||
1050 | static int tomoyo_write_task(struct tomoyo_acl_param *param) | ||
1051 | { | ||
1052 | int error = -EINVAL; | ||
1053 | if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { | ||
1054 | struct tomoyo_task_acl e = { | ||
1055 | .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, | ||
1056 | .domainname = tomoyo_get_domainname(param), | ||
1057 | }; | ||
1058 | if (e.domainname) | ||
1059 | error = tomoyo_update_domain(&e.head, sizeof(e), param, | ||
1060 | tomoyo_same_task_acl, | ||
1061 | NULL); | ||
1062 | tomoyo_put_name(e.domainname); | ||
1063 | } | ||
1064 | return error; | ||
1065 | } | ||
1066 | |||
1067 | /** | ||
985 | * tomoyo_delete_domain - Delete a domain. | 1068 | * tomoyo_delete_domain - Delete a domain. |
986 | * | 1069 | * |
987 | * @domainname: The name of domain. | 1070 | * @domainname: The name of domain. |
@@ -1039,11 +1122,16 @@ static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, | |||
1039 | static const struct { | 1122 | static const struct { |
1040 | const char *keyword; | 1123 | const char *keyword; |
1041 | int (*write) (struct tomoyo_acl_param *); | 1124 | int (*write) (struct tomoyo_acl_param *); |
1042 | } tomoyo_callback[1] = { | 1125 | } tomoyo_callback[5] = { |
1043 | { "file ", tomoyo_write_file }, | 1126 | { "file ", tomoyo_write_file }, |
1127 | { "network inet ", tomoyo_write_inet_network }, | ||
1128 | { "network unix ", tomoyo_write_unix_network }, | ||
1129 | { "misc ", tomoyo_write_misc }, | ||
1130 | { "task ", tomoyo_write_task }, | ||
1044 | }; | 1131 | }; |
1045 | u8 i; | 1132 | u8 i; |
1046 | for (i = 0; i < 1; i++) { | 1133 | |
1134 | for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) { | ||
1047 | if (!tomoyo_str_starts(¶m.data, | 1135 | if (!tomoyo_str_starts(¶m.data, |
1048 | tomoyo_callback[i].keyword)) | 1136 | tomoyo_callback[i].keyword)) |
1049 | continue; | 1137 | continue; |
@@ -1127,6 +1215,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1127 | case 0: | 1215 | case 0: |
1128 | head->r.cond_index = 0; | 1216 | head->r.cond_index = 0; |
1129 | head->r.cond_step++; | 1217 | head->r.cond_step++; |
1218 | if (cond->transit) { | ||
1219 | tomoyo_set_space(head); | ||
1220 | tomoyo_set_string(head, cond->transit->name); | ||
1221 | } | ||
1130 | /* fall through */ | 1222 | /* fall through */ |
1131 | case 1: | 1223 | case 1: |
1132 | { | 1224 | { |
@@ -1239,6 +1331,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1239 | head->r.cond_step++; | 1331 | head->r.cond_step++; |
1240 | /* fall through */ | 1332 | /* fall through */ |
1241 | case 3: | 1333 | case 3: |
1334 | if (cond->grant_log != TOMOYO_GRANTLOG_AUTO) | ||
1335 | tomoyo_io_printf(head, " grant_log=%s", | ||
1336 | tomoyo_yesno(cond->grant_log == | ||
1337 | TOMOYO_GRANTLOG_YES)); | ||
1242 | tomoyo_set_lf(head); | 1338 | tomoyo_set_lf(head); |
1243 | return true; | 1339 | return true; |
1244 | } | 1340 | } |
@@ -1306,6 +1402,12 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1306 | if (first) | 1402 | if (first) |
1307 | return true; | 1403 | return true; |
1308 | tomoyo_print_name_union(head, &ptr->name); | 1404 | tomoyo_print_name_union(head, &ptr->name); |
1405 | } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { | ||
1406 | struct tomoyo_task_acl *ptr = | ||
1407 | container_of(acl, typeof(*ptr), head); | ||
1408 | tomoyo_set_group(head, "task "); | ||
1409 | tomoyo_set_string(head, "manual_domain_transition "); | ||
1410 | tomoyo_set_string(head, ptr->domainname->name); | ||
1309 | } else if (head->r.print_transition_related_only) { | 1411 | } else if (head->r.print_transition_related_only) { |
1310 | return true; | 1412 | return true; |
1311 | } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { | 1413 | } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { |
@@ -1370,6 +1472,60 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1370 | tomoyo_print_number_union(head, &ptr->mode); | 1472 | tomoyo_print_number_union(head, &ptr->mode); |
1371 | tomoyo_print_number_union(head, &ptr->major); | 1473 | tomoyo_print_number_union(head, &ptr->major); |
1372 | tomoyo_print_number_union(head, &ptr->minor); | 1474 | tomoyo_print_number_union(head, &ptr->minor); |
1475 | } else if (acl_type == TOMOYO_TYPE_INET_ACL) { | ||
1476 | struct tomoyo_inet_acl *ptr = | ||
1477 | container_of(acl, typeof(*ptr), head); | ||
1478 | const u8 perm = ptr->perm; | ||
1479 | |||
1480 | for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { | ||
1481 | if (!(perm & (1 << bit))) | ||
1482 | continue; | ||
1483 | if (first) { | ||
1484 | tomoyo_set_group(head, "network inet "); | ||
1485 | tomoyo_set_string(head, tomoyo_proto_keyword | ||
1486 | [ptr->protocol]); | ||
1487 | tomoyo_set_space(head); | ||
1488 | first = false; | ||
1489 | } else { | ||
1490 | tomoyo_set_slash(head); | ||
1491 | } | ||
1492 | tomoyo_set_string(head, tomoyo_socket_keyword[bit]); | ||
1493 | } | ||
1494 | if (first) | ||
1495 | return true; | ||
1496 | tomoyo_set_space(head); | ||
1497 | if (ptr->address.group) { | ||
1498 | tomoyo_set_string(head, "@"); | ||
1499 | tomoyo_set_string(head, ptr->address.group->group_name | ||
1500 | ->name); | ||
1501 | } else { | ||
1502 | char buf[128]; | ||
1503 | tomoyo_print_ip(buf, sizeof(buf), &ptr->address); | ||
1504 | tomoyo_io_printf(head, "%s", buf); | ||
1505 | } | ||
1506 | tomoyo_print_number_union(head, &ptr->port); | ||
1507 | } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) { | ||
1508 | struct tomoyo_unix_acl *ptr = | ||
1509 | container_of(acl, typeof(*ptr), head); | ||
1510 | const u8 perm = ptr->perm; | ||
1511 | |||
1512 | for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { | ||
1513 | if (!(perm & (1 << bit))) | ||
1514 | continue; | ||
1515 | if (first) { | ||
1516 | tomoyo_set_group(head, "network unix "); | ||
1517 | tomoyo_set_string(head, tomoyo_proto_keyword | ||
1518 | [ptr->protocol]); | ||
1519 | tomoyo_set_space(head); | ||
1520 | first = false; | ||
1521 | } else { | ||
1522 | tomoyo_set_slash(head); | ||
1523 | } | ||
1524 | tomoyo_set_string(head, tomoyo_socket_keyword[bit]); | ||
1525 | } | ||
1526 | if (first) | ||
1527 | return true; | ||
1528 | tomoyo_print_name_union(head, &ptr->name); | ||
1373 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { | 1529 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { |
1374 | struct tomoyo_mount_acl *ptr = | 1530 | struct tomoyo_mount_acl *ptr = |
1375 | container_of(acl, typeof(*ptr), head); | 1531 | container_of(acl, typeof(*ptr), head); |
@@ -1378,6 +1534,12 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1378 | tomoyo_print_name_union(head, &ptr->dir_name); | 1534 | tomoyo_print_name_union(head, &ptr->dir_name); |
1379 | tomoyo_print_name_union(head, &ptr->fs_type); | 1535 | tomoyo_print_name_union(head, &ptr->fs_type); |
1380 | tomoyo_print_number_union(head, &ptr->flags); | 1536 | tomoyo_print_number_union(head, &ptr->flags); |
1537 | } else if (acl_type == TOMOYO_TYPE_ENV_ACL) { | ||
1538 | struct tomoyo_env_acl *ptr = | ||
1539 | container_of(acl, typeof(*ptr), head); | ||
1540 | |||
1541 | tomoyo_set_group(head, "misc env "); | ||
1542 | tomoyo_set_string(head, ptr->env->name); | ||
1381 | } | 1543 | } |
1382 | if (acl->cond) { | 1544 | if (acl->cond) { |
1383 | head->r.print_cond_part = true; | 1545 | head->r.print_cond_part = true; |
@@ -1510,14 +1672,12 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head) | |||
1510 | global_pid = true; | 1672 | global_pid = true; |
1511 | pid = (unsigned int) simple_strtoul(buf, NULL, 10); | 1673 | pid = (unsigned int) simple_strtoul(buf, NULL, 10); |
1512 | rcu_read_lock(); | 1674 | rcu_read_lock(); |
1513 | read_lock(&tasklist_lock); | ||
1514 | if (global_pid) | 1675 | if (global_pid) |
1515 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 1676 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
1516 | else | 1677 | else |
1517 | p = find_task_by_vpid(pid); | 1678 | p = find_task_by_vpid(pid); |
1518 | if (p) | 1679 | if (p) |
1519 | domain = tomoyo_real_domain(p); | 1680 | domain = tomoyo_real_domain(p); |
1520 | read_unlock(&tasklist_lock); | ||
1521 | rcu_read_unlock(); | 1681 | rcu_read_unlock(); |
1522 | if (!domain) | 1682 | if (!domain) |
1523 | return; | 1683 | return; |
@@ -1537,8 +1697,9 @@ static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { | |||
1537 | 1697 | ||
1538 | /* String table for grouping keywords. */ | 1698 | /* String table for grouping keywords. */ |
1539 | static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { | 1699 | static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { |
1540 | [TOMOYO_PATH_GROUP] = "path_group ", | 1700 | [TOMOYO_PATH_GROUP] = "path_group ", |
1541 | [TOMOYO_NUMBER_GROUP] = "number_group ", | 1701 | [TOMOYO_NUMBER_GROUP] = "number_group ", |
1702 | [TOMOYO_ADDRESS_GROUP] = "address_group ", | ||
1542 | }; | 1703 | }; |
1543 | 1704 | ||
1544 | /** | 1705 | /** |
@@ -1580,7 +1741,7 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1580 | } | 1741 | } |
1581 | 1742 | ||
1582 | /** | 1743 | /** |
1583 | * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list. | 1744 | * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list. |
1584 | * | 1745 | * |
1585 | * @head: Pointer to "struct tomoyo_io_buffer". | 1746 | * @head: Pointer to "struct tomoyo_io_buffer". |
1586 | * @idx: Index number. | 1747 | * @idx: Index number. |
@@ -1617,6 +1778,15 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1617 | (ptr, | 1778 | (ptr, |
1618 | struct tomoyo_number_group, | 1779 | struct tomoyo_number_group, |
1619 | head)->number); | 1780 | head)->number); |
1781 | } else if (idx == TOMOYO_ADDRESS_GROUP) { | ||
1782 | char buffer[128]; | ||
1783 | |||
1784 | struct tomoyo_address_group *member = | ||
1785 | container_of(ptr, typeof(*member), | ||
1786 | head); | ||
1787 | tomoyo_print_ip(buffer, sizeof(buffer), | ||
1788 | &member->address); | ||
1789 | tomoyo_io_printf(head, " %s", buffer); | ||
1620 | } | 1790 | } |
1621 | tomoyo_set_lf(head); | 1791 | tomoyo_set_lf(head); |
1622 | } | 1792 | } |
@@ -1729,6 +1899,7 @@ static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait); | |||
1729 | /* Structure for query. */ | 1899 | /* Structure for query. */ |
1730 | struct tomoyo_query { | 1900 | struct tomoyo_query { |
1731 | struct list_head list; | 1901 | struct list_head list; |
1902 | struct tomoyo_domain_info *domain; | ||
1732 | char *query; | 1903 | char *query; |
1733 | size_t query_len; | 1904 | size_t query_len; |
1734 | unsigned int serial; | 1905 | unsigned int serial; |
@@ -1879,6 +2050,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) | |||
1879 | goto out; | 2050 | goto out; |
1880 | } | 2051 | } |
1881 | len = tomoyo_round2(entry.query_len); | 2052 | len = tomoyo_round2(entry.query_len); |
2053 | entry.domain = r->domain; | ||
1882 | spin_lock(&tomoyo_query_list_lock); | 2054 | spin_lock(&tomoyo_query_list_lock); |
1883 | if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] && | 2055 | if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] && |
1884 | tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len | 2056 | tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len |
@@ -1926,6 +2098,29 @@ out: | |||
1926 | } | 2098 | } |
1927 | 2099 | ||
1928 | /** | 2100 | /** |
2101 | * tomoyo_find_domain_by_qid - Get domain by query id. | ||
2102 | * | ||
2103 | * @serial: Query ID assigned by tomoyo_supervisor(). | ||
2104 | * | ||
2105 | * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. | ||
2106 | */ | ||
2107 | static struct tomoyo_domain_info *tomoyo_find_domain_by_qid | ||
2108 | (unsigned int serial) | ||
2109 | { | ||
2110 | struct tomoyo_query *ptr; | ||
2111 | struct tomoyo_domain_info *domain = NULL; | ||
2112 | spin_lock(&tomoyo_query_list_lock); | ||
2113 | list_for_each_entry(ptr, &tomoyo_query_list, list) { | ||
2114 | if (ptr->serial != serial || ptr->answer) | ||
2115 | continue; | ||
2116 | domain = ptr->domain; | ||
2117 | break; | ||
2118 | } | ||
2119 | spin_unlock(&tomoyo_query_list_lock); | ||
2120 | return domain; | ||
2121 | } | ||
2122 | |||
2123 | /** | ||
1929 | * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query. | 2124 | * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query. |
1930 | * | 2125 | * |
1931 | * @file: Pointer to "struct file". | 2126 | * @file: Pointer to "struct file". |
@@ -2066,27 +2261,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head) | |||
2066 | static void tomoyo_read_version(struct tomoyo_io_buffer *head) | 2261 | static void tomoyo_read_version(struct tomoyo_io_buffer *head) |
2067 | { | 2262 | { |
2068 | if (!head->r.eof) { | 2263 | if (!head->r.eof) { |
2069 | tomoyo_io_printf(head, "2.4.0"); | 2264 | tomoyo_io_printf(head, "2.5.0"); |
2070 | head->r.eof = true; | ||
2071 | } | ||
2072 | } | ||
2073 | |||
2074 | /** | ||
2075 | * tomoyo_read_self_domain - Get the current process's domainname. | ||
2076 | * | ||
2077 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
2078 | * | ||
2079 | * Returns the current process's domainname. | ||
2080 | */ | ||
2081 | static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head) | ||
2082 | { | ||
2083 | if (!head->r.eof) { | ||
2084 | /* | ||
2085 | * tomoyo_domain()->domainname != NULL | ||
2086 | * because every process belongs to a domain and | ||
2087 | * the domain's name cannot be NULL. | ||
2088 | */ | ||
2089 | tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); | ||
2090 | head->r.eof = true; | 2265 | head->r.eof = true; |
2091 | } | 2266 | } |
2092 | } | 2267 | } |
@@ -2221,10 +2396,6 @@ int tomoyo_open_control(const u8 type, struct file *file) | |||
2221 | head->poll = tomoyo_poll_log; | 2396 | head->poll = tomoyo_poll_log; |
2222 | head->read = tomoyo_read_log; | 2397 | head->read = tomoyo_read_log; |
2223 | break; | 2398 | break; |
2224 | case TOMOYO_SELFDOMAIN: | ||
2225 | /* /sys/kernel/security/tomoyo/self_domain */ | ||
2226 | head->read = tomoyo_read_self_domain; | ||
2227 | break; | ||
2228 | case TOMOYO_PROCESS_STATUS: | 2399 | case TOMOYO_PROCESS_STATUS: |
2229 | /* /sys/kernel/security/tomoyo/.process_status */ | 2400 | /* /sys/kernel/security/tomoyo/.process_status */ |
2230 | head->write = tomoyo_write_pid; | 2401 | head->write = tomoyo_write_pid; |
@@ -2453,6 +2624,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, | |||
2453 | return -EFAULT; | 2624 | return -EFAULT; |
2454 | if (mutex_lock_interruptible(&head->io_sem)) | 2625 | if (mutex_lock_interruptible(&head->io_sem)) |
2455 | return -EINTR; | 2626 | return -EINTR; |
2627 | head->read_user_buf_avail = 0; | ||
2456 | idx = tomoyo_read_lock(); | 2628 | idx = tomoyo_read_lock(); |
2457 | /* Read a line and dispatch it to the policy handler. */ | 2629 | /* Read a line and dispatch it to the policy handler. */ |
2458 | while (avail_len > 0) { | 2630 | while (avail_len > 0) { |
@@ -2562,11 +2734,11 @@ void tomoyo_check_profile(void) | |||
2562 | struct tomoyo_domain_info *domain; | 2734 | struct tomoyo_domain_info *domain; |
2563 | const int idx = tomoyo_read_lock(); | 2735 | const int idx = tomoyo_read_lock(); |
2564 | tomoyo_policy_loaded = true; | 2736 | tomoyo_policy_loaded = true; |
2565 | printk(KERN_INFO "TOMOYO: 2.4.0\n"); | 2737 | printk(KERN_INFO "TOMOYO: 2.5.0\n"); |
2566 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 2738 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
2567 | const u8 profile = domain->profile; | 2739 | const u8 profile = domain->profile; |
2568 | const struct tomoyo_policy_namespace *ns = domain->ns; | 2740 | const struct tomoyo_policy_namespace *ns = domain->ns; |
2569 | if (ns->profile_version != 20100903) | 2741 | if (ns->profile_version != 20110903) |
2570 | printk(KERN_ERR | 2742 | printk(KERN_ERR |
2571 | "Profile version %u is not supported.\n", | 2743 | "Profile version %u is not supported.\n", |
2572 | ns->profile_version); | 2744 | ns->profile_version); |
@@ -2577,9 +2749,9 @@ void tomoyo_check_profile(void) | |||
2577 | else | 2749 | else |
2578 | continue; | 2750 | continue; |
2579 | printk(KERN_ERR | 2751 | printk(KERN_ERR |
2580 | "Userland tools for TOMOYO 2.4 must be installed and " | 2752 | "Userland tools for TOMOYO 2.5 must be installed and " |
2581 | "policy must be initialized.\n"); | 2753 | "policy must be initialized.\n"); |
2582 | printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ " | 2754 | printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.5/ " |
2583 | "for more information.\n"); | 2755 | "for more information.\n"); |
2584 | panic("STOP!"); | 2756 | panic("STOP!"); |
2585 | } | 2757 | } |