diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/tomoyo/audit.c | 21 | ||||
| -rw-r--r-- | security/tomoyo/common.c | 66 | ||||
| -rw-r--r-- | security/tomoyo/common.h | 24 | ||||
| -rw-r--r-- | security/tomoyo/condition.c | 116 | ||||
| -rw-r--r-- | security/tomoyo/gc.c | 5 |
5 files changed, 228 insertions, 4 deletions
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c index 4973edd40718..b33a20accbef 100644 --- a/security/tomoyo/audit.c +++ b/security/tomoyo/audit.c | |||
| @@ -140,6 +140,8 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, | |||
| 140 | { | 140 | { |
| 141 | char *buf = NULL; | 141 | char *buf = NULL; |
| 142 | const char *header = NULL; | 142 | const char *header = NULL; |
| 143 | char *realpath = NULL; | ||
| 144 | const char *symlink = NULL; | ||
| 143 | int pos; | 145 | int pos; |
| 144 | const char *domainname = r->domain->domainname->name; | 146 | const char *domainname = r->domain->domainname->name; |
| 145 | header = tomoyo_print_header(r); | 147 | header = tomoyo_print_header(r); |
| @@ -147,15 +149,34 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, | |||
| 147 | return NULL; | 149 | return NULL; |
| 148 | /* +10 is for '\n' etc. and '\0'. */ | 150 | /* +10 is for '\n' etc. and '\0'. */ |
| 149 | len += strlen(domainname) + strlen(header) + 10; | 151 | len += strlen(domainname) + strlen(header) + 10; |
| 152 | if (r->ee) { | ||
| 153 | struct file *file = r->ee->bprm->file; | ||
| 154 | realpath = tomoyo_realpath_from_path(&file->f_path); | ||
| 155 | if (!realpath) | ||
| 156 | goto out; | ||
| 157 | /* +80 is for " exec={ realpath=\"%s\" }" */ | ||
| 158 | len += strlen(realpath) + 80; | ||
| 159 | } else if (r->obj && r->obj->symlink_target) { | ||
| 160 | symlink = r->obj->symlink_target->name; | ||
| 161 | /* +18 is for " symlink.target=\"%s\"" */ | ||
| 162 | len += 18 + strlen(symlink); | ||
| 163 | } | ||
| 150 | len = tomoyo_round2(len); | 164 | len = tomoyo_round2(len); |
| 151 | buf = kzalloc(len, GFP_NOFS); | 165 | buf = kzalloc(len, GFP_NOFS); |
| 152 | if (!buf) | 166 | if (!buf) |
| 153 | goto out; | 167 | goto out; |
| 154 | len--; | 168 | len--; |
| 155 | pos = snprintf(buf, len, "%s", header); | 169 | pos = snprintf(buf, len, "%s", header); |
| 170 | if (realpath) { | ||
| 171 | pos += snprintf(buf + pos, len - pos, | ||
| 172 | " exec={ realpath=\"%s\" }", realpath); | ||
| 173 | } else if (symlink) | ||
| 174 | pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"", | ||
| 175 | symlink); | ||
| 156 | pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); | 176 | pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); |
| 157 | vsnprintf(buf + pos, len - pos, fmt, args); | 177 | vsnprintf(buf + pos, len - pos, fmt, args); |
| 158 | out: | 178 | out: |
| 179 | kfree(realpath); | ||
| 159 | kfree(header); | 180 | kfree(header); |
| 160 | return buf; | 181 | return buf; |
| 161 | } | 182 | } |
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ec02d2ab08c3..69d6b59f5937 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
| @@ -79,6 +79,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = { | |||
| 79 | [TOMOYO_MODE_OTHERS_READ] = "others_read", | 79 | [TOMOYO_MODE_OTHERS_READ] = "others_read", |
| 80 | [TOMOYO_MODE_OTHERS_WRITE] = "others_write", | 80 | [TOMOYO_MODE_OTHERS_WRITE] = "others_write", |
| 81 | [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", | 81 | [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", |
| 82 | [TOMOYO_EXEC_REALPATH] = "exec.realpath", | ||
| 83 | [TOMOYO_SYMLINK_TARGET] = "symlink.target", | ||
| 82 | [TOMOYO_PATH1_UID] = "path1.uid", | 84 | [TOMOYO_PATH1_UID] = "path1.uid", |
| 83 | [TOMOYO_PATH1_GID] = "path1.gid", | 85 | [TOMOYO_PATH1_GID] = "path1.gid", |
| 84 | [TOMOYO_PATH1_INO] = "path1.ino", | 86 | [TOMOYO_PATH1_INO] = "path1.ino", |
| @@ -353,6 +355,27 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head, | |||
| 353 | } | 355 | } |
| 354 | 356 | ||
| 355 | /** | 357 | /** |
| 358 | * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote. | ||
| 359 | * | ||
| 360 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
| 361 | * @ptr: Pointer to "struct tomoyo_name_union". | ||
| 362 | * | ||
| 363 | * Returns nothing. | ||
| 364 | */ | ||
| 365 | static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head, | ||
| 366 | const struct tomoyo_name_union *ptr) | ||
| 367 | { | ||
| 368 | if (ptr->group) { | ||
| 369 | tomoyo_set_string(head, "@"); | ||
| 370 | tomoyo_set_string(head, ptr->group->group_name->name); | ||
| 371 | } else { | ||
| 372 | tomoyo_set_string(head, "\""); | ||
| 373 | tomoyo_set_string(head, ptr->filename->name); | ||
| 374 | tomoyo_set_string(head, "\""); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | /** | ||
| 356 | * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. | 379 | * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. |
| 357 | * | 380 | * |
| 358 | * @head: Pointer to "struct tomoyo_io_buffer". | 381 | * @head: Pointer to "struct tomoyo_io_buffer". |
| @@ -1101,6 +1124,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
| 1101 | (typeof(condp)) (cond + 1); | 1124 | (typeof(condp)) (cond + 1); |
| 1102 | const struct tomoyo_number_union *numbers_p = | 1125 | const struct tomoyo_number_union *numbers_p = |
| 1103 | (typeof(numbers_p)) (condp + condc); | 1126 | (typeof(numbers_p)) (condp + condc); |
| 1127 | const struct tomoyo_name_union *names_p = | ||
| 1128 | (typeof(names_p)) | ||
| 1129 | (numbers_p + cond->numbers_count); | ||
| 1104 | u16 skip; | 1130 | u16 skip; |
| 1105 | for (skip = 0; skip < head->r.cond_index; skip++) { | 1131 | for (skip = 0; skip < head->r.cond_index; skip++) { |
| 1106 | const u8 left = condp->left; | 1132 | const u8 left = condp->left; |
| @@ -1112,6 +1138,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
| 1112 | break; | 1138 | break; |
| 1113 | } | 1139 | } |
| 1114 | switch (right) { | 1140 | switch (right) { |
| 1141 | case TOMOYO_NAME_UNION: | ||
| 1142 | names_p++; | ||
| 1143 | break; | ||
| 1115 | case TOMOYO_NUMBER_UNION: | 1144 | case TOMOYO_NUMBER_UNION: |
| 1116 | numbers_p++; | 1145 | numbers_p++; |
| 1117 | break; | 1146 | break; |
| @@ -1138,6 +1167,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | |||
| 1138 | } | 1167 | } |
| 1139 | tomoyo_set_string(head, match ? "=" : "!="); | 1168 | tomoyo_set_string(head, match ? "=" : "!="); |
| 1140 | switch (right) { | 1169 | switch (right) { |
| 1170 | case TOMOYO_NAME_UNION: | ||
| 1171 | tomoyo_print_name_union_quoted | ||
| 1172 | (head, names_p++); | ||
| 1173 | break; | ||
| 1141 | case TOMOYO_NUMBER_UNION: | 1174 | case TOMOYO_NUMBER_UNION: |
| 1142 | tomoyo_print_number_union_nospace | 1175 | tomoyo_print_number_union_nospace |
| 1143 | (head, numbers_p++); | 1176 | (head, numbers_p++); |
| @@ -1666,6 +1699,22 @@ static DEFINE_SPINLOCK(tomoyo_query_list_lock); | |||
| 1666 | static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); | 1699 | static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); |
| 1667 | 1700 | ||
| 1668 | /** | 1701 | /** |
| 1702 | * tomoyo_truncate - Truncate a line. | ||
| 1703 | * | ||
| 1704 | * @str: String to truncate. | ||
| 1705 | * | ||
| 1706 | * Returns length of truncated @str. | ||
| 1707 | */ | ||
| 1708 | static int tomoyo_truncate(char *str) | ||
| 1709 | { | ||
| 1710 | char *start = str; | ||
| 1711 | while (*(unsigned char *) str > (unsigned char) ' ') | ||
| 1712 | str++; | ||
| 1713 | *str = '\0'; | ||
| 1714 | return strlen(start) + 1; | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | /** | ||
| 1669 | * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. | 1718 | * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. |
| 1670 | * | 1719 | * |
| 1671 | * @domain: Pointer to "struct tomoyo_domain_info". | 1720 | * @domain: Pointer to "struct tomoyo_domain_info". |
| @@ -1676,6 +1725,8 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); | |||
| 1676 | static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) | 1725 | static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) |
| 1677 | { | 1726 | { |
| 1678 | char *buffer; | 1727 | char *buffer; |
| 1728 | char *realpath = NULL; | ||
| 1729 | char *symlink = NULL; | ||
| 1679 | char *cp = strchr(header, '\n'); | 1730 | char *cp = strchr(header, '\n'); |
| 1680 | int len; | 1731 | int len; |
| 1681 | if (!cp) | 1732 | if (!cp) |
| @@ -1685,10 +1736,25 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) | |||
| 1685 | return; | 1736 | return; |
| 1686 | *cp++ = '\0'; | 1737 | *cp++ = '\0'; |
| 1687 | len = strlen(cp) + 1; | 1738 | len = strlen(cp) + 1; |
| 1739 | /* strstr() will return NULL if ordering is wrong. */ | ||
| 1740 | if (*cp == 'f') { | ||
| 1741 | realpath = strstr(header, " exec={ realpath=\""); | ||
| 1742 | if (realpath) { | ||
| 1743 | realpath += 8; | ||
| 1744 | len += tomoyo_truncate(realpath) + 6; | ||
| 1745 | } | ||
| 1746 | symlink = strstr(header, " symlink.target=\""); | ||
| 1747 | if (symlink) | ||
| 1748 | len += tomoyo_truncate(symlink + 1) + 1; | ||
| 1749 | } | ||
| 1688 | buffer = kmalloc(len, GFP_NOFS); | 1750 | buffer = kmalloc(len, GFP_NOFS); |
| 1689 | if (!buffer) | 1751 | if (!buffer) |
| 1690 | return; | 1752 | return; |
| 1691 | snprintf(buffer, len - 1, "%s", cp); | 1753 | snprintf(buffer, len - 1, "%s", cp); |
| 1754 | if (realpath) | ||
| 1755 | tomoyo_addprintf(buffer, len, " exec.%s", realpath); | ||
| 1756 | if (symlink) | ||
| 1757 | tomoyo_addprintf(buffer, len, "%s", symlink); | ||
| 1692 | tomoyo_normalize_line(buffer); | 1758 | tomoyo_normalize_line(buffer); |
| 1693 | if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, | 1759 | if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, |
| 1694 | false)) | 1760 | false)) |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 5a0fcedb332b..7e56e6b364e5 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
| @@ -73,6 +73,8 @@ enum tomoyo_conditions_index { | |||
| 73 | TOMOYO_MODE_OTHERS_READ, /* S_IROTH */ | 73 | TOMOYO_MODE_OTHERS_READ, /* S_IROTH */ |
| 74 | TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */ | 74 | TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */ |
| 75 | TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */ | 75 | TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */ |
| 76 | TOMOYO_EXEC_REALPATH, | ||
| 77 | TOMOYO_SYMLINK_TARGET, | ||
| 76 | TOMOYO_PATH1_UID, | 78 | TOMOYO_PATH1_UID, |
| 77 | TOMOYO_PATH1_GID, | 79 | TOMOYO_PATH1_GID, |
| 78 | TOMOYO_PATH1_INO, | 80 | TOMOYO_PATH1_INO, |
| @@ -101,6 +103,7 @@ enum tomoyo_conditions_index { | |||
| 101 | TOMOYO_PATH2_PARENT_PERM, | 103 | TOMOYO_PATH2_PARENT_PERM, |
| 102 | TOMOYO_MAX_CONDITION_KEYWORD, | 104 | TOMOYO_MAX_CONDITION_KEYWORD, |
| 103 | TOMOYO_NUMBER_UNION, | 105 | TOMOYO_NUMBER_UNION, |
| 106 | TOMOYO_NAME_UNION, | ||
| 104 | }; | 107 | }; |
| 105 | 108 | ||
| 106 | 109 | ||
| @@ -351,6 +354,11 @@ struct tomoyo_request_info { | |||
| 351 | * NULL if not dealing files. | 354 | * NULL if not dealing files. |
| 352 | */ | 355 | */ |
| 353 | struct tomoyo_obj_info *obj; | 356 | struct tomoyo_obj_info *obj; |
| 357 | /* | ||
| 358 | * For holding parameters specific to execve() request. | ||
| 359 | * NULL if not dealing do_execve(). | ||
| 360 | */ | ||
| 361 | struct tomoyo_execve *ee; | ||
| 354 | struct tomoyo_domain_info *domain; | 362 | struct tomoyo_domain_info *domain; |
| 355 | /* For holding parameters. */ | 363 | /* For holding parameters. */ |
| 356 | union { | 364 | union { |
| @@ -476,6 +484,20 @@ struct tomoyo_obj_info { | |||
| 476 | * parent directory. | 484 | * parent directory. |
| 477 | */ | 485 | */ |
| 478 | struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT]; | 486 | struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT]; |
| 487 | /* | ||
| 488 | * Content of symbolic link to be created. NULL for operations other | ||
| 489 | * than symlink(). | ||
| 490 | */ | ||
| 491 | struct tomoyo_path_info *symlink_target; | ||
| 492 | }; | ||
| 493 | |||
| 494 | /* Structure for execve() operation. */ | ||
| 495 | struct tomoyo_execve { | ||
| 496 | struct tomoyo_request_info r; | ||
| 497 | struct tomoyo_obj_info obj; | ||
| 498 | struct linux_binprm *bprm; | ||
| 499 | /* For temporary use. */ | ||
| 500 | char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */ | ||
| 479 | }; | 501 | }; |
| 480 | 502 | ||
| 481 | /* Structure for entries which follows "struct tomoyo_condition". */ | 503 | /* Structure for entries which follows "struct tomoyo_condition". */ |
| @@ -494,9 +516,11 @@ struct tomoyo_condition { | |||
| 494 | u32 size; /* Memory size allocated for this entry. */ | 516 | u32 size; /* Memory size allocated for this entry. */ |
| 495 | u16 condc; /* Number of conditions in this struct. */ | 517 | u16 condc; /* Number of conditions in this struct. */ |
| 496 | u16 numbers_count; /* Number of "struct tomoyo_number_union values". */ | 518 | u16 numbers_count; /* Number of "struct tomoyo_number_union values". */ |
| 519 | u16 names_count; /* Number of "struct tomoyo_name_union names". */ | ||
| 497 | /* | 520 | /* |
| 498 | * struct tomoyo_condition_element condition[condc]; | 521 | * struct tomoyo_condition_element condition[condc]; |
| 499 | * struct tomoyo_number_union values[numbers_count]; | 522 | * struct tomoyo_number_union values[numbers_count]; |
| 523 | * struct tomoyo_name_union names[names_count]; | ||
| 500 | */ | 524 | */ |
| 501 | }; | 525 | }; |
| 502 | 526 | ||
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index ac7ebeb47d7d..790b9872cc37 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c | |||
| @@ -11,6 +11,68 @@ | |||
| 11 | LIST_HEAD(tomoyo_condition_list); | 11 | LIST_HEAD(tomoyo_condition_list); |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition". | ||
| 15 | * | ||
| 16 | * @file: Pointer to "struct file". | ||
| 17 | * @ptr: Pointer to "struct tomoyo_name_union". | ||
| 18 | * @match: True if "exec.realpath=", false if "exec.realpath!=". | ||
| 19 | * | ||
| 20 | * Returns true on success, false otherwise. | ||
| 21 | */ | ||
| 22 | static bool tomoyo_scan_exec_realpath(struct file *file, | ||
| 23 | const struct tomoyo_name_union *ptr, | ||
| 24 | const bool match) | ||
| 25 | { | ||
| 26 | bool result; | ||
| 27 | struct tomoyo_path_info exe; | ||
| 28 | if (!file) | ||
| 29 | return false; | ||
| 30 | exe.name = tomoyo_realpath_from_path(&file->f_path); | ||
| 31 | if (!exe.name) | ||
| 32 | return false; | ||
| 33 | tomoyo_fill_path_info(&exe); | ||
| 34 | result = tomoyo_compare_name_union(&exe, ptr); | ||
| 35 | kfree(exe.name); | ||
| 36 | return result == match; | ||
| 37 | } | ||
| 38 | |||
| 39 | /** | ||
| 40 | * tomoyo_get_dqword - tomoyo_get_name() for a quoted string. | ||
| 41 | * | ||
| 42 | * @start: String to save. | ||
| 43 | * | ||
| 44 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. | ||
| 45 | */ | ||
| 46 | static const struct tomoyo_path_info *tomoyo_get_dqword(char *start) | ||
| 47 | { | ||
| 48 | char *cp = start + strlen(start) - 1; | ||
| 49 | if (cp == start || *start++ != '"' || *cp != '"') | ||
| 50 | return NULL; | ||
| 51 | *cp = '\0'; | ||
| 52 | if (*start && !tomoyo_correct_word(start)) | ||
| 53 | return NULL; | ||
| 54 | return tomoyo_get_name(start); | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * tomoyo_parse_name_union_quoted - Parse a quoted word. | ||
| 59 | * | ||
| 60 | * @param: Pointer to "struct tomoyo_acl_param". | ||
| 61 | * @ptr: Pointer to "struct tomoyo_name_union". | ||
| 62 | * | ||
| 63 | * Returns true on success, false otherwise. | ||
| 64 | */ | ||
| 65 | static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param, | ||
| 66 | struct tomoyo_name_union *ptr) | ||
| 67 | { | ||
| 68 | char *filename = param->data; | ||
| 69 | if (*filename == '@') | ||
| 70 | return tomoyo_parse_name_union(param, ptr); | ||
| 71 | ptr->filename = tomoyo_get_dqword(filename); | ||
| 72 | return ptr->filename != NULL; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 14 | * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry. | 76 | * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry. |
| 15 | * | 77 | * |
| 16 | * @a: Pointer to "struct tomoyo_condition". | 78 | * @a: Pointer to "struct tomoyo_condition". |
| @@ -23,6 +85,7 @@ static inline bool tomoyo_same_condition(const struct tomoyo_condition *a, | |||
| 23 | { | 85 | { |
| 24 | return a->size == b->size && a->condc == b->condc && | 86 | return a->size == b->size && a->condc == b->condc && |
| 25 | a->numbers_count == b->numbers_count && | 87 | a->numbers_count == b->numbers_count && |
| 88 | a->names_count == b->names_count && | ||
| 26 | !memcmp(a + 1, b + 1, a->size - sizeof(*a)); | 89 | !memcmp(a + 1, b + 1, a->size - sizeof(*a)); |
| 27 | } | 90 | } |
| 28 | 91 | ||
| @@ -114,6 +177,7 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param) | |||
| 114 | struct tomoyo_condition *entry = NULL; | 177 | struct tomoyo_condition *entry = NULL; |
| 115 | struct tomoyo_condition_element *condp = NULL; | 178 | struct tomoyo_condition_element *condp = NULL; |
| 116 | struct tomoyo_number_union *numbers_p = NULL; | 179 | struct tomoyo_number_union *numbers_p = NULL; |
| 180 | struct tomoyo_name_union *names_p = NULL; | ||
| 117 | struct tomoyo_condition e = { }; | 181 | struct tomoyo_condition e = { }; |
| 118 | char * const start_of_string = param->data; | 182 | char * const start_of_string = param->data; |
| 119 | char * const end_of_string = start_of_string + strlen(start_of_string); | 183 | char * const end_of_string = start_of_string + strlen(start_of_string); |
| @@ -178,6 +242,20 @@ rerun: | |||
| 178 | e.condc++; | 242 | e.condc++; |
| 179 | else | 243 | else |
| 180 | e.condc--; | 244 | e.condc--; |
| 245 | if (left == TOMOYO_EXEC_REALPATH || | ||
| 246 | left == TOMOYO_SYMLINK_TARGET) { | ||
| 247 | if (!names_p) { | ||
| 248 | e.names_count++; | ||
| 249 | } else { | ||
| 250 | e.names_count--; | ||
| 251 | right = TOMOYO_NAME_UNION; | ||
| 252 | param->data = right_word; | ||
| 253 | if (!tomoyo_parse_name_union_quoted(param, | ||
| 254 | names_p++)) | ||
| 255 | goto out; | ||
| 256 | } | ||
| 257 | goto store_value; | ||
| 258 | } | ||
| 181 | right = tomoyo_condition_type(right_word); | 259 | right = tomoyo_condition_type(right_word); |
| 182 | if (right == TOMOYO_MAX_CONDITION_KEYWORD) { | 260 | if (right == TOMOYO_MAX_CONDITION_KEYWORD) { |
| 183 | if (!numbers_p) { | 261 | if (!numbers_p) { |
| @@ -191,6 +269,7 @@ rerun: | |||
| 191 | goto out; | 269 | goto out; |
| 192 | } | 270 | } |
| 193 | } | 271 | } |
| 272 | store_value: | ||
| 194 | if (!condp) { | 273 | if (!condp) { |
| 195 | dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " | 274 | dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " |
| 196 | "match=%u\n", __LINE__, left, right, !is_not); | 275 | "match=%u\n", __LINE__, left, right, !is_not); |
| @@ -204,21 +283,23 @@ rerun: | |||
| 204 | condp->equals); | 283 | condp->equals); |
| 205 | condp++; | 284 | condp++; |
| 206 | } | 285 | } |
| 207 | dprintk(KERN_INFO "%u: cond=%u numbers=%u\n", | 286 | dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u\n", |
| 208 | __LINE__, e.condc, e.numbers_count); | 287 | __LINE__, e.condc, e.numbers_count, e.names_count); |
| 209 | if (entry) { | 288 | if (entry) { |
| 210 | BUG_ON(e.numbers_count | e.condc); | 289 | BUG_ON(e.names_count | e.numbers_count | e.condc); |
| 211 | return tomoyo_commit_condition(entry); | 290 | return tomoyo_commit_condition(entry); |
| 212 | } | 291 | } |
| 213 | e.size = sizeof(*entry) | 292 | e.size = sizeof(*entry) |
| 214 | + e.condc * sizeof(struct tomoyo_condition_element) | 293 | + e.condc * sizeof(struct tomoyo_condition_element) |
| 215 | + e.numbers_count * sizeof(struct tomoyo_number_union); | 294 | + e.numbers_count * sizeof(struct tomoyo_number_union) |
| 295 | + e.names_count * sizeof(struct tomoyo_name_union); | ||
| 216 | entry = kzalloc(e.size, GFP_NOFS); | 296 | entry = kzalloc(e.size, GFP_NOFS); |
| 217 | if (!entry) | 297 | if (!entry) |
| 218 | return NULL; | 298 | return NULL; |
| 219 | *entry = e; | 299 | *entry = e; |
| 220 | condp = (struct tomoyo_condition_element *) (entry + 1); | 300 | condp = (struct tomoyo_condition_element *) (entry + 1); |
| 221 | numbers_p = (struct tomoyo_number_union *) (condp + e.condc); | 301 | numbers_p = (struct tomoyo_number_union *) (condp + e.condc); |
| 302 | names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count); | ||
| 222 | { | 303 | { |
| 223 | bool flag = false; | 304 | bool flag = false; |
| 224 | for (pos = start_of_string; pos < end_of_string; pos++) { | 305 | for (pos = start_of_string; pos < end_of_string; pos++) { |
| @@ -309,6 +390,7 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
| 309 | unsigned long max_v[2] = { 0, 0 }; | 390 | unsigned long max_v[2] = { 0, 0 }; |
| 310 | const struct tomoyo_condition_element *condp; | 391 | const struct tomoyo_condition_element *condp; |
| 311 | const struct tomoyo_number_union *numbers_p; | 392 | const struct tomoyo_number_union *numbers_p; |
| 393 | const struct tomoyo_name_union *names_p; | ||
| 312 | struct tomoyo_obj_info *obj; | 394 | struct tomoyo_obj_info *obj; |
| 313 | u16 condc; | 395 | u16 condc; |
| 314 | if (!cond) | 396 | if (!cond) |
| @@ -317,6 +399,8 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
| 317 | obj = r->obj; | 399 | obj = r->obj; |
| 318 | condp = (struct tomoyo_condition_element *) (cond + 1); | 400 | condp = (struct tomoyo_condition_element *) (cond + 1); |
| 319 | numbers_p = (const struct tomoyo_number_union *) (condp + condc); | 401 | numbers_p = (const struct tomoyo_number_union *) (condp + condc); |
| 402 | names_p = (const struct tomoyo_name_union *) | ||
| 403 | (numbers_p + cond->numbers_count); | ||
| 320 | for (i = 0; i < condc; i++) { | 404 | for (i = 0; i < condc; i++) { |
| 321 | const bool match = condp->equals; | 405 | const bool match = condp->equals; |
| 322 | const u8 left = condp->left; | 406 | const u8 left = condp->left; |
| @@ -324,6 +408,30 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
| 324 | bool is_bitop[2] = { false, false }; | 408 | bool is_bitop[2] = { false, false }; |
| 325 | u8 j; | 409 | u8 j; |
| 326 | condp++; | 410 | condp++; |
| 411 | /* Check string expressions. */ | ||
| 412 | if (right == TOMOYO_NAME_UNION) { | ||
| 413 | const struct tomoyo_name_union *ptr = names_p++; | ||
| 414 | switch (left) { | ||
| 415 | struct tomoyo_path_info *symlink; | ||
| 416 | struct tomoyo_execve *ee; | ||
| 417 | struct file *file; | ||
| 418 | case TOMOYO_SYMLINK_TARGET: | ||
| 419 | symlink = obj ? obj->symlink_target : NULL; | ||
| 420 | if (!symlink || | ||
| 421 | !tomoyo_compare_name_union(symlink, ptr) | ||
| 422 | == match) | ||
| 423 | goto out; | ||
| 424 | break; | ||
| 425 | case TOMOYO_EXEC_REALPATH: | ||
| 426 | ee = r->ee; | ||
| 427 | file = ee ? ee->bprm->file : NULL; | ||
| 428 | if (!tomoyo_scan_exec_realpath(file, ptr, | ||
| 429 | match)) | ||
| 430 | goto out; | ||
| 431 | break; | ||
| 432 | } | ||
| 433 | continue; | ||
| 434 | } | ||
| 327 | /* Check numeric or bit-op expressions. */ | 435 | /* Check numeric or bit-op expressions. */ |
| 328 | for (j = 0; j < 2; j++) { | 436 | for (j = 0; j < 2; j++) { |
| 329 | const u8 index = j ? right : left; | 437 | const u8 index = j ? right : left; |
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index 21fccd67c255..e0502b6d5866 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c | |||
| @@ -357,13 +357,18 @@ void tomoyo_del_condition(struct list_head *element) | |||
| 357 | head.list); | 357 | head.list); |
| 358 | const u16 condc = cond->condc; | 358 | const u16 condc = cond->condc; |
| 359 | const u16 numbers_count = cond->numbers_count; | 359 | const u16 numbers_count = cond->numbers_count; |
| 360 | const u16 names_count = cond->names_count; | ||
| 360 | unsigned int i; | 361 | unsigned int i; |
| 361 | const struct tomoyo_condition_element *condp | 362 | const struct tomoyo_condition_element *condp |
| 362 | = (const struct tomoyo_condition_element *) (cond + 1); | 363 | = (const struct tomoyo_condition_element *) (cond + 1); |
| 363 | struct tomoyo_number_union *numbers_p | 364 | struct tomoyo_number_union *numbers_p |
| 364 | = (struct tomoyo_number_union *) (condp + condc); | 365 | = (struct tomoyo_number_union *) (condp + condc); |
| 366 | struct tomoyo_name_union *names_p | ||
| 367 | = (struct tomoyo_name_union *) (numbers_p + numbers_count); | ||
| 365 | for (i = 0; i < numbers_count; i++) | 368 | for (i = 0; i < numbers_count; i++) |
| 366 | tomoyo_put_number_union(numbers_p++); | 369 | tomoyo_put_number_union(numbers_p++); |
| 370 | for (i = 0; i < names_count; i++) | ||
| 371 | tomoyo_put_name_union(names_p++); | ||
| 367 | } | 372 | } |
| 368 | 373 | ||
| 369 | /** | 374 | /** |
