aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/condition.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/condition.c')
-rw-r--r--security/tomoyo/condition.c59
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,
182out: 189out:
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,
250static const struct tomoyo_path_info *tomoyo_get_dqword(char *start) 259static 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,
364static u8 tomoyo_condition_type(const char *word) 376static 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
492rerun: 509rerun:
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 }
623store_value: 641store_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],