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