diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-09-10 02:23:54 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-09-13 18:27:05 -0400 |
commit | 059d84dbb3897d4ee494a9c842c5dda54316cb47 (patch) | |
tree | 483ca0cb613b1304184b92f075b3f5283d36c723 /security/tomoyo/common.c | |
parent | d58e0da854376841ac99defeb117a83f086715c6 (diff) |
TOMOYO: Add socket operation restriction support.
This patch adds support for permission checks for PF_INET/PF_INET6/PF_UNIX
socket's bind()/listen()/connect()/send() operations.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 104 |
1 files changed, 98 insertions, 6 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index d116e1ece3e6..85d915587a71 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -44,10 +44,27 @@ const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX | |||
44 | [TOMOYO_MAC_FILE_MOUNT] = "mount", | 44 | [TOMOYO_MAC_FILE_MOUNT] = "mount", |
45 | [TOMOYO_MAC_FILE_UMOUNT] = "unmount", | 45 | [TOMOYO_MAC_FILE_UMOUNT] = "unmount", |
46 | [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", | 46 | [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", |
47 | /* CONFIG::network group */ | ||
48 | [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind", | ||
49 | [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen", | ||
50 | [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect", | ||
51 | [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind", | ||
52 | [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send", | ||
53 | [TOMOYO_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind", | ||
54 | [TOMOYO_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send", | ||
55 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind", | ||
56 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen", | ||
57 | [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect", | ||
58 | [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind", | ||
59 | [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send", | ||
60 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind", | ||
61 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen", | ||
62 | [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect", | ||
47 | /* CONFIG::misc group */ | 63 | /* CONFIG::misc group */ |
48 | [TOMOYO_MAC_ENVIRON] = "env", | 64 | [TOMOYO_MAC_ENVIRON] = "env", |
49 | /* CONFIG group */ | 65 | /* CONFIG group */ |
50 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", | 66 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", |
67 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network", | ||
51 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc", | 68 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc", |
52 | }; | 69 | }; |
53 | 70 | ||
@@ -135,11 +152,20 @@ const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { | |||
135 | [TOMOYO_TYPE_UMOUNT] = "unmount", | 152 | [TOMOYO_TYPE_UMOUNT] = "unmount", |
136 | }; | 153 | }; |
137 | 154 | ||
155 | /* String table for socket's operation. */ | ||
156 | const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = { | ||
157 | [TOMOYO_NETWORK_BIND] = "bind", | ||
158 | [TOMOYO_NETWORK_LISTEN] = "listen", | ||
159 | [TOMOYO_NETWORK_CONNECT] = "connect", | ||
160 | [TOMOYO_NETWORK_SEND] = "send", | ||
161 | }; | ||
162 | |||
138 | /* String table for categories. */ | 163 | /* String table for categories. */ |
139 | static const char * const tomoyo_category_keywords | 164 | static const char * const tomoyo_category_keywords |
140 | [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { | 165 | [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { |
141 | [TOMOYO_MAC_CATEGORY_FILE] = "file", | 166 | [TOMOYO_MAC_CATEGORY_FILE] = "file", |
142 | [TOMOYO_MAC_CATEGORY_MISC] = "misc", | 167 | [TOMOYO_MAC_CATEGORY_NETWORK] = "network", |
168 | [TOMOYO_MAC_CATEGORY_MISC] = "misc", | ||
143 | }; | 169 | }; |
144 | 170 | ||
145 | /* Permit policy management by non-root user? */ | 171 | /* Permit policy management by non-root user? */ |
@@ -1042,8 +1068,10 @@ static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, | |||
1042 | static const struct { | 1068 | static const struct { |
1043 | const char *keyword; | 1069 | const char *keyword; |
1044 | int (*write) (struct tomoyo_acl_param *); | 1070 | int (*write) (struct tomoyo_acl_param *); |
1045 | } tomoyo_callback[2] = { | 1071 | } tomoyo_callback[4] = { |
1046 | { "file ", tomoyo_write_file }, | 1072 | { "file ", tomoyo_write_file }, |
1073 | { "network inet ", tomoyo_write_inet_network }, | ||
1074 | { "network unix ", tomoyo_write_unix_network }, | ||
1047 | { "misc ", tomoyo_write_misc }, | 1075 | { "misc ", tomoyo_write_misc }, |
1048 | }; | 1076 | }; |
1049 | u8 i; | 1077 | u8 i; |
@@ -1375,6 +1403,60 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1375 | tomoyo_print_number_union(head, &ptr->mode); | 1403 | tomoyo_print_number_union(head, &ptr->mode); |
1376 | tomoyo_print_number_union(head, &ptr->major); | 1404 | tomoyo_print_number_union(head, &ptr->major); |
1377 | tomoyo_print_number_union(head, &ptr->minor); | 1405 | tomoyo_print_number_union(head, &ptr->minor); |
1406 | } else if (acl_type == TOMOYO_TYPE_INET_ACL) { | ||
1407 | struct tomoyo_inet_acl *ptr = | ||
1408 | container_of(acl, typeof(*ptr), head); | ||
1409 | const u8 perm = ptr->perm; | ||
1410 | |||
1411 | for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { | ||
1412 | if (!(perm & (1 << bit))) | ||
1413 | continue; | ||
1414 | if (first) { | ||
1415 | tomoyo_set_group(head, "network inet "); | ||
1416 | tomoyo_set_string(head, tomoyo_proto_keyword | ||
1417 | [ptr->protocol]); | ||
1418 | tomoyo_set_space(head); | ||
1419 | first = false; | ||
1420 | } else { | ||
1421 | tomoyo_set_slash(head); | ||
1422 | } | ||
1423 | tomoyo_set_string(head, tomoyo_socket_keyword[bit]); | ||
1424 | } | ||
1425 | if (first) | ||
1426 | return true; | ||
1427 | tomoyo_set_space(head); | ||
1428 | if (ptr->address.group) { | ||
1429 | tomoyo_set_string(head, "@"); | ||
1430 | tomoyo_set_string(head, ptr->address.group->group_name | ||
1431 | ->name); | ||
1432 | } else { | ||
1433 | char buf[128]; | ||
1434 | tomoyo_print_ip(buf, sizeof(buf), &ptr->address); | ||
1435 | tomoyo_io_printf(head, "%s", buf); | ||
1436 | } | ||
1437 | tomoyo_print_number_union(head, &ptr->port); | ||
1438 | } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) { | ||
1439 | struct tomoyo_unix_acl *ptr = | ||
1440 | container_of(acl, typeof(*ptr), head); | ||
1441 | const u8 perm = ptr->perm; | ||
1442 | |||
1443 | for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { | ||
1444 | if (!(perm & (1 << bit))) | ||
1445 | continue; | ||
1446 | if (first) { | ||
1447 | tomoyo_set_group(head, "network unix "); | ||
1448 | tomoyo_set_string(head, tomoyo_proto_keyword | ||
1449 | [ptr->protocol]); | ||
1450 | tomoyo_set_space(head); | ||
1451 | first = false; | ||
1452 | } else { | ||
1453 | tomoyo_set_slash(head); | ||
1454 | } | ||
1455 | tomoyo_set_string(head, tomoyo_socket_keyword[bit]); | ||
1456 | } | ||
1457 | if (first) | ||
1458 | return true; | ||
1459 | tomoyo_print_name_union(head, &ptr->name); | ||
1378 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { | 1460 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { |
1379 | struct tomoyo_mount_acl *ptr = | 1461 | struct tomoyo_mount_acl *ptr = |
1380 | container_of(acl, typeof(*ptr), head); | 1462 | container_of(acl, typeof(*ptr), head); |
@@ -1548,8 +1630,9 @@ static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { | |||
1548 | 1630 | ||
1549 | /* String table for grouping keywords. */ | 1631 | /* String table for grouping keywords. */ |
1550 | static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { | 1632 | static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { |
1551 | [TOMOYO_PATH_GROUP] = "path_group ", | 1633 | [TOMOYO_PATH_GROUP] = "path_group ", |
1552 | [TOMOYO_NUMBER_GROUP] = "number_group ", | 1634 | [TOMOYO_NUMBER_GROUP] = "number_group ", |
1635 | [TOMOYO_ADDRESS_GROUP] = "address_group ", | ||
1553 | }; | 1636 | }; |
1554 | 1637 | ||
1555 | /** | 1638 | /** |
@@ -1591,7 +1674,7 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head) | |||
1591 | } | 1674 | } |
1592 | 1675 | ||
1593 | /** | 1676 | /** |
1594 | * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list. | 1677 | * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list. |
1595 | * | 1678 | * |
1596 | * @head: Pointer to "struct tomoyo_io_buffer". | 1679 | * @head: Pointer to "struct tomoyo_io_buffer". |
1597 | * @idx: Index number. | 1680 | * @idx: Index number. |
@@ -1628,6 +1711,15 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1628 | (ptr, | 1711 | (ptr, |
1629 | struct tomoyo_number_group, | 1712 | struct tomoyo_number_group, |
1630 | head)->number); | 1713 | head)->number); |
1714 | } else if (idx == TOMOYO_ADDRESS_GROUP) { | ||
1715 | char buffer[128]; | ||
1716 | |||
1717 | struct tomoyo_address_group *member = | ||
1718 | container_of(ptr, typeof(*member), | ||
1719 | head); | ||
1720 | tomoyo_print_ip(buffer, sizeof(buffer), | ||
1721 | &member->address); | ||
1722 | tomoyo_io_printf(head, " %s", buffer); | ||
1631 | } | 1723 | } |
1632 | tomoyo_set_lf(head); | 1724 | tomoyo_set_lf(head); |
1633 | } | 1725 | } |