diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 6580ef35074b..507ebf01e43b 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -896,6 +896,12 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
896 | domain->profile = (u8) profile; | 896 | domain->profile = (u8) profile; |
897 | return 0; | 897 | return 0; |
898 | } | 898 | } |
899 | if (sscanf(data, "use_group %u\n", &profile) == 1 | ||
900 | && profile < TOMOYO_MAX_ACL_GROUPS) { | ||
901 | if (!is_delete) | ||
902 | domain->group = (u8) profile; | ||
903 | return 0; | ||
904 | } | ||
899 | if (!strcmp(data, "quota_exceeded")) { | 905 | if (!strcmp(data, "quota_exceeded")) { |
900 | domain->quota_warned = !is_delete; | 906 | domain->quota_warned = !is_delete; |
901 | return 0; | 907 | return 0; |
@@ -908,7 +914,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
908 | } | 914 | } |
909 | 915 | ||
910 | /** | 916 | /** |
911 | * tomoyo_set_group - Print category name. | 917 | * tomoyo_set_group - Print "acl_group " header keyword and category name. |
912 | * | 918 | * |
913 | * @head: Pointer to "struct tomoyo_io_buffer". | 919 | * @head: Pointer to "struct tomoyo_io_buffer". |
914 | * @category: Category name. | 920 | * @category: Category name. |
@@ -918,6 +924,9 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
918 | static void tomoyo_set_group(struct tomoyo_io_buffer *head, | 924 | static void tomoyo_set_group(struct tomoyo_io_buffer *head, |
919 | const char *category) | 925 | const char *category) |
920 | { | 926 | { |
927 | if (head->type == TOMOYO_EXCEPTIONPOLICY) | ||
928 | tomoyo_io_printf(head, "acl_group %u ", | ||
929 | head->r.acl_group_index); | ||
921 | tomoyo_set_string(head, category); | 930 | tomoyo_set_string(head, category); |
922 | } | 931 | } |
923 | 932 | ||
@@ -1041,17 +1050,17 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1041 | /** | 1050 | /** |
1042 | * tomoyo_read_domain2 - Read domain policy. | 1051 | * tomoyo_read_domain2 - Read domain policy. |
1043 | * | 1052 | * |
1044 | * @head: Pointer to "struct tomoyo_io_buffer". | 1053 | * @head: Pointer to "struct tomoyo_io_buffer". |
1045 | * @domain: Pointer to "struct tomoyo_domain_info". | 1054 | * @list: Pointer to "struct list_head". |
1046 | * | 1055 | * |
1047 | * Caller holds tomoyo_read_lock(). | 1056 | * Caller holds tomoyo_read_lock(). |
1048 | * | 1057 | * |
1049 | * Returns true on success, false otherwise. | 1058 | * Returns true on success, false otherwise. |
1050 | */ | 1059 | */ |
1051 | static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, | 1060 | static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, |
1052 | struct tomoyo_domain_info *domain) | 1061 | struct list_head *list) |
1053 | { | 1062 | { |
1054 | list_for_each_cookie(head->r.acl, &domain->acl_info_list) { | 1063 | list_for_each_cookie(head->r.acl, list) { |
1055 | struct tomoyo_acl_info *ptr = | 1064 | struct tomoyo_acl_info *ptr = |
1056 | list_entry(head->r.acl, typeof(*ptr), list); | 1065 | list_entry(head->r.acl, typeof(*ptr), list); |
1057 | if (!tomoyo_print_entry(head, ptr)) | 1066 | if (!tomoyo_print_entry(head, ptr)) |
@@ -1085,6 +1094,8 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head) | |||
1085 | tomoyo_set_lf(head); | 1094 | tomoyo_set_lf(head); |
1086 | tomoyo_io_printf(head, "use_profile %u\n", | 1095 | tomoyo_io_printf(head, "use_profile %u\n", |
1087 | domain->profile); | 1096 | domain->profile); |
1097 | tomoyo_io_printf(head, "use_group %u\n", | ||
1098 | domain->group); | ||
1088 | if (domain->quota_warned) | 1099 | if (domain->quota_warned) |
1089 | tomoyo_set_string(head, "quota_exceeded\n"); | 1100 | tomoyo_set_string(head, "quota_exceeded\n"); |
1090 | if (domain->transition_failed) | 1101 | if (domain->transition_failed) |
@@ -1093,7 +1104,7 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head) | |||
1093 | tomoyo_set_lf(head); | 1104 | tomoyo_set_lf(head); |
1094 | /* fall through */ | 1105 | /* fall through */ |
1095 | case 1: | 1106 | case 1: |
1096 | if (!tomoyo_read_domain2(head, domain)) | 1107 | if (!tomoyo_read_domain2(head, &domain->acl_info_list)) |
1097 | return; | 1108 | return; |
1098 | head->r.step++; | 1109 | head->r.step++; |
1099 | if (!tomoyo_set_lf(head)) | 1110 | if (!tomoyo_set_lf(head)) |
@@ -1262,6 +1273,14 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1262 | }; | 1273 | }; |
1263 | u8 i; | 1274 | u8 i; |
1264 | param.is_delete = tomoyo_str_starts(¶m.data, "delete "); | 1275 | param.is_delete = tomoyo_str_starts(¶m.data, "delete "); |
1276 | if (!param.is_delete && tomoyo_str_starts(¶m.data, "select ") && | ||
1277 | !strcmp(param.data, "execute_only")) { | ||
1278 | head->r.print_execute_only = true; | ||
1279 | return 0; | ||
1280 | } | ||
1281 | /* Don't allow updating policies by non manager programs. */ | ||
1282 | if (!tomoyo_manager()) | ||
1283 | return -EPERM; | ||
1265 | if (tomoyo_str_starts(¶m.data, "aggregator ")) | 1284 | if (tomoyo_str_starts(¶m.data, "aggregator ")) |
1266 | return tomoyo_write_aggregator(¶m); | 1285 | return tomoyo_write_aggregator(¶m); |
1267 | for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) | 1286 | for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) |
@@ -1270,6 +1289,14 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1270 | for (i = 0; i < TOMOYO_MAX_GROUP; i++) | 1289 | for (i = 0; i < TOMOYO_MAX_GROUP; i++) |
1271 | if (tomoyo_str_starts(¶m.data, tomoyo_group_name[i])) | 1290 | if (tomoyo_str_starts(¶m.data, tomoyo_group_name[i])) |
1272 | return tomoyo_write_group(¶m, i); | 1291 | return tomoyo_write_group(¶m, i); |
1292 | if (tomoyo_str_starts(¶m.data, "acl_group ")) { | ||
1293 | unsigned int group; | ||
1294 | char *data; | ||
1295 | group = simple_strtoul(param.data, &data, 10); | ||
1296 | if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') | ||
1297 | return tomoyo_write_domain2(&tomoyo_acl_group[group], | ||
1298 | data, param.is_delete); | ||
1299 | } | ||
1273 | return -EINVAL; | 1300 | return -EINVAL; |
1274 | } | 1301 | } |
1275 | 1302 | ||
@@ -1392,6 +1419,15 @@ static void tomoyo_read_exception(struct tomoyo_io_buffer *head) | |||
1392 | head->r.step++; | 1419 | head->r.step++; |
1393 | if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) | 1420 | if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) |
1394 | return; | 1421 | return; |
1422 | while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP | ||
1423 | + TOMOYO_MAX_ACL_GROUPS) { | ||
1424 | head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY | ||
1425 | - TOMOYO_MAX_GROUP; | ||
1426 | if (!tomoyo_read_domain2(head, &tomoyo_acl_group | ||
1427 | [head->r.acl_group_index])) | ||
1428 | return; | ||
1429 | head->r.step++; | ||
1430 | } | ||
1395 | head->r.eof = true; | 1431 | head->r.eof = true; |
1396 | } | 1432 | } |
1397 | 1433 | ||
@@ -1914,7 +1950,8 @@ int tomoyo_write_control(struct tomoyo_io_buffer *head, | |||
1914 | return -EFAULT; | 1950 | return -EFAULT; |
1915 | /* Don't allow updating policies by non manager programs. */ | 1951 | /* Don't allow updating policies by non manager programs. */ |
1916 | if (head->write != tomoyo_write_pid && | 1952 | if (head->write != tomoyo_write_pid && |
1917 | head->write != tomoyo_write_domain && !tomoyo_manager()) | 1953 | head->write != tomoyo_write_domain && |
1954 | head->write != tomoyo_write_exception && !tomoyo_manager()) | ||
1918 | return -EPERM; | 1955 | return -EPERM; |
1919 | if (mutex_lock_interruptible(&head->io_sem)) | 1956 | if (mutex_lock_interruptible(&head->io_sem)) |
1920 | return -EINTR; | 1957 | return -EINTR; |