diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 138 |
1 files changed, 99 insertions, 39 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 6936def78002..0f8079b65e23 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -197,6 +197,7 @@ static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) | |||
197 | { | 197 | { |
198 | va_list args; | 198 | va_list args; |
199 | const int pos = strlen(buffer); | 199 | const int pos = strlen(buffer); |
200 | |||
200 | va_start(args, fmt); | 201 | va_start(args, fmt); |
201 | vsnprintf(buffer + pos, len - pos - 1, fmt, args); | 202 | vsnprintf(buffer + pos, len - pos - 1, fmt, args); |
202 | va_end(args); | 203 | va_end(args); |
@@ -214,6 +215,7 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head) | |||
214 | while (head->r.w_pos) { | 215 | while (head->r.w_pos) { |
215 | const char *w = head->r.w[0]; | 216 | const char *w = head->r.w[0]; |
216 | size_t len = strlen(w); | 217 | size_t len = strlen(w); |
218 | |||
217 | if (len) { | 219 | if (len) { |
218 | if (len > head->read_user_buf_avail) | 220 | if (len > head->read_user_buf_avail) |
219 | len = head->read_user_buf_avail; | 221 | len = head->read_user_buf_avail; |
@@ -279,6 +281,7 @@ static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, | |||
279 | size_t len; | 281 | size_t len; |
280 | size_t pos = head->r.avail; | 282 | size_t pos = head->r.avail; |
281 | int size = head->readbuf_size - pos; | 283 | int size = head->readbuf_size - pos; |
284 | |||
282 | if (size <= 0) | 285 | if (size <= 0) |
283 | return; | 286 | return; |
284 | va_start(args, fmt); | 287 | va_start(args, fmt); |
@@ -344,6 +347,7 @@ static bool tomoyo_namespace_enabled; | |||
344 | void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) | 347 | void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) |
345 | { | 348 | { |
346 | unsigned int idx; | 349 | unsigned int idx; |
350 | |||
347 | for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) | 351 | for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) |
348 | INIT_LIST_HEAD(&ns->acl_group[idx]); | 352 | INIT_LIST_HEAD(&ns->acl_group[idx]); |
349 | for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++) | 353 | for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++) |
@@ -433,6 +437,7 @@ static void tomoyo_print_number_union_nospace | |||
433 | u8 min_type = ptr->value_type[0]; | 437 | u8 min_type = ptr->value_type[0]; |
434 | const u8 max_type = ptr->value_type[1]; | 438 | const u8 max_type = ptr->value_type[1]; |
435 | char buffer[128]; | 439 | char buffer[128]; |
440 | |||
436 | buffer[0] = '\0'; | 441 | buffer[0] = '\0'; |
437 | for (i = 0; i < 2; i++) { | 442 | for (i = 0; i < 2; i++) { |
438 | switch (min_type) { | 443 | switch (min_type) { |
@@ -487,6 +492,7 @@ static struct tomoyo_profile *tomoyo_assign_profile | |||
487 | { | 492 | { |
488 | struct tomoyo_profile *ptr; | 493 | struct tomoyo_profile *ptr; |
489 | struct tomoyo_profile *entry; | 494 | struct tomoyo_profile *entry; |
495 | |||
490 | if (profile >= TOMOYO_MAX_PROFILES) | 496 | if (profile >= TOMOYO_MAX_PROFILES) |
491 | return NULL; | 497 | return NULL; |
492 | ptr = ns->profile_ptr[profile]; | 498 | ptr = ns->profile_ptr[profile]; |
@@ -530,6 +536,7 @@ struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns, | |||
530 | { | 536 | { |
531 | static struct tomoyo_profile tomoyo_null_profile; | 537 | static struct tomoyo_profile tomoyo_null_profile; |
532 | struct tomoyo_profile *ptr = ns->profile_ptr[profile]; | 538 | struct tomoyo_profile *ptr = ns->profile_ptr[profile]; |
539 | |||
533 | if (!ptr) | 540 | if (!ptr) |
534 | ptr = &tomoyo_null_profile; | 541 | ptr = &tomoyo_null_profile; |
535 | return ptr; | 542 | return ptr; |
@@ -546,6 +553,7 @@ struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns, | |||
546 | static s8 tomoyo_find_yesno(const char *string, const char *find) | 553 | static s8 tomoyo_find_yesno(const char *string, const char *find) |
547 | { | 554 | { |
548 | const char *cp = strstr(string, find); | 555 | const char *cp = strstr(string, find); |
556 | |||
549 | if (cp) { | 557 | if (cp) { |
550 | cp += strlen(find); | 558 | cp += strlen(find); |
551 | if (!strncmp(cp, "=yes", 4)) | 559 | if (!strncmp(cp, "=yes", 4)) |
@@ -569,6 +577,7 @@ static void tomoyo_set_uint(unsigned int *i, const char *string, | |||
569 | const char *find) | 577 | const char *find) |
570 | { | 578 | { |
571 | const char *cp = strstr(string, find); | 579 | const char *cp = strstr(string, find); |
580 | |||
572 | if (cp) | 581 | if (cp) |
573 | sscanf(cp + strlen(find), "=%u", i); | 582 | sscanf(cp + strlen(find), "=%u", i); |
574 | } | 583 | } |
@@ -587,6 +596,7 @@ static int tomoyo_set_mode(char *name, const char *value, | |||
587 | { | 596 | { |
588 | u8 i; | 597 | u8 i; |
589 | u8 config; | 598 | u8 config; |
599 | |||
590 | if (!strcmp(name, "CONFIG")) { | 600 | if (!strcmp(name, "CONFIG")) { |
591 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; | 601 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; |
592 | config = profile->default_config; | 602 | config = profile->default_config; |
@@ -595,10 +605,12 @@ static int tomoyo_set_mode(char *name, const char *value, | |||
595 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX | 605 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX |
596 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { | 606 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { |
597 | int len = 0; | 607 | int len = 0; |
608 | |||
598 | if (i < TOMOYO_MAX_MAC_INDEX) { | 609 | if (i < TOMOYO_MAX_MAC_INDEX) { |
599 | const u8 c = tomoyo_index2category[i]; | 610 | const u8 c = tomoyo_index2category[i]; |
600 | const char *category = | 611 | const char *category = |
601 | tomoyo_category_keywords[c]; | 612 | tomoyo_category_keywords[c]; |
613 | |||
602 | len = strlen(category); | 614 | len = strlen(category); |
603 | if (strncmp(name, category, len) || | 615 | if (strncmp(name, category, len) || |
604 | name[len++] != ':' || name[len++] != ':') | 616 | name[len++] != ':' || name[len++] != ':') |
@@ -618,6 +630,7 @@ static int tomoyo_set_mode(char *name, const char *value, | |||
618 | config = TOMOYO_CONFIG_USE_DEFAULT; | 630 | config = TOMOYO_CONFIG_USE_DEFAULT; |
619 | } else { | 631 | } else { |
620 | u8 mode; | 632 | u8 mode; |
633 | |||
621 | for (mode = 0; mode < 4; mode++) | 634 | for (mode = 0; mode < 4; mode++) |
622 | if (strstr(value, tomoyo_mode[mode])) | 635 | if (strstr(value, tomoyo_mode[mode])) |
623 | /* | 636 | /* |
@@ -664,6 +677,7 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
664 | unsigned int i; | 677 | unsigned int i; |
665 | char *cp; | 678 | char *cp; |
666 | struct tomoyo_profile *profile; | 679 | struct tomoyo_profile *profile; |
680 | |||
667 | if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) | 681 | if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) |
668 | == 1) | 682 | == 1) |
669 | return 0; | 683 | return 0; |
@@ -683,6 +697,7 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) | |||
683 | const struct tomoyo_path_info *new_comment | 697 | const struct tomoyo_path_info *new_comment |
684 | = tomoyo_get_name(cp); | 698 | = tomoyo_get_name(cp); |
685 | const struct tomoyo_path_info *old_comment; | 699 | const struct tomoyo_path_info *old_comment; |
700 | |||
686 | if (!new_comment) | 701 | if (!new_comment) |
687 | return -ENOMEM; | 702 | return -ENOMEM; |
688 | spin_lock(&lock); | 703 | spin_lock(&lock); |
@@ -732,6 +747,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head) | |||
732 | struct tomoyo_policy_namespace *ns = | 747 | struct tomoyo_policy_namespace *ns = |
733 | container_of(head->r.ns, typeof(*ns), namespace_list); | 748 | container_of(head->r.ns, typeof(*ns), namespace_list); |
734 | const struct tomoyo_profile *profile; | 749 | const struct tomoyo_profile *profile; |
750 | |||
735 | if (head->r.eof) | 751 | if (head->r.eof) |
736 | return; | 752 | return; |
737 | next: | 753 | next: |
@@ -760,6 +776,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head) | |||
760 | u8 i; | 776 | u8 i; |
761 | const struct tomoyo_path_info *comment = | 777 | const struct tomoyo_path_info *comment = |
762 | profile->comment; | 778 | profile->comment; |
779 | |||
763 | tomoyo_print_namespace(head); | 780 | tomoyo_print_namespace(head); |
764 | tomoyo_io_printf(head, "%u-COMMENT=", index); | 781 | tomoyo_io_printf(head, "%u-COMMENT=", index); |
765 | tomoyo_set_string(head, comment ? comment->name : ""); | 782 | tomoyo_set_string(head, comment ? comment->name : ""); |
@@ -788,6 +805,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head) | |||
788 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { | 805 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { |
789 | const u8 i = head->r.bit; | 806 | const u8 i = head->r.bit; |
790 | const u8 config = profile->config[i]; | 807 | const u8 config = profile->config[i]; |
808 | |||
791 | if (config == TOMOYO_CONFIG_USE_DEFAULT) | 809 | if (config == TOMOYO_CONFIG_USE_DEFAULT) |
792 | continue; | 810 | continue; |
793 | tomoyo_print_namespace(head); | 811 | tomoyo_print_namespace(head); |
@@ -847,10 +865,10 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
847 | struct tomoyo_acl_param param = { | 865 | struct tomoyo_acl_param param = { |
848 | /* .ns = &tomoyo_kernel_namespace, */ | 866 | /* .ns = &tomoyo_kernel_namespace, */ |
849 | .is_delete = is_delete, | 867 | .is_delete = is_delete, |
850 | .list = &tomoyo_kernel_namespace. | 868 | .list = &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], |
851 | policy_list[TOMOYO_ID_MANAGER], | ||
852 | }; | 869 | }; |
853 | int error = is_delete ? -ENOENT : -ENOMEM; | 870 | int error = is_delete ? -ENOENT : -ENOMEM; |
871 | |||
854 | if (!tomoyo_correct_domain(manager) && | 872 | if (!tomoyo_correct_domain(manager) && |
855 | !tomoyo_correct_word(manager)) | 873 | !tomoyo_correct_word(manager)) |
856 | return -EINVAL; | 874 | return -EINVAL; |
@@ -894,10 +912,10 @@ static void tomoyo_read_manager(struct tomoyo_io_buffer *head) | |||
894 | { | 912 | { |
895 | if (head->r.eof) | 913 | if (head->r.eof) |
896 | return; | 914 | return; |
897 | list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace. | 915 | list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER]) { |
898 | policy_list[TOMOYO_ID_MANAGER]) { | ||
899 | struct tomoyo_manager *ptr = | 916 | struct tomoyo_manager *ptr = |
900 | list_entry(head->r.acl, typeof(*ptr), head.list); | 917 | list_entry(head->r.acl, typeof(*ptr), head.list); |
918 | |||
901 | if (ptr->head.is_deleted) | 919 | if (ptr->head.is_deleted) |
902 | continue; | 920 | continue; |
903 | if (!tomoyo_flush(head)) | 921 | if (!tomoyo_flush(head)) |
@@ -933,8 +951,7 @@ static bool tomoyo_manager(void) | |||
933 | exe = tomoyo_get_exe(); | 951 | exe = tomoyo_get_exe(); |
934 | if (!exe) | 952 | if (!exe) |
935 | return false; | 953 | return false; |
936 | list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. | 954 | list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list) { |
937 | policy_list[TOMOYO_ID_MANAGER], head.list) { | ||
938 | if (!ptr->head.is_deleted && | 955 | if (!ptr->head.is_deleted && |
939 | (!tomoyo_pathcmp(domainname, ptr->manager) || | 956 | (!tomoyo_pathcmp(domainname, ptr->manager) || |
940 | !strcmp(exe, ptr->manager->name))) { | 957 | !strcmp(exe, ptr->manager->name))) { |
@@ -945,9 +962,10 @@ static bool tomoyo_manager(void) | |||
945 | if (!found) { /* Reduce error messages. */ | 962 | if (!found) { /* Reduce error messages. */ |
946 | static pid_t last_pid; | 963 | static pid_t last_pid; |
947 | const pid_t pid = current->pid; | 964 | const pid_t pid = current->pid; |
965 | |||
948 | if (last_pid != pid) { | 966 | if (last_pid != pid) { |
949 | printk(KERN_WARNING "%s ( %s ) is not permitted to " | 967 | pr_warn("%s ( %s ) is not permitted to update policies.\n", |
950 | "update policies.\n", domainname->name, exe); | 968 | domainname->name, exe); |
951 | last_pid = pid; | 969 | last_pid = pid; |
952 | } | 970 | } |
953 | } | 971 | } |
@@ -974,12 +992,14 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, | |||
974 | unsigned int pid; | 992 | unsigned int pid; |
975 | struct tomoyo_domain_info *domain = NULL; | 993 | struct tomoyo_domain_info *domain = NULL; |
976 | bool global_pid = false; | 994 | bool global_pid = false; |
995 | |||
977 | if (strncmp(data, "select ", 7)) | 996 | if (strncmp(data, "select ", 7)) |
978 | return false; | 997 | return false; |
979 | data += 7; | 998 | data += 7; |
980 | if (sscanf(data, "pid=%u", &pid) == 1 || | 999 | if (sscanf(data, "pid=%u", &pid) == 1 || |
981 | (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { | 1000 | (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { |
982 | struct task_struct *p; | 1001 | struct task_struct *p; |
1002 | |||
983 | rcu_read_lock(); | 1003 | rcu_read_lock(); |
984 | if (global_pid) | 1004 | if (global_pid) |
985 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 1005 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
@@ -1020,10 +1040,11 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, | |||
1020 | * Returns true if @a == @b, false otherwise. | 1040 | * Returns true if @a == @b, false otherwise. |
1021 | */ | 1041 | */ |
1022 | static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, | 1042 | static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, |
1023 | const struct tomoyo_acl_info *b) | 1043 | const struct tomoyo_acl_info *b) |
1024 | { | 1044 | { |
1025 | const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); | 1045 | const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); |
1026 | const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); | 1046 | const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); |
1047 | |||
1027 | return p1->domainname == p2->domainname; | 1048 | return p1->domainname == p2->domainname; |
1028 | } | 1049 | } |
1029 | 1050 | ||
@@ -1039,11 +1060,13 @@ static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, | |||
1039 | static int tomoyo_write_task(struct tomoyo_acl_param *param) | 1060 | static int tomoyo_write_task(struct tomoyo_acl_param *param) |
1040 | { | 1061 | { |
1041 | int error = -EINVAL; | 1062 | int error = -EINVAL; |
1063 | |||
1042 | if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { | 1064 | if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { |
1043 | struct tomoyo_task_acl e = { | 1065 | struct tomoyo_task_acl e = { |
1044 | .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, | 1066 | .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, |
1045 | .domainname = tomoyo_get_domainname(param), | 1067 | .domainname = tomoyo_get_domainname(param), |
1046 | }; | 1068 | }; |
1069 | |||
1047 | if (e.domainname) | 1070 | if (e.domainname) |
1048 | error = tomoyo_update_domain(&e.head, sizeof(e), param, | 1071 | error = tomoyo_update_domain(&e.head, sizeof(e), param, |
1049 | tomoyo_same_task_acl, | 1072 | tomoyo_same_task_acl, |
@@ -1110,7 +1133,7 @@ static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, | |||
1110 | }; | 1133 | }; |
1111 | static const struct { | 1134 | static const struct { |
1112 | const char *keyword; | 1135 | const char *keyword; |
1113 | int (*write) (struct tomoyo_acl_param *); | 1136 | int (*write)(struct tomoyo_acl_param *param); |
1114 | } tomoyo_callback[5] = { | 1137 | } tomoyo_callback[5] = { |
1115 | { "file ", tomoyo_write_file }, | 1138 | { "file ", tomoyo_write_file }, |
1116 | { "network inet ", tomoyo_write_inet_network }, | 1139 | { "network inet ", tomoyo_write_inet_network }, |
@@ -1152,8 +1175,10 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
1152 | const bool is_delete = head->w.is_delete; | 1175 | const bool is_delete = head->w.is_delete; |
1153 | bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); | 1176 | bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); |
1154 | unsigned int profile; | 1177 | unsigned int profile; |
1178 | |||
1155 | if (*data == '<') { | 1179 | if (*data == '<') { |
1156 | int ret = 0; | 1180 | int ret = 0; |
1181 | |||
1157 | domain = NULL; | 1182 | domain = NULL; |
1158 | if (is_delete) | 1183 | if (is_delete) |
1159 | ret = tomoyo_delete_domain(data); | 1184 | ret = tomoyo_delete_domain(data); |
@@ -1181,6 +1206,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
1181 | } | 1206 | } |
1182 | for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { | 1207 | for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { |
1183 | const char *cp = tomoyo_dif[profile]; | 1208 | const char *cp = tomoyo_dif[profile]; |
1209 | |||
1184 | if (strncmp(data, cp, strlen(cp) - 1)) | 1210 | if (strncmp(data, cp, strlen(cp) - 1)) |
1185 | continue; | 1211 | continue; |
1186 | domain->flags[profile] = !is_delete; | 1212 | domain->flags[profile] = !is_delete; |
@@ -1225,9 +1251,11 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1225 | const struct tomoyo_envp *envp = | 1251 | const struct tomoyo_envp *envp = |
1226 | (typeof(envp)) (argv + cond->argc); | 1252 | (typeof(envp)) (argv + cond->argc); |
1227 | u16 skip; | 1253 | u16 skip; |
1254 | |||
1228 | for (skip = 0; skip < head->r.cond_index; skip++) { | 1255 | for (skip = 0; skip < head->r.cond_index; skip++) { |
1229 | const u8 left = condp->left; | 1256 | const u8 left = condp->left; |
1230 | const u8 right = condp->right; | 1257 | const u8 right = condp->right; |
1258 | |||
1231 | condp++; | 1259 | condp++; |
1232 | switch (left) { | 1260 | switch (left) { |
1233 | case TOMOYO_ARGV_ENTRY: | 1261 | case TOMOYO_ARGV_ENTRY: |
@@ -1253,6 +1281,7 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1253 | const u8 match = condp->equals; | 1281 | const u8 match = condp->equals; |
1254 | const u8 left = condp->left; | 1282 | const u8 left = condp->left; |
1255 | const u8 right = condp->right; | 1283 | const u8 right = condp->right; |
1284 | |||
1256 | if (!tomoyo_flush(head)) | 1285 | if (!tomoyo_flush(head)) |
1257 | return false; | 1286 | return false; |
1258 | condp++; | 1287 | condp++; |
@@ -1262,8 +1291,7 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1262 | case TOMOYO_ARGV_ENTRY: | 1291 | case TOMOYO_ARGV_ENTRY: |
1263 | tomoyo_io_printf(head, | 1292 | tomoyo_io_printf(head, |
1264 | "exec.argv[%lu]%s=\"", | 1293 | "exec.argv[%lu]%s=\"", |
1265 | argv->index, argv-> | 1294 | argv->index, argv->is_not ? "!" : ""); |
1266 | is_not ? "!" : ""); | ||
1267 | tomoyo_set_string(head, | 1295 | tomoyo_set_string(head, |
1268 | argv->value->name); | 1296 | argv->value->name); |
1269 | tomoyo_set_string(head, "\""); | 1297 | tomoyo_set_string(head, "\""); |
@@ -1274,12 +1302,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
1274 | "exec.envp[\""); | 1302 | "exec.envp[\""); |
1275 | tomoyo_set_string(head, | 1303 | tomoyo_set_string(head, |
1276 | envp->name->name); | 1304 | envp->name->name); |
1277 | tomoyo_io_printf(head, "\"]%s=", envp-> | 1305 | tomoyo_io_printf(head, "\"]%s=", envp->is_not ? "!" : ""); |
1278 | is_not ? "!" : ""); | ||
1279 | if (envp->value) { | 1306 | if (envp->value) { |
1280 | tomoyo_set_string(head, "\""); | 1307 | tomoyo_set_string(head, "\""); |
1281 | tomoyo_set_string(head, envp-> | 1308 | tomoyo_set_string(head, envp->value->name); |
1282 | value->name); | ||
1283 | tomoyo_set_string(head, "\""); | 1309 | tomoyo_set_string(head, "\""); |
1284 | } else { | 1310 | } else { |
1285 | tomoyo_set_string(head, | 1311 | tomoyo_set_string(head, |
@@ -1375,6 +1401,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1375 | struct tomoyo_path_acl *ptr = | 1401 | struct tomoyo_path_acl *ptr = |
1376 | container_of(acl, typeof(*ptr), head); | 1402 | container_of(acl, typeof(*ptr), head); |
1377 | const u16 perm = ptr->perm; | 1403 | const u16 perm = ptr->perm; |
1404 | |||
1378 | for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { | 1405 | for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { |
1379 | if (!(perm & (1 << bit))) | 1406 | if (!(perm & (1 << bit))) |
1380 | continue; | 1407 | continue; |
@@ -1395,6 +1422,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1395 | } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { | 1422 | } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { |
1396 | struct tomoyo_task_acl *ptr = | 1423 | struct tomoyo_task_acl *ptr = |
1397 | container_of(acl, typeof(*ptr), head); | 1424 | container_of(acl, typeof(*ptr), head); |
1425 | |||
1398 | tomoyo_set_group(head, "task "); | 1426 | tomoyo_set_group(head, "task "); |
1399 | tomoyo_set_string(head, "manual_domain_transition "); | 1427 | tomoyo_set_string(head, "manual_domain_transition "); |
1400 | tomoyo_set_string(head, ptr->domainname->name); | 1428 | tomoyo_set_string(head, ptr->domainname->name); |
@@ -1404,6 +1432,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1404 | struct tomoyo_path2_acl *ptr = | 1432 | struct tomoyo_path2_acl *ptr = |
1405 | container_of(acl, typeof(*ptr), head); | 1433 | container_of(acl, typeof(*ptr), head); |
1406 | const u8 perm = ptr->perm; | 1434 | const u8 perm = ptr->perm; |
1435 | |||
1407 | for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { | 1436 | for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { |
1408 | if (!(perm & (1 << bit))) | 1437 | if (!(perm & (1 << bit))) |
1409 | continue; | 1438 | continue; |
@@ -1424,6 +1453,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1424 | struct tomoyo_path_number_acl *ptr = | 1453 | struct tomoyo_path_number_acl *ptr = |
1425 | container_of(acl, typeof(*ptr), head); | 1454 | container_of(acl, typeof(*ptr), head); |
1426 | const u8 perm = ptr->perm; | 1455 | const u8 perm = ptr->perm; |
1456 | |||
1427 | for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) { | 1457 | for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) { |
1428 | if (!(perm & (1 << bit))) | 1458 | if (!(perm & (1 << bit))) |
1429 | continue; | 1459 | continue; |
@@ -1444,6 +1474,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1444 | struct tomoyo_mkdev_acl *ptr = | 1474 | struct tomoyo_mkdev_acl *ptr = |
1445 | container_of(acl, typeof(*ptr), head); | 1475 | container_of(acl, typeof(*ptr), head); |
1446 | const u8 perm = ptr->perm; | 1476 | const u8 perm = ptr->perm; |
1477 | |||
1447 | for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) { | 1478 | for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) { |
1448 | if (!(perm & (1 << bit))) | 1479 | if (!(perm & (1 << bit))) |
1449 | continue; | 1480 | continue; |
@@ -1490,6 +1521,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1490 | ->name); | 1521 | ->name); |
1491 | } else { | 1522 | } else { |
1492 | char buf[128]; | 1523 | char buf[128]; |
1524 | |||
1493 | tomoyo_print_ip(buf, sizeof(buf), &ptr->address); | 1525 | tomoyo_print_ip(buf, sizeof(buf), &ptr->address); |
1494 | tomoyo_io_printf(head, "%s", buf); | 1526 | tomoyo_io_printf(head, "%s", buf); |
1495 | } | 1527 | } |
@@ -1519,6 +1551,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1519 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { | 1551 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { |
1520 | struct tomoyo_mount_acl *ptr = | 1552 | struct tomoyo_mount_acl *ptr = |
1521 | container_of(acl, typeof(*ptr), head); | 1553 | container_of(acl, typeof(*ptr), head); |
1554 | |||
1522 | tomoyo_set_group(head, "file mount"); | 1555 | tomoyo_set_group(head, "file mount"); |
1523 | tomoyo_print_name_union(head, &ptr->dev_name); | 1556 | tomoyo_print_name_union(head, &ptr->dev_name); |
1524 | tomoyo_print_name_union(head, &ptr->dir_name); | 1557 | tomoyo_print_name_union(head, &ptr->dir_name); |
@@ -1562,6 +1595,7 @@ static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, | |||
1562 | list_for_each_cookie(head->r.acl, list) { | 1595 | list_for_each_cookie(head->r.acl, list) { |
1563 | struct tomoyo_acl_info *ptr = | 1596 | struct tomoyo_acl_info *ptr = |
1564 | list_entry(head->r.acl, typeof(*ptr), list); | 1597 | list_entry(head->r.acl, typeof(*ptr), list); |
1598 | |||
1565 | if (!tomoyo_print_entry(head, ptr)) | 1599 | if (!tomoyo_print_entry(head, ptr)) |
1566 | return false; | 1600 | return false; |
1567 | } | 1601 | } |
@@ -1583,8 +1617,9 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head) | |||
1583 | list_for_each_cookie(head->r.domain, &tomoyo_domain_list) { | 1617 | list_for_each_cookie(head->r.domain, &tomoyo_domain_list) { |
1584 | struct tomoyo_domain_info *domain = | 1618 | struct tomoyo_domain_info *domain = |
1585 | list_entry(head->r.domain, typeof(*domain), list); | 1619 | list_entry(head->r.domain, typeof(*domain), list); |
1620 | u8 i; | ||
1621 | |||
1586 | switch (head->r.step) { | 1622 | switch (head->r.step) { |
1587 | u8 i; | ||
1588 | case 0: | 1623 | case 0: |
1589 | if (domain->is_deleted && | 1624 | if (domain->is_deleted && |
1590 | !head->r.print_this_domain_only) | 1625 | !head->r.print_this_domain_only) |
@@ -1711,6 +1746,7 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1711 | .data = head->write_buf, | 1746 | .data = head->write_buf, |
1712 | }; | 1747 | }; |
1713 | u8 i; | 1748 | u8 i; |
1749 | |||
1714 | if (tomoyo_str_starts(¶m.data, "aggregator ")) | 1750 | if (tomoyo_str_starts(¶m.data, "aggregator ")) |
1715 | return tomoyo_write_aggregator(¶m); | 1751 | return tomoyo_write_aggregator(¶m); |
1716 | for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) | 1752 | for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) |
@@ -1722,6 +1758,7 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1722 | if (tomoyo_str_starts(¶m.data, "acl_group ")) { | 1758 | if (tomoyo_str_starts(¶m.data, "acl_group ")) { |
1723 | unsigned int group; | 1759 | unsigned int group; |
1724 | char *data; | 1760 | char *data; |
1761 | |||
1725 | group = simple_strtoul(param.data, &data, 10); | 1762 | group = simple_strtoul(param.data, &data, 10); |
1726 | if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') | 1763 | if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') |
1727 | return tomoyo_write_domain2 | 1764 | return tomoyo_write_domain2 |
@@ -1746,12 +1783,15 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1746 | struct tomoyo_policy_namespace *ns = | 1783 | struct tomoyo_policy_namespace *ns = |
1747 | container_of(head->r.ns, typeof(*ns), namespace_list); | 1784 | container_of(head->r.ns, typeof(*ns), namespace_list); |
1748 | struct list_head *list = &ns->group_list[idx]; | 1785 | struct list_head *list = &ns->group_list[idx]; |
1786 | |||
1749 | list_for_each_cookie(head->r.group, list) { | 1787 | list_for_each_cookie(head->r.group, list) { |
1750 | struct tomoyo_group *group = | 1788 | struct tomoyo_group *group = |
1751 | list_entry(head->r.group, typeof(*group), head.list); | 1789 | list_entry(head->r.group, typeof(*group), head.list); |
1790 | |||
1752 | list_for_each_cookie(head->r.acl, &group->member_list) { | 1791 | list_for_each_cookie(head->r.acl, &group->member_list) { |
1753 | struct tomoyo_acl_head *ptr = | 1792 | struct tomoyo_acl_head *ptr = |
1754 | list_entry(head->r.acl, typeof(*ptr), list); | 1793 | list_entry(head->r.acl, typeof(*ptr), list); |
1794 | |||
1755 | if (ptr->is_deleted) | 1795 | if (ptr->is_deleted) |
1756 | continue; | 1796 | continue; |
1757 | if (!tomoyo_flush(head)) | 1797 | if (!tomoyo_flush(head)) |
@@ -1771,10 +1811,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1771 | head)->number); | 1811 | head)->number); |
1772 | } else if (idx == TOMOYO_ADDRESS_GROUP) { | 1812 | } else if (idx == TOMOYO_ADDRESS_GROUP) { |
1773 | char buffer[128]; | 1813 | char buffer[128]; |
1774 | |||
1775 | struct tomoyo_address_group *member = | 1814 | struct tomoyo_address_group *member = |
1776 | container_of(ptr, typeof(*member), | 1815 | container_of(ptr, typeof(*member), |
1777 | head); | 1816 | head); |
1817 | |||
1778 | tomoyo_print_ip(buffer, sizeof(buffer), | 1818 | tomoyo_print_ip(buffer, sizeof(buffer), |
1779 | &member->address); | 1819 | &member->address); |
1780 | tomoyo_io_printf(head, " %s", buffer); | 1820 | tomoyo_io_printf(head, " %s", buffer); |
@@ -1802,6 +1842,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | |||
1802 | struct tomoyo_policy_namespace *ns = | 1842 | struct tomoyo_policy_namespace *ns = |
1803 | container_of(head->r.ns, typeof(*ns), namespace_list); | 1843 | container_of(head->r.ns, typeof(*ns), namespace_list); |
1804 | struct list_head *list = &ns->policy_list[idx]; | 1844 | struct list_head *list = &ns->policy_list[idx]; |
1845 | |||
1805 | list_for_each_cookie(head->r.acl, list) { | 1846 | list_for_each_cookie(head->r.acl, list) { |
1806 | struct tomoyo_acl_head *acl = | 1847 | struct tomoyo_acl_head *acl = |
1807 | container_of(head->r.acl, typeof(*acl), list); | 1848 | container_of(head->r.acl, typeof(*acl), list); |
@@ -1814,6 +1855,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | |||
1814 | { | 1855 | { |
1815 | struct tomoyo_transition_control *ptr = | 1856 | struct tomoyo_transition_control *ptr = |
1816 | container_of(acl, typeof(*ptr), head); | 1857 | container_of(acl, typeof(*ptr), head); |
1858 | |||
1817 | tomoyo_print_namespace(head); | 1859 | tomoyo_print_namespace(head); |
1818 | tomoyo_set_string(head, tomoyo_transition_type | 1860 | tomoyo_set_string(head, tomoyo_transition_type |
1819 | [ptr->type]); | 1861 | [ptr->type]); |
@@ -1829,6 +1871,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | |||
1829 | { | 1871 | { |
1830 | struct tomoyo_aggregator *ptr = | 1872 | struct tomoyo_aggregator *ptr = |
1831 | container_of(acl, typeof(*ptr), head); | 1873 | container_of(acl, typeof(*ptr), head); |
1874 | |||
1832 | tomoyo_print_namespace(head); | 1875 | tomoyo_print_namespace(head); |
1833 | tomoyo_set_string(head, "aggregator "); | 1876 | tomoyo_set_string(head, "aggregator "); |
1834 | tomoyo_set_string(head, | 1877 | tomoyo_set_string(head, |
@@ -1858,6 +1901,7 @@ static void tomoyo_read_exception(struct tomoyo_io_buffer *head) | |||
1858 | { | 1901 | { |
1859 | struct tomoyo_policy_namespace *ns = | 1902 | struct tomoyo_policy_namespace *ns = |
1860 | container_of(head->r.ns, typeof(*ns), namespace_list); | 1903 | container_of(head->r.ns, typeof(*ns), namespace_list); |
1904 | |||
1861 | if (head->r.eof) | 1905 | if (head->r.eof) |
1862 | return; | 1906 | return; |
1863 | while (head->r.step < TOMOYO_MAX_POLICY && | 1907 | while (head->r.step < TOMOYO_MAX_POLICY && |
@@ -1921,6 +1965,7 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); | |||
1921 | static int tomoyo_truncate(char *str) | 1965 | static int tomoyo_truncate(char *str) |
1922 | { | 1966 | { |
1923 | char *start = str; | 1967 | char *start = str; |
1968 | |||
1924 | while (*(unsigned char *) str > (unsigned char) ' ') | 1969 | while (*(unsigned char *) str > (unsigned char) ' ') |
1925 | str++; | 1970 | str++; |
1926 | *str = '\0'; | 1971 | *str = '\0'; |
@@ -1943,6 +1988,7 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) | |||
1943 | char *symlink = NULL; | 1988 | char *symlink = NULL; |
1944 | char *cp = strchr(header, '\n'); | 1989 | char *cp = strchr(header, '\n'); |
1945 | int len; | 1990 | int len; |
1991 | |||
1946 | if (!cp) | 1992 | if (!cp) |
1947 | return; | 1993 | return; |
1948 | cp = strchr(cp + 1, '\n'); | 1994 | cp = strchr(cp + 1, '\n'); |
@@ -2002,6 +2048,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) | |||
2002 | static unsigned int tomoyo_serial; | 2048 | static unsigned int tomoyo_serial; |
2003 | struct tomoyo_query entry = { }; | 2049 | struct tomoyo_query entry = { }; |
2004 | bool quota_exceeded = false; | 2050 | bool quota_exceeded = false; |
2051 | |||
2005 | va_start(args, fmt); | 2052 | va_start(args, fmt); |
2006 | len = vsnprintf((char *) &len, 1, fmt, args) + 1; | 2053 | len = vsnprintf((char *) &len, 1, fmt, args) + 1; |
2007 | va_end(args); | 2054 | va_end(args); |
@@ -2063,8 +2110,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) | |||
2063 | (tomoyo_answer_wait, entry.answer || | 2110 | (tomoyo_answer_wait, entry.answer || |
2064 | !atomic_read(&tomoyo_query_observers), HZ)) | 2111 | !atomic_read(&tomoyo_query_observers), HZ)) |
2065 | break; | 2112 | break; |
2066 | else | 2113 | entry.timer++; |
2067 | entry.timer++; | ||
2068 | } | 2114 | } |
2069 | spin_lock(&tomoyo_query_list_lock); | 2115 | spin_lock(&tomoyo_query_list_lock); |
2070 | list_del(&entry.list); | 2116 | list_del(&entry.list); |
@@ -2100,6 +2146,7 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid | |||
2100 | { | 2146 | { |
2101 | struct tomoyo_query *ptr; | 2147 | struct tomoyo_query *ptr; |
2102 | struct tomoyo_domain_info *domain = NULL; | 2148 | struct tomoyo_domain_info *domain = NULL; |
2149 | |||
2103 | spin_lock(&tomoyo_query_list_lock); | 2150 | spin_lock(&tomoyo_query_list_lock); |
2104 | list_for_each_entry(ptr, &tomoyo_query_list, list) { | 2151 | list_for_each_entry(ptr, &tomoyo_query_list, list) { |
2105 | if (ptr->serial != serial) | 2152 | if (ptr->serial != serial) |
@@ -2142,15 +2189,15 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head) | |||
2142 | unsigned int pos = 0; | 2189 | unsigned int pos = 0; |
2143 | size_t len = 0; | 2190 | size_t len = 0; |
2144 | char *buf; | 2191 | char *buf; |
2192 | |||
2145 | if (head->r.w_pos) | 2193 | if (head->r.w_pos) |
2146 | return; | 2194 | return; |
2147 | if (head->read_buf) { | 2195 | kfree(head->read_buf); |
2148 | kfree(head->read_buf); | 2196 | head->read_buf = NULL; |
2149 | head->read_buf = NULL; | ||
2150 | } | ||
2151 | spin_lock(&tomoyo_query_list_lock); | 2197 | spin_lock(&tomoyo_query_list_lock); |
2152 | list_for_each(tmp, &tomoyo_query_list) { | 2198 | list_for_each(tmp, &tomoyo_query_list) { |
2153 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2199 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2200 | |||
2154 | if (pos++ != head->r.query_index) | 2201 | if (pos++ != head->r.query_index) |
2155 | continue; | 2202 | continue; |
2156 | len = ptr->query_len; | 2203 | len = ptr->query_len; |
@@ -2168,6 +2215,7 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head) | |||
2168 | spin_lock(&tomoyo_query_list_lock); | 2215 | spin_lock(&tomoyo_query_list_lock); |
2169 | list_for_each(tmp, &tomoyo_query_list) { | 2216 | list_for_each(tmp, &tomoyo_query_list) { |
2170 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2217 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2218 | |||
2171 | if (pos++ != head->r.query_index) | 2219 | if (pos++ != head->r.query_index) |
2172 | continue; | 2220 | continue; |
2173 | /* | 2221 | /* |
@@ -2202,9 +2250,11 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head) | |||
2202 | struct list_head *tmp; | 2250 | struct list_head *tmp; |
2203 | unsigned int serial; | 2251 | unsigned int serial; |
2204 | unsigned int answer; | 2252 | unsigned int answer; |
2253 | |||
2205 | spin_lock(&tomoyo_query_list_lock); | 2254 | spin_lock(&tomoyo_query_list_lock); |
2206 | list_for_each(tmp, &tomoyo_query_list) { | 2255 | list_for_each(tmp, &tomoyo_query_list) { |
2207 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2256 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2257 | |||
2208 | ptr->timer = 0; | 2258 | ptr->timer = 0; |
2209 | } | 2259 | } |
2210 | spin_unlock(&tomoyo_query_list_lock); | 2260 | spin_unlock(&tomoyo_query_list_lock); |
@@ -2213,6 +2263,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head) | |||
2213 | spin_lock(&tomoyo_query_list_lock); | 2263 | spin_lock(&tomoyo_query_list_lock); |
2214 | list_for_each(tmp, &tomoyo_query_list) { | 2264 | list_for_each(tmp, &tomoyo_query_list) { |
2215 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2265 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2266 | |||
2216 | if (ptr->serial != serial) | 2267 | if (ptr->serial != serial) |
2217 | continue; | 2268 | continue; |
2218 | ptr->answer = answer; | 2269 | ptr->answer = answer; |
@@ -2287,6 +2338,7 @@ static void tomoyo_read_stat(struct tomoyo_io_buffer *head) | |||
2287 | { | 2338 | { |
2288 | u8 i; | 2339 | u8 i; |
2289 | unsigned int total = 0; | 2340 | unsigned int total = 0; |
2341 | |||
2290 | if (head->r.eof) | 2342 | if (head->r.eof) |
2291 | return; | 2343 | return; |
2292 | for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) { | 2344 | for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) { |
@@ -2295,9 +2347,9 @@ static void tomoyo_read_stat(struct tomoyo_io_buffer *head) | |||
2295 | tomoyo_stat_updated[i]); | 2347 | tomoyo_stat_updated[i]); |
2296 | if (tomoyo_stat_modified[i]) { | 2348 | if (tomoyo_stat_modified[i]) { |
2297 | struct tomoyo_time stamp; | 2349 | struct tomoyo_time stamp; |
2350 | |||
2298 | tomoyo_convert_time(tomoyo_stat_modified[i], &stamp); | 2351 | tomoyo_convert_time(tomoyo_stat_modified[i], &stamp); |
2299 | tomoyo_io_printf(head, " (Last: %04u/%02u/%02u " | 2352 | tomoyo_io_printf(head, " (Last: %04u/%02u/%02u %02u:%02u:%02u)", |
2300 | "%02u:%02u:%02u)", | ||
2301 | stamp.year, stamp.month, stamp.day, | 2353 | stamp.year, stamp.month, stamp.day, |
2302 | stamp.hour, stamp.min, stamp.sec); | 2354 | stamp.hour, stamp.min, stamp.sec); |
2303 | } | 2355 | } |
@@ -2305,6 +2357,7 @@ static void tomoyo_read_stat(struct tomoyo_io_buffer *head) | |||
2305 | } | 2357 | } |
2306 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) { | 2358 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) { |
2307 | unsigned int used = tomoyo_memory_used[i]; | 2359 | unsigned int used = tomoyo_memory_used[i]; |
2360 | |||
2308 | total += used; | 2361 | total += used; |
2309 | tomoyo_io_printf(head, "Memory used by %-22s %10u", | 2362 | tomoyo_io_printf(head, "Memory used by %-22s %10u", |
2310 | tomoyo_memory_headers[i], used); | 2363 | tomoyo_memory_headers[i], used); |
@@ -2329,6 +2382,7 @@ static int tomoyo_write_stat(struct tomoyo_io_buffer *head) | |||
2329 | { | 2382 | { |
2330 | char *data = head->write_buf; | 2383 | char *data = head->write_buf; |
2331 | u8 i; | 2384 | u8 i; |
2385 | |||
2332 | if (tomoyo_str_starts(&data, "Memory used by ")) | 2386 | if (tomoyo_str_starts(&data, "Memory used by ")) |
2333 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) | 2387 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) |
2334 | if (tomoyo_str_starts(&data, tomoyo_memory_headers[i])) | 2388 | if (tomoyo_str_starts(&data, tomoyo_memory_headers[i])) |
@@ -2457,6 +2511,7 @@ int tomoyo_open_control(const u8 type, struct file *file) | |||
2457 | __poll_t tomoyo_poll_control(struct file *file, poll_table *wait) | 2511 | __poll_t tomoyo_poll_control(struct file *file, poll_table *wait) |
2458 | { | 2512 | { |
2459 | struct tomoyo_io_buffer *head = file->private_data; | 2513 | struct tomoyo_io_buffer *head = file->private_data; |
2514 | |||
2460 | if (head->poll) | 2515 | if (head->poll) |
2461 | return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM; | 2516 | return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM; |
2462 | return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM; | 2517 | return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM; |
@@ -2472,6 +2527,7 @@ __poll_t tomoyo_poll_control(struct file *file, poll_table *wait) | |||
2472 | static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head) | 2527 | static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head) |
2473 | { | 2528 | { |
2474 | struct list_head *ns; | 2529 | struct list_head *ns; |
2530 | |||
2475 | if (head->type != TOMOYO_EXCEPTIONPOLICY && | 2531 | if (head->type != TOMOYO_EXCEPTIONPOLICY && |
2476 | head->type != TOMOYO_PROFILE) | 2532 | head->type != TOMOYO_PROFILE) |
2477 | return; | 2533 | return; |
@@ -2517,7 +2573,7 @@ ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, | |||
2517 | int idx; | 2573 | int idx; |
2518 | 2574 | ||
2519 | if (!head->read) | 2575 | if (!head->read) |
2520 | return -ENOSYS; | 2576 | return -EINVAL; |
2521 | if (mutex_lock_interruptible(&head->io_sem)) | 2577 | if (mutex_lock_interruptible(&head->io_sem)) |
2522 | return -EINTR; | 2578 | return -EINTR; |
2523 | head->read_user_buf = buffer; | 2579 | head->read_user_buf = buffer; |
@@ -2557,6 +2613,7 @@ static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line) | |||
2557 | head->type == TOMOYO_PROFILE) { | 2613 | head->type == TOMOYO_PROFILE) { |
2558 | if (*line == '<') { | 2614 | if (*line == '<') { |
2559 | char *cp = strchr(line, ' '); | 2615 | char *cp = strchr(line, ' '); |
2616 | |||
2560 | if (cp) { | 2617 | if (cp) { |
2561 | *cp++ = '\0'; | 2618 | *cp++ = '\0'; |
2562 | head->w.ns = tomoyo_assign_namespace(line); | 2619 | head->w.ns = tomoyo_assign_namespace(line); |
@@ -2589,8 +2646,9 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, | |||
2589 | size_t avail_len = buffer_len; | 2646 | size_t avail_len = buffer_len; |
2590 | char *cp0 = head->write_buf; | 2647 | char *cp0 = head->write_buf; |
2591 | int idx; | 2648 | int idx; |
2649 | |||
2592 | if (!head->write) | 2650 | if (!head->write) |
2593 | return -ENOSYS; | 2651 | return -EINVAL; |
2594 | if (!access_ok(buffer, buffer_len)) | 2652 | if (!access_ok(buffer, buffer_len)) |
2595 | return -EFAULT; | 2653 | return -EFAULT; |
2596 | if (mutex_lock_interruptible(&head->io_sem)) | 2654 | if (mutex_lock_interruptible(&head->io_sem)) |
@@ -2600,9 +2658,11 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, | |||
2600 | /* Read a line and dispatch it to the policy handler. */ | 2658 | /* Read a line and dispatch it to the policy handler. */ |
2601 | while (avail_len > 0) { | 2659 | while (avail_len > 0) { |
2602 | char c; | 2660 | char c; |
2661 | |||
2603 | if (head->w.avail >= head->writebuf_size - 1) { | 2662 | if (head->w.avail >= head->writebuf_size - 1) { |
2604 | const int len = head->writebuf_size * 2; | 2663 | const int len = head->writebuf_size * 2; |
2605 | char *cp = kzalloc(len, GFP_NOFS); | 2664 | char *cp = kzalloc(len, GFP_NOFS); |
2665 | |||
2606 | if (!cp) { | 2666 | if (!cp) { |
2607 | error = -ENOMEM; | 2667 | error = -ENOMEM; |
2608 | break; | 2668 | break; |
@@ -2701,30 +2761,27 @@ void tomoyo_check_profile(void) | |||
2701 | { | 2761 | { |
2702 | struct tomoyo_domain_info *domain; | 2762 | struct tomoyo_domain_info *domain; |
2703 | const int idx = tomoyo_read_lock(); | 2763 | const int idx = tomoyo_read_lock(); |
2764 | |||
2704 | tomoyo_policy_loaded = true; | 2765 | tomoyo_policy_loaded = true; |
2705 | printk(KERN_INFO "TOMOYO: 2.5.0\n"); | 2766 | pr_info("TOMOYO: 2.5.0\n"); |
2706 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 2767 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
2707 | const u8 profile = domain->profile; | 2768 | const u8 profile = domain->profile; |
2708 | const struct tomoyo_policy_namespace *ns = domain->ns; | 2769 | const struct tomoyo_policy_namespace *ns = domain->ns; |
2770 | |||
2709 | if (ns->profile_version != 20110903) | 2771 | if (ns->profile_version != 20110903) |
2710 | printk(KERN_ERR | 2772 | pr_err("Profile version %u is not supported.\n", |
2711 | "Profile version %u is not supported.\n", | ||
2712 | ns->profile_version); | 2773 | ns->profile_version); |
2713 | else if (!ns->profile_ptr[profile]) | 2774 | else if (!ns->profile_ptr[profile]) |
2714 | printk(KERN_ERR | 2775 | pr_err("Profile %u (used by '%s') is not defined.\n", |
2715 | "Profile %u (used by '%s') is not defined.\n", | ||
2716 | profile, domain->domainname->name); | 2776 | profile, domain->domainname->name); |
2717 | else | 2777 | else |
2718 | continue; | 2778 | continue; |
2719 | printk(KERN_ERR | 2779 | pr_err("Userland tools for TOMOYO 2.5 must be installed and policy must be initialized.\n"); |
2720 | "Userland tools for TOMOYO 2.5 must be installed and " | 2780 | pr_err("Please see http://tomoyo.sourceforge.jp/2.5/ for more information.\n"); |
2721 | "policy must be initialized.\n"); | ||
2722 | printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.5/ " | ||
2723 | "for more information.\n"); | ||
2724 | panic("STOP!"); | 2781 | panic("STOP!"); |
2725 | } | 2782 | } |
2726 | tomoyo_read_unlock(idx); | 2783 | tomoyo_read_unlock(idx); |
2727 | printk(KERN_INFO "Mandatory Access Control activated.\n"); | 2784 | pr_info("Mandatory Access Control activated.\n"); |
2728 | } | 2785 | } |
2729 | 2786 | ||
2730 | /** | 2787 | /** |
@@ -2743,9 +2800,11 @@ void __init tomoyo_load_builtin_policy(void) | |||
2743 | #include "builtin-policy.h" | 2800 | #include "builtin-policy.h" |
2744 | u8 i; | 2801 | u8 i; |
2745 | const int idx = tomoyo_read_lock(); | 2802 | const int idx = tomoyo_read_lock(); |
2803 | |||
2746 | for (i = 0; i < 5; i++) { | 2804 | for (i = 0; i < 5; i++) { |
2747 | struct tomoyo_io_buffer head = { }; | 2805 | struct tomoyo_io_buffer head = { }; |
2748 | char *start = ""; | 2806 | char *start = ""; |
2807 | |||
2749 | switch (i) { | 2808 | switch (i) { |
2750 | case 0: | 2809 | case 0: |
2751 | start = tomoyo_builtin_profile; | 2810 | start = tomoyo_builtin_profile; |
@@ -2775,6 +2834,7 @@ void __init tomoyo_load_builtin_policy(void) | |||
2775 | } | 2834 | } |
2776 | while (1) { | 2835 | while (1) { |
2777 | char *end = strchr(start, '\n'); | 2836 | char *end = strchr(start, '\n'); |
2837 | |||
2778 | if (!end) | 2838 | if (!end) |
2779 | break; | 2839 | break; |
2780 | *end = '\0'; | 2840 | *end = '\0'; |