| .. | .. |
|---|
| 197 | 197 | { |
|---|
| 198 | 198 | va_list args; |
|---|
| 199 | 199 | const int pos = strlen(buffer); |
|---|
| 200 | + |
|---|
| 200 | 201 | va_start(args, fmt); |
|---|
| 201 | 202 | vsnprintf(buffer + pos, len - pos - 1, fmt, args); |
|---|
| 202 | 203 | va_end(args); |
|---|
| .. | .. |
|---|
| 214 | 215 | while (head->r.w_pos) { |
|---|
| 215 | 216 | const char *w = head->r.w[0]; |
|---|
| 216 | 217 | size_t len = strlen(w); |
|---|
| 218 | + |
|---|
| 217 | 219 | if (len) { |
|---|
| 218 | 220 | if (len > head->read_user_buf_avail) |
|---|
| 219 | 221 | len = head->read_user_buf_avail; |
|---|
| .. | .. |
|---|
| 279 | 281 | size_t len; |
|---|
| 280 | 282 | size_t pos = head->r.avail; |
|---|
| 281 | 283 | int size = head->readbuf_size - pos; |
|---|
| 284 | + |
|---|
| 282 | 285 | if (size <= 0) |
|---|
| 283 | 286 | return; |
|---|
| 284 | 287 | va_start(args, fmt); |
|---|
| .. | .. |
|---|
| 344 | 347 | void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) |
|---|
| 345 | 348 | { |
|---|
| 346 | 349 | unsigned int idx; |
|---|
| 350 | + |
|---|
| 347 | 351 | for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) |
|---|
| 348 | 352 | INIT_LIST_HEAD(&ns->acl_group[idx]); |
|---|
| 349 | 353 | for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++) |
|---|
| 350 | 354 | INIT_LIST_HEAD(&ns->group_list[idx]); |
|---|
| 351 | 355 | for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) |
|---|
| 352 | 356 | INIT_LIST_HEAD(&ns->policy_list[idx]); |
|---|
| 353 | | - ns->profile_version = 20110903; |
|---|
| 357 | + ns->profile_version = 20150505; |
|---|
| 354 | 358 | tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); |
|---|
| 355 | 359 | list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); |
|---|
| 356 | 360 | } |
|---|
| .. | .. |
|---|
| 433 | 437 | u8 min_type = ptr->value_type[0]; |
|---|
| 434 | 438 | const u8 max_type = ptr->value_type[1]; |
|---|
| 435 | 439 | char buffer[128]; |
|---|
| 440 | + |
|---|
| 436 | 441 | buffer[0] = '\0'; |
|---|
| 437 | 442 | for (i = 0; i < 2; i++) { |
|---|
| 438 | 443 | switch (min_type) { |
|---|
| .. | .. |
|---|
| 487 | 492 | { |
|---|
| 488 | 493 | struct tomoyo_profile *ptr; |
|---|
| 489 | 494 | struct tomoyo_profile *entry; |
|---|
| 495 | + |
|---|
| 490 | 496 | if (profile >= TOMOYO_MAX_PROFILES) |
|---|
| 491 | 497 | return NULL; |
|---|
| 492 | 498 | ptr = ns->profile_ptr[profile]; |
|---|
| .. | .. |
|---|
| 530 | 536 | { |
|---|
| 531 | 537 | static struct tomoyo_profile tomoyo_null_profile; |
|---|
| 532 | 538 | struct tomoyo_profile *ptr = ns->profile_ptr[profile]; |
|---|
| 539 | + |
|---|
| 533 | 540 | if (!ptr) |
|---|
| 534 | 541 | ptr = &tomoyo_null_profile; |
|---|
| 535 | 542 | return ptr; |
|---|
| .. | .. |
|---|
| 546 | 553 | static s8 tomoyo_find_yesno(const char *string, const char *find) |
|---|
| 547 | 554 | { |
|---|
| 548 | 555 | const char *cp = strstr(string, find); |
|---|
| 556 | + |
|---|
| 549 | 557 | if (cp) { |
|---|
| 550 | 558 | cp += strlen(find); |
|---|
| 551 | 559 | if (!strncmp(cp, "=yes", 4)) |
|---|
| .. | .. |
|---|
| 569 | 577 | const char *find) |
|---|
| 570 | 578 | { |
|---|
| 571 | 579 | const char *cp = strstr(string, find); |
|---|
| 580 | + |
|---|
| 572 | 581 | if (cp) |
|---|
| 573 | 582 | sscanf(cp + strlen(find), "=%u", i); |
|---|
| 574 | 583 | } |
|---|
| .. | .. |
|---|
| 587 | 596 | { |
|---|
| 588 | 597 | u8 i; |
|---|
| 589 | 598 | u8 config; |
|---|
| 599 | + |
|---|
| 590 | 600 | if (!strcmp(name, "CONFIG")) { |
|---|
| 591 | 601 | i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; |
|---|
| 592 | 602 | config = profile->default_config; |
|---|
| .. | .. |
|---|
| 595 | 605 | for (i = 0; i < TOMOYO_MAX_MAC_INDEX |
|---|
| 596 | 606 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { |
|---|
| 597 | 607 | int len = 0; |
|---|
| 608 | + |
|---|
| 598 | 609 | if (i < TOMOYO_MAX_MAC_INDEX) { |
|---|
| 599 | 610 | const u8 c = tomoyo_index2category[i]; |
|---|
| 600 | 611 | const char *category = |
|---|
| 601 | 612 | tomoyo_category_keywords[c]; |
|---|
| 613 | + |
|---|
| 602 | 614 | len = strlen(category); |
|---|
| 603 | 615 | if (strncmp(name, category, len) || |
|---|
| 604 | 616 | name[len++] != ':' || name[len++] != ':') |
|---|
| .. | .. |
|---|
| 618 | 630 | config = TOMOYO_CONFIG_USE_DEFAULT; |
|---|
| 619 | 631 | } else { |
|---|
| 620 | 632 | u8 mode; |
|---|
| 633 | + |
|---|
| 621 | 634 | for (mode = 0; mode < 4; mode++) |
|---|
| 622 | 635 | if (strstr(value, tomoyo_mode[mode])) |
|---|
| 623 | 636 | /* |
|---|
| .. | .. |
|---|
| 664 | 677 | unsigned int i; |
|---|
| 665 | 678 | char *cp; |
|---|
| 666 | 679 | struct tomoyo_profile *profile; |
|---|
| 680 | + |
|---|
| 667 | 681 | if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) |
|---|
| 668 | 682 | == 1) |
|---|
| 669 | 683 | return 0; |
|---|
| .. | .. |
|---|
| 683 | 697 | const struct tomoyo_path_info *new_comment |
|---|
| 684 | 698 | = tomoyo_get_name(cp); |
|---|
| 685 | 699 | const struct tomoyo_path_info *old_comment; |
|---|
| 700 | + |
|---|
| 686 | 701 | if (!new_comment) |
|---|
| 687 | 702 | return -ENOMEM; |
|---|
| 688 | 703 | spin_lock(&lock); |
|---|
| .. | .. |
|---|
| 732 | 747 | struct tomoyo_policy_namespace *ns = |
|---|
| 733 | 748 | container_of(head->r.ns, typeof(*ns), namespace_list); |
|---|
| 734 | 749 | const struct tomoyo_profile *profile; |
|---|
| 750 | + |
|---|
| 735 | 751 | if (head->r.eof) |
|---|
| 736 | 752 | return; |
|---|
| 737 | 753 | next: |
|---|
| .. | .. |
|---|
| 760 | 776 | u8 i; |
|---|
| 761 | 777 | const struct tomoyo_path_info *comment = |
|---|
| 762 | 778 | profile->comment; |
|---|
| 779 | + |
|---|
| 763 | 780 | tomoyo_print_namespace(head); |
|---|
| 764 | 781 | tomoyo_io_printf(head, "%u-COMMENT=", index); |
|---|
| 765 | 782 | tomoyo_set_string(head, comment ? comment->name : ""); |
|---|
| .. | .. |
|---|
| 788 | 805 | + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { |
|---|
| 789 | 806 | const u8 i = head->r.bit; |
|---|
| 790 | 807 | const u8 config = profile->config[i]; |
|---|
| 808 | + |
|---|
| 791 | 809 | if (config == TOMOYO_CONFIG_USE_DEFAULT) |
|---|
| 792 | 810 | continue; |
|---|
| 793 | 811 | tomoyo_print_namespace(head); |
|---|
| .. | .. |
|---|
| 847 | 865 | struct tomoyo_acl_param param = { |
|---|
| 848 | 866 | /* .ns = &tomoyo_kernel_namespace, */ |
|---|
| 849 | 867 | .is_delete = is_delete, |
|---|
| 850 | | - .list = &tomoyo_kernel_namespace. |
|---|
| 851 | | - policy_list[TOMOYO_ID_MANAGER], |
|---|
| 868 | + .list = &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], |
|---|
| 852 | 869 | }; |
|---|
| 853 | 870 | int error = is_delete ? -ENOENT : -ENOMEM; |
|---|
| 871 | + |
|---|
| 854 | 872 | if (!tomoyo_correct_domain(manager) && |
|---|
| 855 | 873 | !tomoyo_correct_word(manager)) |
|---|
| 856 | 874 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 894 | 912 | { |
|---|
| 895 | 913 | if (head->r.eof) |
|---|
| 896 | 914 | return; |
|---|
| 897 | | - list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace. |
|---|
| 898 | | - policy_list[TOMOYO_ID_MANAGER]) { |
|---|
| 915 | + list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER]) { |
|---|
| 899 | 916 | struct tomoyo_manager *ptr = |
|---|
| 900 | 917 | list_entry(head->r.acl, typeof(*ptr), head.list); |
|---|
| 918 | + |
|---|
| 901 | 919 | if (ptr->head.is_deleted) |
|---|
| 902 | 920 | continue; |
|---|
| 903 | 921 | if (!tomoyo_flush(head)) |
|---|
| .. | .. |
|---|
| 922 | 940 | const char *exe; |
|---|
| 923 | 941 | const struct task_struct *task = current; |
|---|
| 924 | 942 | const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; |
|---|
| 925 | | - bool found = false; |
|---|
| 943 | + bool found = IS_ENABLED(CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING); |
|---|
| 926 | 944 | |
|---|
| 927 | 945 | if (!tomoyo_policy_loaded) |
|---|
| 928 | 946 | return true; |
|---|
| .. | .. |
|---|
| 933 | 951 | exe = tomoyo_get_exe(); |
|---|
| 934 | 952 | if (!exe) |
|---|
| 935 | 953 | return false; |
|---|
| 936 | | - list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. |
|---|
| 937 | | - policy_list[TOMOYO_ID_MANAGER], head.list) { |
|---|
| 954 | + list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list, |
|---|
| 955 | + srcu_read_lock_held(&tomoyo_ss)) { |
|---|
| 938 | 956 | if (!ptr->head.is_deleted && |
|---|
| 939 | 957 | (!tomoyo_pathcmp(domainname, ptr->manager) || |
|---|
| 940 | 958 | !strcmp(exe, ptr->manager->name))) { |
|---|
| .. | .. |
|---|
| 945 | 963 | if (!found) { /* Reduce error messages. */ |
|---|
| 946 | 964 | static pid_t last_pid; |
|---|
| 947 | 965 | const pid_t pid = current->pid; |
|---|
| 966 | + |
|---|
| 948 | 967 | if (last_pid != pid) { |
|---|
| 949 | | - printk(KERN_WARNING "%s ( %s ) is not permitted to " |
|---|
| 950 | | - "update policies.\n", domainname->name, exe); |
|---|
| 968 | + pr_warn("%s ( %s ) is not permitted to update policies.\n", |
|---|
| 969 | + domainname->name, exe); |
|---|
| 951 | 970 | last_pid = pid; |
|---|
| 952 | 971 | } |
|---|
| 953 | 972 | } |
|---|
| .. | .. |
|---|
| 974 | 993 | unsigned int pid; |
|---|
| 975 | 994 | struct tomoyo_domain_info *domain = NULL; |
|---|
| 976 | 995 | bool global_pid = false; |
|---|
| 996 | + |
|---|
| 977 | 997 | if (strncmp(data, "select ", 7)) |
|---|
| 978 | 998 | return false; |
|---|
| 979 | 999 | data += 7; |
|---|
| 980 | 1000 | if (sscanf(data, "pid=%u", &pid) == 1 || |
|---|
| 981 | 1001 | (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { |
|---|
| 982 | 1002 | struct task_struct *p; |
|---|
| 1003 | + |
|---|
| 983 | 1004 | rcu_read_lock(); |
|---|
| 984 | 1005 | if (global_pid) |
|---|
| 985 | 1006 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
|---|
| 986 | 1007 | else |
|---|
| 987 | 1008 | p = find_task_by_vpid(pid); |
|---|
| 988 | 1009 | if (p) |
|---|
| 989 | | - domain = tomoyo_real_domain(p); |
|---|
| 1010 | + domain = tomoyo_task(p)->domain_info; |
|---|
| 990 | 1011 | rcu_read_unlock(); |
|---|
| 991 | 1012 | } else if (!strncmp(data, "domain=", 7)) { |
|---|
| 992 | 1013 | if (tomoyo_domain_def(data + 7)) |
|---|
| .. | .. |
|---|
| 1004 | 1025 | if (domain) |
|---|
| 1005 | 1026 | head->r.domain = &domain->list; |
|---|
| 1006 | 1027 | else |
|---|
| 1007 | | - head->r.eof = 1; |
|---|
| 1028 | + head->r.eof = true; |
|---|
| 1008 | 1029 | tomoyo_io_printf(head, "# select %s\n", data); |
|---|
| 1009 | 1030 | if (domain && domain->is_deleted) |
|---|
| 1010 | 1031 | tomoyo_io_printf(head, "# This is a deleted domain.\n"); |
|---|
| .. | .. |
|---|
| 1020 | 1041 | * Returns true if @a == @b, false otherwise. |
|---|
| 1021 | 1042 | */ |
|---|
| 1022 | 1043 | static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, |
|---|
| 1023 | | - const struct tomoyo_acl_info *b) |
|---|
| 1044 | + const struct tomoyo_acl_info *b) |
|---|
| 1024 | 1045 | { |
|---|
| 1025 | 1046 | const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); |
|---|
| 1026 | 1047 | const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); |
|---|
| 1048 | + |
|---|
| 1027 | 1049 | return p1->domainname == p2->domainname; |
|---|
| 1028 | 1050 | } |
|---|
| 1029 | 1051 | |
|---|
| .. | .. |
|---|
| 1039 | 1061 | static int tomoyo_write_task(struct tomoyo_acl_param *param) |
|---|
| 1040 | 1062 | { |
|---|
| 1041 | 1063 | int error = -EINVAL; |
|---|
| 1064 | + |
|---|
| 1042 | 1065 | if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { |
|---|
| 1043 | 1066 | struct tomoyo_task_acl e = { |
|---|
| 1044 | 1067 | .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, |
|---|
| 1045 | 1068 | .domainname = tomoyo_get_domainname(param), |
|---|
| 1046 | 1069 | }; |
|---|
| 1070 | + |
|---|
| 1047 | 1071 | if (e.domainname) |
|---|
| 1048 | 1072 | error = tomoyo_update_domain(&e.head, sizeof(e), param, |
|---|
| 1049 | 1073 | tomoyo_same_task_acl, |
|---|
| .. | .. |
|---|
| 1072 | 1096 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
|---|
| 1073 | 1097 | return -EINTR; |
|---|
| 1074 | 1098 | /* Is there an active domain? */ |
|---|
| 1075 | | - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
|---|
| 1099 | + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, |
|---|
| 1100 | + srcu_read_lock_held(&tomoyo_ss)) { |
|---|
| 1076 | 1101 | /* Never delete tomoyo_kernel_domain */ |
|---|
| 1077 | 1102 | if (domain == &tomoyo_kernel_domain) |
|---|
| 1078 | 1103 | continue; |
|---|
| .. | .. |
|---|
| 1110 | 1135 | }; |
|---|
| 1111 | 1136 | static const struct { |
|---|
| 1112 | 1137 | const char *keyword; |
|---|
| 1113 | | - int (*write) (struct tomoyo_acl_param *); |
|---|
| 1138 | + int (*write)(struct tomoyo_acl_param *param); |
|---|
| 1114 | 1139 | } tomoyo_callback[5] = { |
|---|
| 1115 | 1140 | { "file ", tomoyo_write_file }, |
|---|
| 1116 | 1141 | { "network inet ", tomoyo_write_inet_network }, |
|---|
| .. | .. |
|---|
| 1151 | 1176 | struct tomoyo_domain_info *domain = head->w.domain; |
|---|
| 1152 | 1177 | const bool is_delete = head->w.is_delete; |
|---|
| 1153 | 1178 | bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); |
|---|
| 1154 | | - unsigned int profile; |
|---|
| 1179 | + unsigned int idx; |
|---|
| 1180 | + |
|---|
| 1155 | 1181 | if (*data == '<') { |
|---|
| 1156 | 1182 | int ret = 0; |
|---|
| 1183 | + |
|---|
| 1157 | 1184 | domain = NULL; |
|---|
| 1158 | 1185 | if (is_delete) |
|---|
| 1159 | 1186 | ret = tomoyo_delete_domain(data); |
|---|
| .. | .. |
|---|
| 1167 | 1194 | if (!domain) |
|---|
| 1168 | 1195 | return -EINVAL; |
|---|
| 1169 | 1196 | ns = domain->ns; |
|---|
| 1170 | | - if (sscanf(data, "use_profile %u", &profile) == 1 |
|---|
| 1171 | | - && profile < TOMOYO_MAX_PROFILES) { |
|---|
| 1172 | | - if (!tomoyo_policy_loaded || ns->profile_ptr[profile]) |
|---|
| 1173 | | - domain->profile = (u8) profile; |
|---|
| 1197 | + if (sscanf(data, "use_profile %u", &idx) == 1 |
|---|
| 1198 | + && idx < TOMOYO_MAX_PROFILES) { |
|---|
| 1199 | + if (!tomoyo_policy_loaded || ns->profile_ptr[idx]) |
|---|
| 1200 | + if (!is_delete) |
|---|
| 1201 | + domain->profile = (u8) idx; |
|---|
| 1174 | 1202 | return 0; |
|---|
| 1175 | 1203 | } |
|---|
| 1176 | | - if (sscanf(data, "use_group %u\n", &profile) == 1 |
|---|
| 1177 | | - && profile < TOMOYO_MAX_ACL_GROUPS) { |
|---|
| 1204 | + if (sscanf(data, "use_group %u\n", &idx) == 1 |
|---|
| 1205 | + && idx < TOMOYO_MAX_ACL_GROUPS) { |
|---|
| 1178 | 1206 | if (!is_delete) |
|---|
| 1179 | | - domain->group = (u8) profile; |
|---|
| 1207 | + set_bit(idx, domain->group); |
|---|
| 1208 | + else |
|---|
| 1209 | + clear_bit(idx, domain->group); |
|---|
| 1180 | 1210 | return 0; |
|---|
| 1181 | 1211 | } |
|---|
| 1182 | | - for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { |
|---|
| 1183 | | - const char *cp = tomoyo_dif[profile]; |
|---|
| 1212 | + for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) { |
|---|
| 1213 | + const char *cp = tomoyo_dif[idx]; |
|---|
| 1214 | + |
|---|
| 1184 | 1215 | if (strncmp(data, cp, strlen(cp) - 1)) |
|---|
| 1185 | 1216 | continue; |
|---|
| 1186 | | - domain->flags[profile] = !is_delete; |
|---|
| 1217 | + domain->flags[idx] = !is_delete; |
|---|
| 1187 | 1218 | return 0; |
|---|
| 1188 | 1219 | } |
|---|
| 1189 | 1220 | return tomoyo_write_domain2(ns, &domain->acl_info_list, data, |
|---|
| .. | .. |
|---|
| 1209 | 1240 | tomoyo_set_space(head); |
|---|
| 1210 | 1241 | tomoyo_set_string(head, cond->transit->name); |
|---|
| 1211 | 1242 | } |
|---|
| 1212 | | - /* fall through */ |
|---|
| 1243 | + fallthrough; |
|---|
| 1213 | 1244 | case 1: |
|---|
| 1214 | 1245 | { |
|---|
| 1215 | 1246 | const u16 condc = cond->condc; |
|---|
| .. | .. |
|---|
| 1225 | 1256 | const struct tomoyo_envp *envp = |
|---|
| 1226 | 1257 | (typeof(envp)) (argv + cond->argc); |
|---|
| 1227 | 1258 | u16 skip; |
|---|
| 1259 | + |
|---|
| 1228 | 1260 | for (skip = 0; skip < head->r.cond_index; skip++) { |
|---|
| 1229 | 1261 | const u8 left = condp->left; |
|---|
| 1230 | 1262 | const u8 right = condp->right; |
|---|
| 1263 | + |
|---|
| 1231 | 1264 | condp++; |
|---|
| 1232 | 1265 | switch (left) { |
|---|
| 1233 | 1266 | case TOMOYO_ARGV_ENTRY: |
|---|
| .. | .. |
|---|
| 1253 | 1286 | const u8 match = condp->equals; |
|---|
| 1254 | 1287 | const u8 left = condp->left; |
|---|
| 1255 | 1288 | const u8 right = condp->right; |
|---|
| 1289 | + |
|---|
| 1256 | 1290 | if (!tomoyo_flush(head)) |
|---|
| 1257 | 1291 | return false; |
|---|
| 1258 | 1292 | condp++; |
|---|
| .. | .. |
|---|
| 1262 | 1296 | case TOMOYO_ARGV_ENTRY: |
|---|
| 1263 | 1297 | tomoyo_io_printf(head, |
|---|
| 1264 | 1298 | "exec.argv[%lu]%s=\"", |
|---|
| 1265 | | - argv->index, argv-> |
|---|
| 1266 | | - is_not ? "!" : ""); |
|---|
| 1299 | + argv->index, argv->is_not ? "!" : ""); |
|---|
| 1267 | 1300 | tomoyo_set_string(head, |
|---|
| 1268 | 1301 | argv->value->name); |
|---|
| 1269 | 1302 | tomoyo_set_string(head, "\""); |
|---|
| .. | .. |
|---|
| 1274 | 1307 | "exec.envp[\""); |
|---|
| 1275 | 1308 | tomoyo_set_string(head, |
|---|
| 1276 | 1309 | envp->name->name); |
|---|
| 1277 | | - tomoyo_io_printf(head, "\"]%s=", envp-> |
|---|
| 1278 | | - is_not ? "!" : ""); |
|---|
| 1310 | + tomoyo_io_printf(head, "\"]%s=", envp->is_not ? "!" : ""); |
|---|
| 1279 | 1311 | if (envp->value) { |
|---|
| 1280 | 1312 | tomoyo_set_string(head, "\""); |
|---|
| 1281 | | - tomoyo_set_string(head, envp-> |
|---|
| 1282 | | - value->name); |
|---|
| 1313 | + tomoyo_set_string(head, envp->value->name); |
|---|
| 1283 | 1314 | tomoyo_set_string(head, "\""); |
|---|
| 1284 | 1315 | } else { |
|---|
| 1285 | 1316 | tomoyo_set_string(head, |
|---|
| .. | .. |
|---|
| 1314 | 1345 | } |
|---|
| 1315 | 1346 | } |
|---|
| 1316 | 1347 | head->r.cond_step++; |
|---|
| 1317 | | - /* fall through */ |
|---|
| 1348 | + fallthrough; |
|---|
| 1318 | 1349 | case 2: |
|---|
| 1319 | 1350 | if (!tomoyo_flush(head)) |
|---|
| 1320 | 1351 | break; |
|---|
| 1321 | 1352 | head->r.cond_step++; |
|---|
| 1322 | | - /* fall through */ |
|---|
| 1353 | + fallthrough; |
|---|
| 1323 | 1354 | case 3: |
|---|
| 1324 | 1355 | if (cond->grant_log != TOMOYO_GRANTLOG_AUTO) |
|---|
| 1325 | 1356 | tomoyo_io_printf(head, " grant_log=%s", |
|---|
| .. | .. |
|---|
| 1375 | 1406 | struct tomoyo_path_acl *ptr = |
|---|
| 1376 | 1407 | container_of(acl, typeof(*ptr), head); |
|---|
| 1377 | 1408 | const u16 perm = ptr->perm; |
|---|
| 1409 | + |
|---|
| 1378 | 1410 | for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { |
|---|
| 1379 | 1411 | if (!(perm & (1 << bit))) |
|---|
| 1380 | 1412 | continue; |
|---|
| .. | .. |
|---|
| 1395 | 1427 | } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { |
|---|
| 1396 | 1428 | struct tomoyo_task_acl *ptr = |
|---|
| 1397 | 1429 | container_of(acl, typeof(*ptr), head); |
|---|
| 1430 | + |
|---|
| 1398 | 1431 | tomoyo_set_group(head, "task "); |
|---|
| 1399 | 1432 | tomoyo_set_string(head, "manual_domain_transition "); |
|---|
| 1400 | 1433 | tomoyo_set_string(head, ptr->domainname->name); |
|---|
| .. | .. |
|---|
| 1404 | 1437 | struct tomoyo_path2_acl *ptr = |
|---|
| 1405 | 1438 | container_of(acl, typeof(*ptr), head); |
|---|
| 1406 | 1439 | const u8 perm = ptr->perm; |
|---|
| 1440 | + |
|---|
| 1407 | 1441 | for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { |
|---|
| 1408 | 1442 | if (!(perm & (1 << bit))) |
|---|
| 1409 | 1443 | continue; |
|---|
| .. | .. |
|---|
| 1424 | 1458 | struct tomoyo_path_number_acl *ptr = |
|---|
| 1425 | 1459 | container_of(acl, typeof(*ptr), head); |
|---|
| 1426 | 1460 | const u8 perm = ptr->perm; |
|---|
| 1461 | + |
|---|
| 1427 | 1462 | for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) { |
|---|
| 1428 | 1463 | if (!(perm & (1 << bit))) |
|---|
| 1429 | 1464 | continue; |
|---|
| .. | .. |
|---|
| 1444 | 1479 | struct tomoyo_mkdev_acl *ptr = |
|---|
| 1445 | 1480 | container_of(acl, typeof(*ptr), head); |
|---|
| 1446 | 1481 | const u8 perm = ptr->perm; |
|---|
| 1482 | + |
|---|
| 1447 | 1483 | for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) { |
|---|
| 1448 | 1484 | if (!(perm & (1 << bit))) |
|---|
| 1449 | 1485 | continue; |
|---|
| .. | .. |
|---|
| 1490 | 1526 | ->name); |
|---|
| 1491 | 1527 | } else { |
|---|
| 1492 | 1528 | char buf[128]; |
|---|
| 1529 | + |
|---|
| 1493 | 1530 | tomoyo_print_ip(buf, sizeof(buf), &ptr->address); |
|---|
| 1494 | 1531 | tomoyo_io_printf(head, "%s", buf); |
|---|
| 1495 | 1532 | } |
|---|
| .. | .. |
|---|
| 1519 | 1556 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { |
|---|
| 1520 | 1557 | struct tomoyo_mount_acl *ptr = |
|---|
| 1521 | 1558 | container_of(acl, typeof(*ptr), head); |
|---|
| 1559 | + |
|---|
| 1522 | 1560 | tomoyo_set_group(head, "file mount"); |
|---|
| 1523 | 1561 | tomoyo_print_name_union(head, &ptr->dev_name); |
|---|
| 1524 | 1562 | tomoyo_print_name_union(head, &ptr->dir_name); |
|---|
| .. | .. |
|---|
| 1562 | 1600 | list_for_each_cookie(head->r.acl, list) { |
|---|
| 1563 | 1601 | struct tomoyo_acl_info *ptr = |
|---|
| 1564 | 1602 | list_entry(head->r.acl, typeof(*ptr), list); |
|---|
| 1603 | + |
|---|
| 1565 | 1604 | if (!tomoyo_print_entry(head, ptr)) |
|---|
| 1566 | 1605 | return false; |
|---|
| 1567 | 1606 | } |
|---|
| .. | .. |
|---|
| 1583 | 1622 | list_for_each_cookie(head->r.domain, &tomoyo_domain_list) { |
|---|
| 1584 | 1623 | struct tomoyo_domain_info *domain = |
|---|
| 1585 | 1624 | list_entry(head->r.domain, typeof(*domain), list); |
|---|
| 1625 | + u8 i; |
|---|
| 1626 | + |
|---|
| 1586 | 1627 | switch (head->r.step) { |
|---|
| 1587 | | - u8 i; |
|---|
| 1588 | 1628 | case 0: |
|---|
| 1589 | 1629 | if (domain->is_deleted && |
|---|
| 1590 | 1630 | !head->r.print_this_domain_only) |
|---|
| .. | .. |
|---|
| 1594 | 1634 | tomoyo_set_lf(head); |
|---|
| 1595 | 1635 | tomoyo_io_printf(head, "use_profile %u\n", |
|---|
| 1596 | 1636 | domain->profile); |
|---|
| 1597 | | - tomoyo_io_printf(head, "use_group %u\n", |
|---|
| 1598 | | - domain->group); |
|---|
| 1599 | 1637 | for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) |
|---|
| 1600 | 1638 | if (domain->flags[i]) |
|---|
| 1601 | 1639 | tomoyo_set_string(head, tomoyo_dif[i]); |
|---|
| 1640 | + head->r.index = 0; |
|---|
| 1641 | + head->r.step++; |
|---|
| 1642 | + fallthrough; |
|---|
| 1643 | + case 1: |
|---|
| 1644 | + while (head->r.index < TOMOYO_MAX_ACL_GROUPS) { |
|---|
| 1645 | + i = head->r.index++; |
|---|
| 1646 | + if (!test_bit(i, domain->group)) |
|---|
| 1647 | + continue; |
|---|
| 1648 | + tomoyo_io_printf(head, "use_group %u\n", i); |
|---|
| 1649 | + if (!tomoyo_flush(head)) |
|---|
| 1650 | + return; |
|---|
| 1651 | + } |
|---|
| 1652 | + head->r.index = 0; |
|---|
| 1602 | 1653 | head->r.step++; |
|---|
| 1603 | 1654 | tomoyo_set_lf(head); |
|---|
| 1604 | | - /* fall through */ |
|---|
| 1605 | | - case 1: |
|---|
| 1655 | + fallthrough; |
|---|
| 1656 | + case 2: |
|---|
| 1606 | 1657 | if (!tomoyo_read_domain2(head, &domain->acl_info_list)) |
|---|
| 1607 | 1658 | return; |
|---|
| 1608 | 1659 | head->r.step++; |
|---|
| 1609 | 1660 | if (!tomoyo_set_lf(head)) |
|---|
| 1610 | 1661 | return; |
|---|
| 1611 | | - /* fall through */ |
|---|
| 1612 | | - case 2: |
|---|
| 1662 | + fallthrough; |
|---|
| 1663 | + case 3: |
|---|
| 1613 | 1664 | head->r.step = 0; |
|---|
| 1614 | 1665 | if (head->r.print_this_domain_only) |
|---|
| 1615 | 1666 | goto done; |
|---|
| .. | .. |
|---|
| 1660 | 1711 | head->r.eof = true; |
|---|
| 1661 | 1712 | if (tomoyo_str_starts(&buf, "global-pid ")) |
|---|
| 1662 | 1713 | global_pid = true; |
|---|
| 1663 | | - pid = (unsigned int) simple_strtoul(buf, NULL, 10); |
|---|
| 1714 | + if (kstrtouint(buf, 10, &pid)) |
|---|
| 1715 | + return; |
|---|
| 1664 | 1716 | rcu_read_lock(); |
|---|
| 1665 | 1717 | if (global_pid) |
|---|
| 1666 | 1718 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
|---|
| 1667 | 1719 | else |
|---|
| 1668 | 1720 | p = find_task_by_vpid(pid); |
|---|
| 1669 | 1721 | if (p) |
|---|
| 1670 | | - domain = tomoyo_real_domain(p); |
|---|
| 1722 | + domain = tomoyo_task(p)->domain_info; |
|---|
| 1671 | 1723 | rcu_read_unlock(); |
|---|
| 1672 | 1724 | if (!domain) |
|---|
| 1673 | 1725 | return; |
|---|
| .. | .. |
|---|
| 1710 | 1762 | .data = head->write_buf, |
|---|
| 1711 | 1763 | }; |
|---|
| 1712 | 1764 | u8 i; |
|---|
| 1765 | + |
|---|
| 1713 | 1766 | if (tomoyo_str_starts(¶m.data, "aggregator ")) |
|---|
| 1714 | 1767 | return tomoyo_write_aggregator(¶m); |
|---|
| 1715 | 1768 | for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) |
|---|
| .. | .. |
|---|
| 1721 | 1774 | if (tomoyo_str_starts(¶m.data, "acl_group ")) { |
|---|
| 1722 | 1775 | unsigned int group; |
|---|
| 1723 | 1776 | char *data; |
|---|
| 1777 | + |
|---|
| 1724 | 1778 | group = simple_strtoul(param.data, &data, 10); |
|---|
| 1725 | 1779 | if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') |
|---|
| 1726 | 1780 | return tomoyo_write_domain2 |
|---|
| .. | .. |
|---|
| 1745 | 1799 | struct tomoyo_policy_namespace *ns = |
|---|
| 1746 | 1800 | container_of(head->r.ns, typeof(*ns), namespace_list); |
|---|
| 1747 | 1801 | struct list_head *list = &ns->group_list[idx]; |
|---|
| 1802 | + |
|---|
| 1748 | 1803 | list_for_each_cookie(head->r.group, list) { |
|---|
| 1749 | 1804 | struct tomoyo_group *group = |
|---|
| 1750 | 1805 | list_entry(head->r.group, typeof(*group), head.list); |
|---|
| 1806 | + |
|---|
| 1751 | 1807 | list_for_each_cookie(head->r.acl, &group->member_list) { |
|---|
| 1752 | 1808 | struct tomoyo_acl_head *ptr = |
|---|
| 1753 | 1809 | list_entry(head->r.acl, typeof(*ptr), list); |
|---|
| 1810 | + |
|---|
| 1754 | 1811 | if (ptr->is_deleted) |
|---|
| 1755 | 1812 | continue; |
|---|
| 1756 | 1813 | if (!tomoyo_flush(head)) |
|---|
| .. | .. |
|---|
| 1770 | 1827 | head)->number); |
|---|
| 1771 | 1828 | } else if (idx == TOMOYO_ADDRESS_GROUP) { |
|---|
| 1772 | 1829 | char buffer[128]; |
|---|
| 1773 | | - |
|---|
| 1774 | 1830 | struct tomoyo_address_group *member = |
|---|
| 1775 | 1831 | container_of(ptr, typeof(*member), |
|---|
| 1776 | 1832 | head); |
|---|
| 1833 | + |
|---|
| 1777 | 1834 | tomoyo_print_ip(buffer, sizeof(buffer), |
|---|
| 1778 | 1835 | &member->address); |
|---|
| 1779 | 1836 | tomoyo_io_printf(head, " %s", buffer); |
|---|
| .. | .. |
|---|
| 1801 | 1858 | struct tomoyo_policy_namespace *ns = |
|---|
| 1802 | 1859 | container_of(head->r.ns, typeof(*ns), namespace_list); |
|---|
| 1803 | 1860 | struct list_head *list = &ns->policy_list[idx]; |
|---|
| 1861 | + |
|---|
| 1804 | 1862 | list_for_each_cookie(head->r.acl, list) { |
|---|
| 1805 | 1863 | struct tomoyo_acl_head *acl = |
|---|
| 1806 | 1864 | container_of(head->r.acl, typeof(*acl), list); |
|---|
| .. | .. |
|---|
| 1813 | 1871 | { |
|---|
| 1814 | 1872 | struct tomoyo_transition_control *ptr = |
|---|
| 1815 | 1873 | container_of(acl, typeof(*ptr), head); |
|---|
| 1874 | + |
|---|
| 1816 | 1875 | tomoyo_print_namespace(head); |
|---|
| 1817 | 1876 | tomoyo_set_string(head, tomoyo_transition_type |
|---|
| 1818 | 1877 | [ptr->type]); |
|---|
| .. | .. |
|---|
| 1828 | 1887 | { |
|---|
| 1829 | 1888 | struct tomoyo_aggregator *ptr = |
|---|
| 1830 | 1889 | container_of(acl, typeof(*ptr), head); |
|---|
| 1890 | + |
|---|
| 1831 | 1891 | tomoyo_print_namespace(head); |
|---|
| 1832 | 1892 | tomoyo_set_string(head, "aggregator "); |
|---|
| 1833 | 1893 | tomoyo_set_string(head, |
|---|
| .. | .. |
|---|
| 1857 | 1917 | { |
|---|
| 1858 | 1918 | struct tomoyo_policy_namespace *ns = |
|---|
| 1859 | 1919 | container_of(head->r.ns, typeof(*ns), namespace_list); |
|---|
| 1920 | + |
|---|
| 1860 | 1921 | if (head->r.eof) |
|---|
| 1861 | 1922 | return; |
|---|
| 1862 | 1923 | while (head->r.step < TOMOYO_MAX_POLICY && |
|---|
| .. | .. |
|---|
| 1920 | 1981 | static int tomoyo_truncate(char *str) |
|---|
| 1921 | 1982 | { |
|---|
| 1922 | 1983 | char *start = str; |
|---|
| 1984 | + |
|---|
| 1923 | 1985 | while (*(unsigned char *) str > (unsigned char) ' ') |
|---|
| 1924 | 1986 | str++; |
|---|
| 1925 | 1987 | *str = '\0'; |
|---|
| .. | .. |
|---|
| 1942 | 2004 | char *symlink = NULL; |
|---|
| 1943 | 2005 | char *cp = strchr(header, '\n'); |
|---|
| 1944 | 2006 | int len; |
|---|
| 2007 | + |
|---|
| 1945 | 2008 | if (!cp) |
|---|
| 1946 | 2009 | return; |
|---|
| 1947 | 2010 | cp = strchr(cp + 1, '\n'); |
|---|
| .. | .. |
|---|
| 2001 | 2064 | static unsigned int tomoyo_serial; |
|---|
| 2002 | 2065 | struct tomoyo_query entry = { }; |
|---|
| 2003 | 2066 | bool quota_exceeded = false; |
|---|
| 2067 | + |
|---|
| 2004 | 2068 | va_start(args, fmt); |
|---|
| 2005 | 2069 | len = vsnprintf((char *) &len, 1, fmt, args) + 1; |
|---|
| 2006 | 2070 | va_end(args); |
|---|
| .. | .. |
|---|
| 2024 | 2088 | /* Check max_learning_entry parameter. */ |
|---|
| 2025 | 2089 | if (tomoyo_domain_quota_is_ok(r)) |
|---|
| 2026 | 2090 | break; |
|---|
| 2027 | | - /* fall through */ |
|---|
| 2091 | + fallthrough; |
|---|
| 2028 | 2092 | default: |
|---|
| 2029 | 2093 | return 0; |
|---|
| 2030 | 2094 | } |
|---|
| .. | .. |
|---|
| 2062 | 2126 | (tomoyo_answer_wait, entry.answer || |
|---|
| 2063 | 2127 | !atomic_read(&tomoyo_query_observers), HZ)) |
|---|
| 2064 | 2128 | break; |
|---|
| 2065 | | - else |
|---|
| 2066 | | - entry.timer++; |
|---|
| 2129 | + entry.timer++; |
|---|
| 2067 | 2130 | } |
|---|
| 2068 | 2131 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2069 | 2132 | list_del(&entry.list); |
|---|
| .. | .. |
|---|
| 2099 | 2162 | { |
|---|
| 2100 | 2163 | struct tomoyo_query *ptr; |
|---|
| 2101 | 2164 | struct tomoyo_domain_info *domain = NULL; |
|---|
| 2165 | + |
|---|
| 2102 | 2166 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2103 | 2167 | list_for_each_entry(ptr, &tomoyo_query_list, list) { |
|---|
| 2104 | 2168 | if (ptr->serial != serial) |
|---|
| .. | .. |
|---|
| 2141 | 2205 | unsigned int pos = 0; |
|---|
| 2142 | 2206 | size_t len = 0; |
|---|
| 2143 | 2207 | char *buf; |
|---|
| 2208 | + |
|---|
| 2144 | 2209 | if (head->r.w_pos) |
|---|
| 2145 | 2210 | return; |
|---|
| 2146 | | - if (head->read_buf) { |
|---|
| 2147 | | - kfree(head->read_buf); |
|---|
| 2148 | | - head->read_buf = NULL; |
|---|
| 2149 | | - } |
|---|
| 2211 | + kfree(head->read_buf); |
|---|
| 2212 | + head->read_buf = NULL; |
|---|
| 2150 | 2213 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2151 | 2214 | list_for_each(tmp, &tomoyo_query_list) { |
|---|
| 2152 | 2215 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
|---|
| 2216 | + |
|---|
| 2153 | 2217 | if (pos++ != head->r.query_index) |
|---|
| 2154 | 2218 | continue; |
|---|
| 2155 | 2219 | len = ptr->query_len; |
|---|
| .. | .. |
|---|
| 2167 | 2231 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2168 | 2232 | list_for_each(tmp, &tomoyo_query_list) { |
|---|
| 2169 | 2233 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
|---|
| 2234 | + |
|---|
| 2170 | 2235 | if (pos++ != head->r.query_index) |
|---|
| 2171 | 2236 | continue; |
|---|
| 2172 | 2237 | /* |
|---|
| .. | .. |
|---|
| 2201 | 2266 | struct list_head *tmp; |
|---|
| 2202 | 2267 | unsigned int serial; |
|---|
| 2203 | 2268 | unsigned int answer; |
|---|
| 2269 | + |
|---|
| 2204 | 2270 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2205 | 2271 | list_for_each(tmp, &tomoyo_query_list) { |
|---|
| 2206 | 2272 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
|---|
| 2273 | + |
|---|
| 2207 | 2274 | ptr->timer = 0; |
|---|
| 2208 | 2275 | } |
|---|
| 2209 | 2276 | spin_unlock(&tomoyo_query_list_lock); |
|---|
| .. | .. |
|---|
| 2212 | 2279 | spin_lock(&tomoyo_query_list_lock); |
|---|
| 2213 | 2280 | list_for_each(tmp, &tomoyo_query_list) { |
|---|
| 2214 | 2281 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
|---|
| 2282 | + |
|---|
| 2215 | 2283 | if (ptr->serial != serial) |
|---|
| 2216 | 2284 | continue; |
|---|
| 2217 | 2285 | ptr->answer = answer; |
|---|
| .. | .. |
|---|
| 2234 | 2302 | static void tomoyo_read_version(struct tomoyo_io_buffer *head) |
|---|
| 2235 | 2303 | { |
|---|
| 2236 | 2304 | if (!head->r.eof) { |
|---|
| 2237 | | - tomoyo_io_printf(head, "2.5.0"); |
|---|
| 2305 | + tomoyo_io_printf(head, "2.6.0"); |
|---|
| 2238 | 2306 | head->r.eof = true; |
|---|
| 2239 | 2307 | } |
|---|
| 2240 | 2308 | } |
|---|
| .. | .. |
|---|
| 2283 | 2351 | { |
|---|
| 2284 | 2352 | u8 i; |
|---|
| 2285 | 2353 | unsigned int total = 0; |
|---|
| 2354 | + |
|---|
| 2286 | 2355 | if (head->r.eof) |
|---|
| 2287 | 2356 | return; |
|---|
| 2288 | 2357 | for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) { |
|---|
| .. | .. |
|---|
| 2291 | 2360 | atomic_read(&tomoyo_stat_updated[i])); |
|---|
| 2292 | 2361 | if (tomoyo_stat_modified[i]) { |
|---|
| 2293 | 2362 | struct tomoyo_time stamp; |
|---|
| 2363 | + |
|---|
| 2294 | 2364 | tomoyo_convert_time(tomoyo_stat_modified[i], &stamp); |
|---|
| 2295 | | - tomoyo_io_printf(head, " (Last: %04u/%02u/%02u " |
|---|
| 2296 | | - "%02u:%02u:%02u)", |
|---|
| 2365 | + tomoyo_io_printf(head, " (Last: %04u/%02u/%02u %02u:%02u:%02u)", |
|---|
| 2297 | 2366 | stamp.year, stamp.month, stamp.day, |
|---|
| 2298 | 2367 | stamp.hour, stamp.min, stamp.sec); |
|---|
| 2299 | 2368 | } |
|---|
| .. | .. |
|---|
| 2301 | 2370 | } |
|---|
| 2302 | 2371 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) { |
|---|
| 2303 | 2372 | unsigned int used = tomoyo_memory_used[i]; |
|---|
| 2373 | + |
|---|
| 2304 | 2374 | total += used; |
|---|
| 2305 | 2375 | tomoyo_io_printf(head, "Memory used by %-22s %10u", |
|---|
| 2306 | 2376 | tomoyo_memory_headers[i], used); |
|---|
| .. | .. |
|---|
| 2325 | 2395 | { |
|---|
| 2326 | 2396 | char *data = head->write_buf; |
|---|
| 2327 | 2397 | u8 i; |
|---|
| 2398 | + |
|---|
| 2328 | 2399 | if (tomoyo_str_starts(&data, "Memory used by ")) |
|---|
| 2329 | 2400 | for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) |
|---|
| 2330 | 2401 | if (tomoyo_str_starts(&data, tomoyo_memory_headers[i])) |
|---|
| .. | .. |
|---|
| 2453 | 2524 | __poll_t tomoyo_poll_control(struct file *file, poll_table *wait) |
|---|
| 2454 | 2525 | { |
|---|
| 2455 | 2526 | struct tomoyo_io_buffer *head = file->private_data; |
|---|
| 2527 | + |
|---|
| 2456 | 2528 | if (head->poll) |
|---|
| 2457 | 2529 | return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM; |
|---|
| 2458 | 2530 | return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM; |
|---|
| .. | .. |
|---|
| 2468 | 2540 | static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head) |
|---|
| 2469 | 2541 | { |
|---|
| 2470 | 2542 | struct list_head *ns; |
|---|
| 2543 | + |
|---|
| 2471 | 2544 | if (head->type != TOMOYO_EXCEPTIONPOLICY && |
|---|
| 2472 | 2545 | head->type != TOMOYO_PROFILE) |
|---|
| 2473 | 2546 | return; |
|---|
| .. | .. |
|---|
| 2513 | 2586 | int idx; |
|---|
| 2514 | 2587 | |
|---|
| 2515 | 2588 | if (!head->read) |
|---|
| 2516 | | - return -ENOSYS; |
|---|
| 2589 | + return -EINVAL; |
|---|
| 2517 | 2590 | if (mutex_lock_interruptible(&head->io_sem)) |
|---|
| 2518 | 2591 | return -EINTR; |
|---|
| 2519 | 2592 | head->read_user_buf = buffer; |
|---|
| .. | .. |
|---|
| 2553 | 2626 | head->type == TOMOYO_PROFILE) { |
|---|
| 2554 | 2627 | if (*line == '<') { |
|---|
| 2555 | 2628 | char *cp = strchr(line, ' '); |
|---|
| 2629 | + |
|---|
| 2556 | 2630 | if (cp) { |
|---|
| 2557 | 2631 | *cp++ = '\0'; |
|---|
| 2558 | 2632 | head->w.ns = tomoyo_assign_namespace(line); |
|---|
| .. | .. |
|---|
| 2585 | 2659 | size_t avail_len = buffer_len; |
|---|
| 2586 | 2660 | char *cp0 = head->write_buf; |
|---|
| 2587 | 2661 | int idx; |
|---|
| 2662 | + |
|---|
| 2588 | 2663 | if (!head->write) |
|---|
| 2589 | | - return -ENOSYS; |
|---|
| 2590 | | - if (!access_ok(VERIFY_READ, buffer, buffer_len)) |
|---|
| 2591 | | - return -EFAULT; |
|---|
| 2664 | + return -EINVAL; |
|---|
| 2592 | 2665 | if (mutex_lock_interruptible(&head->io_sem)) |
|---|
| 2593 | 2666 | return -EINTR; |
|---|
| 2594 | 2667 | head->read_user_buf_avail = 0; |
|---|
| .. | .. |
|---|
| 2596 | 2669 | /* Read a line and dispatch it to the policy handler. */ |
|---|
| 2597 | 2670 | while (avail_len > 0) { |
|---|
| 2598 | 2671 | char c; |
|---|
| 2672 | + |
|---|
| 2599 | 2673 | if (head->w.avail >= head->writebuf_size - 1) { |
|---|
| 2600 | 2674 | const int len = head->writebuf_size * 2; |
|---|
| 2601 | 2675 | char *cp = kzalloc(len, GFP_NOFS); |
|---|
| 2676 | + |
|---|
| 2602 | 2677 | if (!cp) { |
|---|
| 2603 | 2678 | error = -ENOMEM; |
|---|
| 2604 | 2679 | break; |
|---|
| .. | .. |
|---|
| 2635 | 2710 | case TOMOYO_DOMAINPOLICY: |
|---|
| 2636 | 2711 | if (tomoyo_select_domain(head, cp0)) |
|---|
| 2637 | 2712 | continue; |
|---|
| 2638 | | - /* fall through */ |
|---|
| 2713 | + fallthrough; |
|---|
| 2639 | 2714 | case TOMOYO_EXCEPTIONPOLICY: |
|---|
| 2640 | 2715 | if (!strcmp(cp0, "select transition_only")) { |
|---|
| 2641 | 2716 | head->r.print_transition_related_only = true; |
|---|
| 2642 | 2717 | continue; |
|---|
| 2643 | 2718 | } |
|---|
| 2644 | | - /* fall through */ |
|---|
| 2719 | + fallthrough; |
|---|
| 2645 | 2720 | default: |
|---|
| 2646 | 2721 | if (!tomoyo_manager()) { |
|---|
| 2647 | 2722 | error = -EPERM; |
|---|
| .. | .. |
|---|
| 2697 | 2772 | { |
|---|
| 2698 | 2773 | struct tomoyo_domain_info *domain; |
|---|
| 2699 | 2774 | const int idx = tomoyo_read_lock(); |
|---|
| 2775 | + |
|---|
| 2700 | 2776 | tomoyo_policy_loaded = true; |
|---|
| 2701 | | - printk(KERN_INFO "TOMOYO: 2.5.0\n"); |
|---|
| 2702 | | - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
|---|
| 2777 | + pr_info("TOMOYO: 2.6.0\n"); |
|---|
| 2778 | + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, |
|---|
| 2779 | + srcu_read_lock_held(&tomoyo_ss)) { |
|---|
| 2703 | 2780 | const u8 profile = domain->profile; |
|---|
| 2704 | | - const struct tomoyo_policy_namespace *ns = domain->ns; |
|---|
| 2705 | | - if (ns->profile_version != 20110903) |
|---|
| 2706 | | - printk(KERN_ERR |
|---|
| 2707 | | - "Profile version %u is not supported.\n", |
|---|
| 2781 | + struct tomoyo_policy_namespace *ns = domain->ns; |
|---|
| 2782 | + |
|---|
| 2783 | + if (ns->profile_version == 20110903) { |
|---|
| 2784 | + pr_info_once("Converting profile version from %u to %u.\n", |
|---|
| 2785 | + 20110903, 20150505); |
|---|
| 2786 | + ns->profile_version = 20150505; |
|---|
| 2787 | + } |
|---|
| 2788 | + if (ns->profile_version != 20150505) |
|---|
| 2789 | + pr_err("Profile version %u is not supported.\n", |
|---|
| 2708 | 2790 | ns->profile_version); |
|---|
| 2709 | 2791 | else if (!ns->profile_ptr[profile]) |
|---|
| 2710 | | - printk(KERN_ERR |
|---|
| 2711 | | - "Profile %u (used by '%s') is not defined.\n", |
|---|
| 2792 | + pr_err("Profile %u (used by '%s') is not defined.\n", |
|---|
| 2712 | 2793 | profile, domain->domainname->name); |
|---|
| 2713 | 2794 | else |
|---|
| 2714 | 2795 | continue; |
|---|
| 2715 | | - printk(KERN_ERR |
|---|
| 2716 | | - "Userland tools for TOMOYO 2.5 must be installed and " |
|---|
| 2717 | | - "policy must be initialized.\n"); |
|---|
| 2718 | | - printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.5/ " |
|---|
| 2719 | | - "for more information.\n"); |
|---|
| 2796 | + pr_err("Userland tools for TOMOYO 2.6 must be installed and policy must be initialized.\n"); |
|---|
| 2797 | + pr_err("Please see https://tomoyo.osdn.jp/2.6/ for more information.\n"); |
|---|
| 2720 | 2798 | panic("STOP!"); |
|---|
| 2721 | 2799 | } |
|---|
| 2722 | 2800 | tomoyo_read_unlock(idx); |
|---|
| 2723 | | - printk(KERN_INFO "Mandatory Access Control activated.\n"); |
|---|
| 2801 | + pr_info("Mandatory Access Control activated.\n"); |
|---|
| 2724 | 2802 | } |
|---|
| 2725 | 2803 | |
|---|
| 2726 | 2804 | /** |
|---|
| .. | .. |
|---|
| 2730 | 2808 | */ |
|---|
| 2731 | 2809 | void __init tomoyo_load_builtin_policy(void) |
|---|
| 2732 | 2810 | { |
|---|
| 2811 | +#ifdef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING |
|---|
| 2812 | + static char tomoyo_builtin_profile[] __initdata = |
|---|
| 2813 | + "PROFILE_VERSION=20150505\n" |
|---|
| 2814 | + "0-CONFIG={ mode=learning grant_log=no reject_log=yes }\n"; |
|---|
| 2815 | + static char tomoyo_builtin_exception_policy[] __initdata = |
|---|
| 2816 | + "aggregator proc:/self/exe /proc/self/exe\n"; |
|---|
| 2817 | + static char tomoyo_builtin_domain_policy[] __initdata = ""; |
|---|
| 2818 | + static char tomoyo_builtin_manager[] __initdata = ""; |
|---|
| 2819 | + static char tomoyo_builtin_stat[] __initdata = ""; |
|---|
| 2820 | +#else |
|---|
| 2733 | 2821 | /* |
|---|
| 2734 | 2822 | * This include file is manually created and contains built-in policy |
|---|
| 2735 | 2823 | * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy", |
|---|
| .. | .. |
|---|
| 2737 | 2825 | * "tomoyo_builtin_stat" in the form of "static char [] __initdata". |
|---|
| 2738 | 2826 | */ |
|---|
| 2739 | 2827 | #include "builtin-policy.h" |
|---|
| 2828 | +#endif |
|---|
| 2740 | 2829 | u8 i; |
|---|
| 2741 | 2830 | const int idx = tomoyo_read_lock(); |
|---|
| 2831 | + |
|---|
| 2742 | 2832 | for (i = 0; i < 5; i++) { |
|---|
| 2743 | 2833 | struct tomoyo_io_buffer head = { }; |
|---|
| 2744 | 2834 | char *start = ""; |
|---|
| 2835 | + |
|---|
| 2745 | 2836 | switch (i) { |
|---|
| 2746 | 2837 | case 0: |
|---|
| 2747 | 2838 | start = tomoyo_builtin_profile; |
|---|
| .. | .. |
|---|
| 2771 | 2862 | } |
|---|
| 2772 | 2863 | while (1) { |
|---|
| 2773 | 2864 | char *end = strchr(start, '\n'); |
|---|
| 2865 | + |
|---|
| 2774 | 2866 | if (!end) |
|---|
| 2775 | 2867 | break; |
|---|
| 2776 | 2868 | *end = '\0'; |
|---|