| .. | .. |
|---|
| 28 | 28 | { |
|---|
| 29 | 29 | int i; |
|---|
| 30 | 30 | struct tomoyo_path_info arg; |
|---|
| 31 | + |
|---|
| 31 | 32 | arg.name = arg_ptr; |
|---|
| 32 | 33 | for (i = 0; i < argc; argv++, checked++, i++) { |
|---|
| 33 | 34 | bool result; |
|---|
| 35 | + |
|---|
| 34 | 36 | if (index != argv->index) |
|---|
| 35 | 37 | continue; |
|---|
| 36 | 38 | *checked = 1; |
|---|
| .. | .. |
|---|
| 62 | 64 | int i; |
|---|
| 63 | 65 | struct tomoyo_path_info name; |
|---|
| 64 | 66 | struct tomoyo_path_info value; |
|---|
| 67 | + |
|---|
| 65 | 68 | name.name = env_name; |
|---|
| 66 | 69 | tomoyo_fill_path_info(&name); |
|---|
| 67 | 70 | value.name = env_value; |
|---|
| 68 | 71 | tomoyo_fill_path_info(&value); |
|---|
| 69 | 72 | for (i = 0; i < envc; envp++, checked++, i++) { |
|---|
| 70 | 73 | bool result; |
|---|
| 74 | + |
|---|
| 71 | 75 | if (!tomoyo_path_matches_pattern(&name, envp->name)) |
|---|
| 72 | 76 | continue; |
|---|
| 73 | 77 | *checked = 1; |
|---|
| .. | .. |
|---|
| 113 | 117 | bool result = true; |
|---|
| 114 | 118 | u8 local_checked[32]; |
|---|
| 115 | 119 | u8 *checked; |
|---|
| 120 | + |
|---|
| 116 | 121 | if (argc + envc <= sizeof(local_checked)) { |
|---|
| 117 | 122 | checked = local_checked; |
|---|
| 118 | 123 | memset(local_checked, 0, sizeof(local_checked)); |
|---|
| .. | .. |
|---|
| 131 | 136 | /* Read. */ |
|---|
| 132 | 137 | const char *kaddr = dump->data; |
|---|
| 133 | 138 | const unsigned char c = kaddr[offset++]; |
|---|
| 139 | + |
|---|
| 134 | 140 | if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) { |
|---|
| 135 | 141 | if (c == '\\') { |
|---|
| 136 | 142 | arg_ptr[arg_len++] = '\\'; |
|---|
| .. | .. |
|---|
| 160 | 166 | argv_count--; |
|---|
| 161 | 167 | } else if (envp_count) { |
|---|
| 162 | 168 | char *cp = strchr(arg_ptr, '='); |
|---|
| 169 | + |
|---|
| 163 | 170 | if (cp) { |
|---|
| 164 | 171 | *cp = '\0'; |
|---|
| 165 | 172 | if (!tomoyo_envp(arg_ptr, cp + 1, |
|---|
| .. | .. |
|---|
| 182 | 189 | out: |
|---|
| 183 | 190 | if (result) { |
|---|
| 184 | 191 | int i; |
|---|
| 192 | + |
|---|
| 185 | 193 | /* Check not-yet-checked entries. */ |
|---|
| 186 | 194 | for (i = 0; i < argc; i++) { |
|---|
| 187 | 195 | if (checked[i]) |
|---|
| .. | .. |
|---|
| 229 | 237 | { |
|---|
| 230 | 238 | bool result; |
|---|
| 231 | 239 | struct tomoyo_path_info exe; |
|---|
| 240 | + |
|---|
| 232 | 241 | if (!file) |
|---|
| 233 | 242 | return false; |
|---|
| 234 | 243 | exe.name = tomoyo_realpath_from_path(&file->f_path); |
|---|
| .. | .. |
|---|
| 250 | 259 | static const struct tomoyo_path_info *tomoyo_get_dqword(char *start) |
|---|
| 251 | 260 | { |
|---|
| 252 | 261 | char *cp = start + strlen(start) - 1; |
|---|
| 262 | + |
|---|
| 253 | 263 | if (cp == start || *start++ != '"' || *cp != '"') |
|---|
| 254 | 264 | return NULL; |
|---|
| 255 | 265 | *cp = '\0'; |
|---|
| .. | .. |
|---|
| 270 | 280 | struct tomoyo_name_union *ptr) |
|---|
| 271 | 281 | { |
|---|
| 272 | 282 | char *filename = param->data; |
|---|
| 283 | + |
|---|
| 273 | 284 | if (*filename == '@') |
|---|
| 274 | 285 | return tomoyo_parse_name_union(param, ptr); |
|---|
| 275 | 286 | ptr->filename = tomoyo_get_dqword(filename); |
|---|
| .. | .. |
|---|
| 310 | 321 | const struct tomoyo_path_info *name; |
|---|
| 311 | 322 | const struct tomoyo_path_info *value; |
|---|
| 312 | 323 | char *cp = left + strlen(left) - 1; |
|---|
| 324 | + |
|---|
| 313 | 325 | if (*cp-- != ']' || *cp != '"') |
|---|
| 314 | 326 | goto out; |
|---|
| 315 | 327 | *cp = '\0'; |
|---|
| .. | .. |
|---|
| 364 | 376 | static u8 tomoyo_condition_type(const char *word) |
|---|
| 365 | 377 | { |
|---|
| 366 | 378 | u8 i; |
|---|
| 379 | + |
|---|
| 367 | 380 | for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) { |
|---|
| 368 | 381 | if (!strcmp(word, tomoyo_condition_keyword[i])) |
|---|
| 369 | 382 | break; |
|---|
| .. | .. |
|---|
| 395 | 408 | { |
|---|
| 396 | 409 | struct tomoyo_condition *ptr; |
|---|
| 397 | 410 | bool found = false; |
|---|
| 411 | + |
|---|
| 398 | 412 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) { |
|---|
| 399 | 413 | dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__); |
|---|
| 400 | 414 | ptr = NULL; |
|---|
| .. | .. |
|---|
| 442 | 456 | { |
|---|
| 443 | 457 | char * const pos = param->data; |
|---|
| 444 | 458 | bool flag; |
|---|
| 459 | + |
|---|
| 445 | 460 | if (*pos == '<') { |
|---|
| 446 | 461 | e->transit = tomoyo_get_domainname(param); |
|---|
| 447 | 462 | goto done; |
|---|
| 448 | 463 | } |
|---|
| 449 | 464 | { |
|---|
| 450 | 465 | char *cp = strchr(pos, ' '); |
|---|
| 466 | + |
|---|
| 451 | 467 | if (cp) |
|---|
| 452 | 468 | *cp = '\0'; |
|---|
| 453 | 469 | flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") || |
|---|
| .. | .. |
|---|
| 489 | 505 | tomoyo_get_transit_preference(param, &e); |
|---|
| 490 | 506 | char * const end_of_string = start_of_string + strlen(start_of_string); |
|---|
| 491 | 507 | char *pos; |
|---|
| 508 | + |
|---|
| 492 | 509 | rerun: |
|---|
| 493 | 510 | pos = start_of_string; |
|---|
| 494 | 511 | while (1) { |
|---|
| .. | .. |
|---|
| 498 | 515 | char *cp; |
|---|
| 499 | 516 | char *right_word; |
|---|
| 500 | 517 | bool is_not; |
|---|
| 518 | + |
|---|
| 501 | 519 | if (!*left_word) |
|---|
| 502 | 520 | break; |
|---|
| 503 | 521 | /* |
|---|
| .. | .. |
|---|
| 622 | 640 | } |
|---|
| 623 | 641 | store_value: |
|---|
| 624 | 642 | if (!condp) { |
|---|
| 625 | | - dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " |
|---|
| 626 | | - "match=%u\n", __LINE__, left, right, !is_not); |
|---|
| 643 | + dprintk(KERN_WARNING "%u: dry_run left=%u right=%u match=%u\n", |
|---|
| 644 | + __LINE__, left, right, !is_not); |
|---|
| 627 | 645 | continue; |
|---|
| 628 | 646 | } |
|---|
| 629 | 647 | condp->left = left; |
|---|
| .. | .. |
|---|
| 660 | 678 | envp = (struct tomoyo_envp *) (argv + e.argc); |
|---|
| 661 | 679 | { |
|---|
| 662 | 680 | bool flag = false; |
|---|
| 681 | + |
|---|
| 663 | 682 | for (pos = start_of_string; pos < end_of_string; pos++) { |
|---|
| 664 | 683 | if (*pos) |
|---|
| 665 | 684 | continue; |
|---|
| .. | .. |
|---|
| 698 | 717 | |
|---|
| 699 | 718 | for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { |
|---|
| 700 | 719 | struct inode *inode; |
|---|
| 720 | + |
|---|
| 701 | 721 | switch (i) { |
|---|
| 702 | 722 | case TOMOYO_PATH1: |
|---|
| 703 | 723 | dentry = obj->path1.dentry; |
|---|
| .. | .. |
|---|
| 718 | 738 | inode = d_backing_inode(dentry); |
|---|
| 719 | 739 | if (inode) { |
|---|
| 720 | 740 | struct tomoyo_mini_stat *stat = &obj->stat[i]; |
|---|
| 741 | + |
|---|
| 721 | 742 | stat->uid = inode->i_uid; |
|---|
| 722 | 743 | stat->gid = inode->i_gid; |
|---|
| 723 | 744 | stat->ino = inode->i_ino; |
|---|
| .. | .. |
|---|
| 726 | 747 | stat->rdev = inode->i_rdev; |
|---|
| 727 | 748 | obj->stat_valid[i] = true; |
|---|
| 728 | 749 | } |
|---|
| 729 | | - if (i & 1) /* i == TOMOYO_PATH1_PARENT || |
|---|
| 730 | | - i == TOMOYO_PATH2_PARENT */ |
|---|
| 750 | + if (i & 1) /* TOMOYO_PATH1_PARENT or TOMOYO_PATH2_PARENT */ |
|---|
| 731 | 751 | dput(dentry); |
|---|
| 732 | 752 | } |
|---|
| 733 | 753 | } |
|---|
| .. | .. |
|---|
| 758 | 778 | u16 argc; |
|---|
| 759 | 779 | u16 envc; |
|---|
| 760 | 780 | struct linux_binprm *bprm = NULL; |
|---|
| 781 | + |
|---|
| 761 | 782 | if (!cond) |
|---|
| 762 | 783 | return true; |
|---|
| 763 | 784 | condc = cond->condc; |
|---|
| .. | .. |
|---|
| 780 | 801 | const u8 right = condp->right; |
|---|
| 781 | 802 | bool is_bitop[2] = { false, false }; |
|---|
| 782 | 803 | u8 j; |
|---|
| 804 | + |
|---|
| 783 | 805 | condp++; |
|---|
| 784 | 806 | /* Check argv[] and envp[] later. */ |
|---|
| 785 | 807 | if (left == TOMOYO_ARGV_ENTRY || left == TOMOYO_ENVP_ENTRY) |
|---|
| .. | .. |
|---|
| 787 | 809 | /* Check string expressions. */ |
|---|
| 788 | 810 | if (right == TOMOYO_NAME_UNION) { |
|---|
| 789 | 811 | const struct tomoyo_name_union *ptr = names_p++; |
|---|
| 812 | + struct tomoyo_path_info *symlink; |
|---|
| 813 | + struct tomoyo_execve *ee; |
|---|
| 814 | + struct file *file; |
|---|
| 815 | + |
|---|
| 790 | 816 | switch (left) { |
|---|
| 791 | | - struct tomoyo_path_info *symlink; |
|---|
| 792 | | - struct tomoyo_execve *ee; |
|---|
| 793 | | - struct file *file; |
|---|
| 794 | 817 | case TOMOYO_SYMLINK_TARGET: |
|---|
| 795 | 818 | symlink = obj ? obj->symlink_target : NULL; |
|---|
| 796 | 819 | if (!symlink || |
|---|
| .. | .. |
|---|
| 812 | 835 | for (j = 0; j < 2; j++) { |
|---|
| 813 | 836 | const u8 index = j ? right : left; |
|---|
| 814 | 837 | unsigned long value = 0; |
|---|
| 838 | + |
|---|
| 815 | 839 | switch (index) { |
|---|
| 816 | 840 | case TOMOYO_TASK_UID: |
|---|
| 817 | 841 | value = from_kuid(&init_user_ns, current_uid()); |
|---|
| .. | .. |
|---|
| 874 | 898 | value = S_ISVTX; |
|---|
| 875 | 899 | break; |
|---|
| 876 | 900 | case TOMOYO_MODE_OWNER_READ: |
|---|
| 877 | | - value = S_IRUSR; |
|---|
| 901 | + value = 0400; |
|---|
| 878 | 902 | break; |
|---|
| 879 | 903 | case TOMOYO_MODE_OWNER_WRITE: |
|---|
| 880 | | - value = S_IWUSR; |
|---|
| 904 | + value = 0200; |
|---|
| 881 | 905 | break; |
|---|
| 882 | 906 | case TOMOYO_MODE_OWNER_EXECUTE: |
|---|
| 883 | | - value = S_IXUSR; |
|---|
| 907 | + value = 0100; |
|---|
| 884 | 908 | break; |
|---|
| 885 | 909 | case TOMOYO_MODE_GROUP_READ: |
|---|
| 886 | | - value = S_IRGRP; |
|---|
| 910 | + value = 0040; |
|---|
| 887 | 911 | break; |
|---|
| 888 | 912 | case TOMOYO_MODE_GROUP_WRITE: |
|---|
| 889 | | - value = S_IWGRP; |
|---|
| 913 | + value = 0020; |
|---|
| 890 | 914 | break; |
|---|
| 891 | 915 | case TOMOYO_MODE_GROUP_EXECUTE: |
|---|
| 892 | | - value = S_IXGRP; |
|---|
| 916 | + value = 0010; |
|---|
| 893 | 917 | break; |
|---|
| 894 | 918 | case TOMOYO_MODE_OTHERS_READ: |
|---|
| 895 | | - value = S_IROTH; |
|---|
| 919 | + value = 0004; |
|---|
| 896 | 920 | break; |
|---|
| 897 | 921 | case TOMOYO_MODE_OTHERS_WRITE: |
|---|
| 898 | | - value = S_IWOTH; |
|---|
| 922 | + value = 0002; |
|---|
| 899 | 923 | break; |
|---|
| 900 | 924 | case TOMOYO_MODE_OTHERS_EXECUTE: |
|---|
| 901 | | - value = S_IXOTH; |
|---|
| 925 | + value = 0001; |
|---|
| 902 | 926 | break; |
|---|
| 903 | 927 | case TOMOYO_EXEC_ARGC: |
|---|
| 904 | 928 | if (!bprm) |
|---|
| .. | .. |
|---|
| 923 | 947 | { |
|---|
| 924 | 948 | u8 stat_index; |
|---|
| 925 | 949 | struct tomoyo_mini_stat *stat; |
|---|
| 950 | + |
|---|
| 926 | 951 | switch (index) { |
|---|
| 927 | 952 | case TOMOYO_PATH1_UID: |
|---|
| 928 | 953 | case TOMOYO_PATH1_GID: |
|---|
| .. | .. |
|---|
| 1036 | 1061 | if (left == TOMOYO_NUMBER_UNION) { |
|---|
| 1037 | 1062 | /* Fetch values now. */ |
|---|
| 1038 | 1063 | const struct tomoyo_number_union *ptr = numbers_p++; |
|---|
| 1064 | + |
|---|
| 1039 | 1065 | min_v[0] = ptr->values[0]; |
|---|
| 1040 | 1066 | max_v[0] = ptr->values[1]; |
|---|
| 1041 | 1067 | } |
|---|
| 1042 | 1068 | if (right == TOMOYO_NUMBER_UNION) { |
|---|
| 1043 | 1069 | /* Fetch values now. */ |
|---|
| 1044 | 1070 | const struct tomoyo_number_union *ptr = numbers_p++; |
|---|
| 1071 | + |
|---|
| 1045 | 1072 | if (ptr->group) { |
|---|
| 1046 | 1073 | if (tomoyo_number_matches_group(min_v[0], |
|---|
| 1047 | 1074 | max_v[0], |
|---|