aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-09-10 02:23:54 -0400
committerJames Morris <jmorris@namei.org>2011-09-13 18:27:05 -0400
commit059d84dbb3897d4ee494a9c842c5dda54316cb47 (patch)
tree483ca0cb613b1304184b92f075b3f5283d36c723 /security/tomoyo
parentd58e0da854376841ac99defeb117a83f086715c6 (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')
-rw-r--r--security/tomoyo/Kconfig2
-rw-r--r--security/tomoyo/Makefile2
-rw-r--r--security/tomoyo/common.c104
-rw-r--r--security/tomoyo/common.h127
-rw-r--r--security/tomoyo/gc.c40
-rw-r--r--security/tomoyo/group.c61
-rw-r--r--security/tomoyo/network.c771
-rw-r--r--security/tomoyo/realpath.c32
-rw-r--r--security/tomoyo/tomoyo.c62
-rw-r--r--security/tomoyo/util.c31
10 files changed, 1215 insertions, 17 deletions
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index 7c7f8c16c10f..8eb779b9d77f 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -1,8 +1,10 @@
1config SECURITY_TOMOYO 1config SECURITY_TOMOYO
2 bool "TOMOYO Linux Support" 2 bool "TOMOYO Linux Support"
3 depends on SECURITY 3 depends on SECURITY
4 depends on NET
4 select SECURITYFS 5 select SECURITYFS
5 select SECURITY_PATH 6 select SECURITY_PATH
7 select SECURITY_NETWORK
6 default n 8 default n
7 help 9 help
8 This selects TOMOYO Linux, pathname-based access control. 10 This selects TOMOYO Linux, pathname-based access control.
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index f7ade960f6cf..fc2a8ce40301 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1,4 +1,4 @@
1obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o realpath.o securityfs_if.o tomoyo.o util.o 1obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
2 2
3$(obj)/policy/profile.conf: 3$(obj)/policy/profile.conf:
4 @mkdir -p $(obj)/policy/ 4 @mkdir -p $(obj)/policy/
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. */
156const 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. */
139static const char * const tomoyo_category_keywords 164static 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. */
1550static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1632static 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 }
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 63720a328edd..d1c758e7f92b 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -23,6 +23,16 @@
23#include <linux/poll.h> 23#include <linux/poll.h>
24#include <linux/binfmts.h> 24#include <linux/binfmts.h>
25#include <linux/highmem.h> 25#include <linux/highmem.h>
26#include <linux/net.h>
27#include <linux/inet.h>
28#include <linux/in.h>
29#include <linux/in6.h>
30#include <linux/un.h>
31#include <net/sock.h>
32#include <net/af_unix.h>
33#include <net/ip.h>
34#include <net/ipv6.h>
35#include <net/udp.h>
26 36
27/********** Constants definitions. **********/ 37/********** Constants definitions. **********/
28 38
@@ -34,6 +44,12 @@
34#define TOMOYO_HASH_BITS 8 44#define TOMOYO_HASH_BITS 8
35#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) 45#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
36 46
47/*
48 * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
49 * Therefore, we don't need SOCK_MAX.
50 */
51#define TOMOYO_SOCK_MAX 6
52
37#define TOMOYO_EXEC_TMPSIZE 4096 53#define TOMOYO_EXEC_TMPSIZE 4096
38 54
39/* Profile number is an integer between 0 and 255. */ 55/* Profile number is an integer between 0 and 255. */
@@ -136,6 +152,7 @@ enum tomoyo_mode_index {
136/* Index numbers for entry type. */ 152/* Index numbers for entry type. */
137enum tomoyo_policy_id { 153enum tomoyo_policy_id {
138 TOMOYO_ID_GROUP, 154 TOMOYO_ID_GROUP,
155 TOMOYO_ID_ADDRESS_GROUP,
139 TOMOYO_ID_PATH_GROUP, 156 TOMOYO_ID_PATH_GROUP,
140 TOMOYO_ID_NUMBER_GROUP, 157 TOMOYO_ID_NUMBER_GROUP,
141 TOMOYO_ID_TRANSITION_CONTROL, 158 TOMOYO_ID_TRANSITION_CONTROL,
@@ -166,6 +183,7 @@ enum tomoyo_domain_info_flags_index {
166enum tomoyo_group_id { 183enum tomoyo_group_id {
167 TOMOYO_PATH_GROUP, 184 TOMOYO_PATH_GROUP,
168 TOMOYO_NUMBER_GROUP, 185 TOMOYO_NUMBER_GROUP,
186 TOMOYO_ADDRESS_GROUP,
169 TOMOYO_MAX_GROUP 187 TOMOYO_MAX_GROUP
170}; 188};
171 189
@@ -196,6 +214,8 @@ enum tomoyo_acl_entry_type_index {
196 TOMOYO_TYPE_PATH_NUMBER_ACL, 214 TOMOYO_TYPE_PATH_NUMBER_ACL,
197 TOMOYO_TYPE_MKDEV_ACL, 215 TOMOYO_TYPE_MKDEV_ACL,
198 TOMOYO_TYPE_MOUNT_ACL, 216 TOMOYO_TYPE_MOUNT_ACL,
217 TOMOYO_TYPE_INET_ACL,
218 TOMOYO_TYPE_UNIX_ACL,
199 TOMOYO_TYPE_ENV_ACL, 219 TOMOYO_TYPE_ENV_ACL,
200}; 220};
201 221
@@ -229,6 +249,15 @@ enum tomoyo_mkdev_acl_index {
229 TOMOYO_MAX_MKDEV_OPERATION 249 TOMOYO_MAX_MKDEV_OPERATION
230}; 250};
231 251
252/* Index numbers for socket operations. */
253enum tomoyo_network_acl_index {
254 TOMOYO_NETWORK_BIND, /* bind() operation. */
255 TOMOYO_NETWORK_LISTEN, /* listen() operation. */
256 TOMOYO_NETWORK_CONNECT, /* connect() operation. */
257 TOMOYO_NETWORK_SEND, /* send() operation. */
258 TOMOYO_MAX_NETWORK_OPERATION
259};
260
232/* Index numbers for access controls with two pathnames. */ 261/* Index numbers for access controls with two pathnames. */
233enum tomoyo_path2_acl_index { 262enum tomoyo_path2_acl_index {
234 TOMOYO_TYPE_LINK, 263 TOMOYO_TYPE_LINK,
@@ -301,6 +330,21 @@ enum tomoyo_mac_index {
301 TOMOYO_MAC_FILE_MOUNT, 330 TOMOYO_MAC_FILE_MOUNT,
302 TOMOYO_MAC_FILE_UMOUNT, 331 TOMOYO_MAC_FILE_UMOUNT,
303 TOMOYO_MAC_FILE_PIVOT_ROOT, 332 TOMOYO_MAC_FILE_PIVOT_ROOT,
333 TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
334 TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
335 TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
336 TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
337 TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
338 TOMOYO_MAC_NETWORK_INET_RAW_BIND,
339 TOMOYO_MAC_NETWORK_INET_RAW_SEND,
340 TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
341 TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
342 TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
343 TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
344 TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
345 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
346 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
347 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
304 TOMOYO_MAC_ENVIRON, 348 TOMOYO_MAC_ENVIRON,
305 TOMOYO_MAX_MAC_INDEX 349 TOMOYO_MAX_MAC_INDEX
306}; 350};
@@ -308,6 +352,7 @@ enum tomoyo_mac_index {
308/* Index numbers for category of functionality. */ 352/* Index numbers for category of functionality. */
309enum tomoyo_mac_category_index { 353enum tomoyo_mac_category_index {
310 TOMOYO_MAC_CATEGORY_FILE, 354 TOMOYO_MAC_CATEGORY_FILE,
355 TOMOYO_MAC_CATEGORY_NETWORK,
311 TOMOYO_MAC_CATEGORY_MISC, 356 TOMOYO_MAC_CATEGORY_MISC,
312 TOMOYO_MAX_MAC_CATEGORY_INDEX 357 TOMOYO_MAX_MAC_CATEGORY_INDEX
313}; 358};
@@ -403,6 +448,22 @@ struct tomoyo_request_info {
403 const struct tomoyo_path_info *name; 448 const struct tomoyo_path_info *name;
404 } environ; 449 } environ;
405 struct { 450 struct {
451 const __be32 *address;
452 u16 port;
453 /* One of values smaller than TOMOYO_SOCK_MAX. */
454 u8 protocol;
455 /* One of values in "enum tomoyo_network_acl_index". */
456 u8 operation;
457 bool is_ipv6;
458 } inet_network;
459 struct {
460 const struct tomoyo_path_info *address;
461 /* One of values smaller than TOMOYO_SOCK_MAX. */
462 u8 protocol;
463 /* One of values in "enum tomoyo_network_acl_index". */
464 u8 operation;
465 } unix_network;
466 struct {
406 const struct tomoyo_path_info *type; 467 const struct tomoyo_path_info *type;
407 const struct tomoyo_path_info *dir; 468 const struct tomoyo_path_info *dir;
408 const struct tomoyo_path_info *dev; 469 const struct tomoyo_path_info *dev;
@@ -448,7 +509,14 @@ struct tomoyo_number_union {
448 u8 value_type[2]; 509 u8 value_type[2];
449}; 510};
450 511
451/* Structure for "path_group"/"number_group" directive. */ 512/* Structure for holding an IP address. */
513struct tomoyo_ipaddr_union {
514 struct in6_addr ip[2]; /* Big endian. */
515 struct tomoyo_group *group; /* Pointer to address group. */
516 bool is_ipv6; /* Valid only if @group == NULL. */
517};
518
519/* Structure for "path_group"/"number_group"/"address_group" directive. */
452struct tomoyo_group { 520struct tomoyo_group {
453 struct tomoyo_shared_acl_head head; 521 struct tomoyo_shared_acl_head head;
454 const struct tomoyo_path_info *group_name; 522 const struct tomoyo_path_info *group_name;
@@ -467,6 +535,13 @@ struct tomoyo_number_group {
467 struct tomoyo_number_union number; 535 struct tomoyo_number_union number;
468}; 536};
469 537
538/* Structure for "address_group" directive. */
539struct tomoyo_address_group {
540 struct tomoyo_acl_head head;
541 /* Structure for holding an IP address. */
542 struct tomoyo_ipaddr_union address;
543};
544
470/* Subset of "struct stat". Used by conditional ACL and audit logs. */ 545/* Subset of "struct stat". Used by conditional ACL and audit logs. */
471struct tomoyo_mini_stat { 546struct tomoyo_mini_stat {
472 uid_t uid; 547 uid_t uid;
@@ -650,6 +725,23 @@ struct tomoyo_env_acl {
650 const struct tomoyo_path_info *env; /* environment variable */ 725 const struct tomoyo_path_info *env; /* environment variable */
651}; 726};
652 727
728/* Structure for "network inet" directive. */
729struct tomoyo_inet_acl {
730 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_INET_ACL */
731 u8 protocol;
732 u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
733 struct tomoyo_ipaddr_union address;
734 struct tomoyo_number_union port;
735};
736
737/* Structure for "network unix" directive. */
738struct tomoyo_unix_acl {
739 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_UNIX_ACL */
740 u8 protocol;
741 u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
742 struct tomoyo_name_union name;
743};
744
653/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */ 745/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
654struct tomoyo_acl_param { 746struct tomoyo_acl_param {
655 char *data; 747 char *data;
@@ -793,6 +885,8 @@ struct tomoyo_policy_namespace {
793 885
794/********** Function prototypes. **********/ 886/********** Function prototypes. **********/
795 887
888bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
889 const struct tomoyo_group *group);
796bool tomoyo_compare_number_union(const unsigned long value, 890bool tomoyo_compare_number_union(const unsigned long value,
797 const struct tomoyo_number_union *ptr); 891 const struct tomoyo_number_union *ptr);
798bool tomoyo_condition(struct tomoyo_request_info *r, 892bool tomoyo_condition(struct tomoyo_request_info *r,
@@ -808,6 +902,8 @@ bool tomoyo_memory_ok(void *ptr);
808bool tomoyo_number_matches_group(const unsigned long min, 902bool tomoyo_number_matches_group(const unsigned long min,
809 const unsigned long max, 903 const unsigned long max,
810 const struct tomoyo_group *group); 904 const struct tomoyo_group *group);
905bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
906 struct tomoyo_ipaddr_union *ptr);
811bool tomoyo_parse_name_union(struct tomoyo_acl_param *param, 907bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
812 struct tomoyo_name_union *ptr); 908 struct tomoyo_name_union *ptr);
813bool tomoyo_parse_number_union(struct tomoyo_acl_param *param, 909bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
@@ -817,6 +913,7 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
817bool tomoyo_permstr(const char *string, const char *keyword); 913bool tomoyo_permstr(const char *string, const char *keyword);
818bool tomoyo_str_starts(char **src, const char *find); 914bool tomoyo_str_starts(char **src, const char *find);
819char *tomoyo_encode(const char *str); 915char *tomoyo_encode(const char *str);
916char *tomoyo_encode2(const char *str, int str_len);
820char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, 917char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
821 va_list args); 918 va_list args);
822char *tomoyo_read_token(struct tomoyo_acl_param *param); 919char *tomoyo_read_token(struct tomoyo_acl_param *param);
@@ -855,6 +952,13 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
855 const struct tomoyo_path_info *filename); 952 const struct tomoyo_path_info *filename);
856int tomoyo_poll_control(struct file *file, poll_table *wait); 953int tomoyo_poll_control(struct file *file, poll_table *wait);
857int tomoyo_poll_log(struct file *file, poll_table *wait); 954int tomoyo_poll_log(struct file *file, poll_table *wait);
955int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
956 int addr_len);
957int tomoyo_socket_connect_permission(struct socket *sock,
958 struct sockaddr *addr, int addr_len);
959int tomoyo_socket_listen_permission(struct socket *sock);
960int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
961 int size);
858int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 962int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
859 __printf(2, 3); 963 __printf(2, 3);
860int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 964int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
@@ -874,8 +978,10 @@ int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
874int tomoyo_write_file(struct tomoyo_acl_param *param); 978int tomoyo_write_file(struct tomoyo_acl_param *param);
875int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type); 979int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
876int tomoyo_write_misc(struct tomoyo_acl_param *param); 980int tomoyo_write_misc(struct tomoyo_acl_param *param);
981int tomoyo_write_inet_network(struct tomoyo_acl_param *param);
877int tomoyo_write_transition_control(struct tomoyo_acl_param *param, 982int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
878 const u8 type); 983 const u8 type);
984int tomoyo_write_unix_network(struct tomoyo_acl_param *param);
879ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, 985ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
880 const int buffer_len); 986 const int buffer_len);
881ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, 987ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
@@ -911,6 +1017,8 @@ void tomoyo_load_policy(const char *filename);
911void tomoyo_memory_free(void *ptr); 1017void tomoyo_memory_free(void *ptr);
912void tomoyo_normalize_line(unsigned char *buffer); 1018void tomoyo_normalize_line(unsigned char *buffer);
913void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register); 1019void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
1020void tomoyo_print_ip(char *buf, const unsigned int size,
1021 const struct tomoyo_ipaddr_union *ptr);
914void tomoyo_print_ulong(char *buffer, const int buffer_len, 1022void tomoyo_print_ulong(char *buffer, const int buffer_len,
915 const unsigned long value, const u8 type); 1023 const unsigned long value, const u8 type);
916void tomoyo_put_name_union(struct tomoyo_name_union *ptr); 1024void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
@@ -933,6 +1041,8 @@ extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
933 + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 1041 + TOMOYO_MAX_MAC_CATEGORY_INDEX];
934extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE]; 1042extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE];
935extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 1043extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
1044extern const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX];
1045extern const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION];
936extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX]; 1046extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX];
937extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION]; 1047extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION];
938extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION]; 1048extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION];
@@ -1112,6 +1222,21 @@ static inline bool tomoyo_same_number_union
1112} 1222}
1113 1223
1114/** 1224/**
1225 * tomoyo_same_ipaddr_union - Check for duplicated "struct tomoyo_ipaddr_union" entry.
1226 *
1227 * @a: Pointer to "struct tomoyo_ipaddr_union".
1228 * @b: Pointer to "struct tomoyo_ipaddr_union".
1229 *
1230 * Returns true if @a == @b, false otherwise.
1231 */
1232static inline bool tomoyo_same_ipaddr_union
1233(const struct tomoyo_ipaddr_union *a, const struct tomoyo_ipaddr_union *b)
1234{
1235 return !memcmp(a->ip, b->ip, sizeof(a->ip)) && a->group == b->group &&
1236 a->is_ipv6 == b->is_ipv6;
1237}
1238
1239/**
1115 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread. 1240 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
1116 * 1241 *
1117 * Returns pointer to "struct tomoyo_policy_namespace" for current thread. 1242 * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 818b07998111..7747ceb9a221 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -16,6 +16,7 @@ static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
16/* Size of an element. */ 16/* Size of an element. */
17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = { 17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group), 18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
19 [TOMOYO_ID_ADDRESS_GROUP] = sizeof(struct tomoyo_address_group),
19 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group), 20 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
20 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group), 21 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
21 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator), 22 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
@@ -36,6 +37,8 @@ static const u8 tomoyo_acl_size[] = {
36 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl), 37 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
37 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl), 38 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
38 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl), 39 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
40 [TOMOYO_TYPE_INET_ACL] = sizeof(struct tomoyo_inet_acl),
41 [TOMOYO_TYPE_UNIX_ACL] = sizeof(struct tomoyo_unix_acl),
39 [TOMOYO_TYPE_ENV_ACL] = sizeof(struct tomoyo_env_acl), 42 [TOMOYO_TYPE_ENV_ACL] = sizeof(struct tomoyo_env_acl),
40}; 43};
41 44
@@ -302,6 +305,23 @@ static void tomoyo_del_acl(struct list_head *element)
302 tomoyo_put_name(entry->env); 305 tomoyo_put_name(entry->env);
303 } 306 }
304 break; 307 break;
308 case TOMOYO_TYPE_INET_ACL:
309 {
310 struct tomoyo_inet_acl *entry =
311 container_of(acl, typeof(*entry), head);
312
313 tomoyo_put_group(entry->address.group);
314 tomoyo_put_number_union(&entry->port);
315 }
316 break;
317 case TOMOYO_TYPE_UNIX_ACL:
318 {
319 struct tomoyo_unix_acl *entry =
320 container_of(acl, typeof(*entry), head);
321
322 tomoyo_put_name_union(&entry->name);
323 }
324 break;
305 } 325 }
306} 326}
307 327
@@ -431,6 +451,18 @@ static void tomoyo_del_group(struct list_head *element)
431} 451}
432 452
433/** 453/**
454 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
455 *
456 * @element: Pointer to "struct list_head".
457 *
458 * Returns nothing.
459 */
460static inline void tomoyo_del_address_group(struct list_head *element)
461{
462 /* Nothing to do. */
463}
464
465/**
434 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group". 466 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
435 * 467 *
436 * @element: Pointer to "struct list_head". 468 * @element: Pointer to "struct list_head".
@@ -527,9 +559,12 @@ static void tomoyo_collect_entry(void)
527 case 0: 559 case 0:
528 id = TOMOYO_ID_PATH_GROUP; 560 id = TOMOYO_ID_PATH_GROUP;
529 break; 561 break;
530 default: 562 case 1:
531 id = TOMOYO_ID_NUMBER_GROUP; 563 id = TOMOYO_ID_NUMBER_GROUP;
532 break; 564 break;
565 default:
566 id = TOMOYO_ID_ADDRESS_GROUP;
567 break;
533 } 568 }
534 list_for_each_entry(group, list, head.list) { 569 list_for_each_entry(group, list, head.list) {
535 if (!tomoyo_collect_member 570 if (!tomoyo_collect_member
@@ -634,6 +669,9 @@ static bool tomoyo_kfree_entry(void)
634 case TOMOYO_ID_PATH_GROUP: 669 case TOMOYO_ID_PATH_GROUP:
635 tomoyo_del_path_group(element); 670 tomoyo_del_path_group(element);
636 break; 671 break;
672 case TOMOYO_ID_ADDRESS_GROUP:
673 tomoyo_del_address_group(element);
674 break;
637 case TOMOYO_ID_GROUP: 675 case TOMOYO_ID_GROUP:
638 tomoyo_del_group(element); 676 tomoyo_del_group(element);
639 break; 677 break;
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index 5fb0e1298400..50092534ec54 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -42,7 +42,26 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
42} 42}
43 43
44/** 44/**
45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 45 * tomoyo_same_address_group - Check for duplicated "struct tomoyo_address_group" entry.
46 *
47 * @a: Pointer to "struct tomoyo_acl_head".
48 * @b: Pointer to "struct tomoyo_acl_head".
49 *
50 * Returns true if @a == @b, false otherwise.
51 */
52static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a,
53 const struct tomoyo_acl_head *b)
54{
55 const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1),
56 head);
57 const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2),
58 head);
59
60 return tomoyo_same_ipaddr_union(&p1->address, &p2->address);
61}
62
63/**
64 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
46 * 65 *
47 * @param: Pointer to "struct tomoyo_acl_param". 66 * @param: Pointer to "struct tomoyo_acl_param".
48 * @type: Type of this group. 67 * @type: Type of this group.
@@ -77,6 +96,14 @@ int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
77 * tomoyo_put_number_union() is not needed because 96 * tomoyo_put_number_union() is not needed because
78 * param->data[0] != '@'. 97 * param->data[0] != '@'.
79 */ 98 */
99 } else {
100 struct tomoyo_address_group e = { };
101
102 if (param->data[0] == '@' ||
103 !tomoyo_parse_ipaddr_union(param, &e.address))
104 goto out;
105 error = tomoyo_update_policy(&e.head, sizeof(e), param,
106 tomoyo_same_address_group);
80 } 107 }
81out: 108out:
82 tomoyo_put_group(group); 109 tomoyo_put_group(group);
@@ -137,3 +164,35 @@ bool tomoyo_number_matches_group(const unsigned long min,
137 } 164 }
138 return matched; 165 return matched;
139} 166}
167
168/**
169 * tomoyo_address_matches_group - Check whether the given address matches members of the given address group.
170 *
171 * @is_ipv6: True if @address is an IPv6 address.
172 * @address: An IPv4 or IPv6 address.
173 * @group: Pointer to "struct tomoyo_address_group".
174 *
175 * Returns true if @address matches addresses in @group group, false otherwise.
176 *
177 * Caller holds tomoyo_read_lock().
178 */
179bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
180 const struct tomoyo_group *group)
181{
182 struct tomoyo_address_group *member;
183 bool matched = false;
184 const u8 size = is_ipv6 ? 16 : 4;
185
186 list_for_each_entry_rcu(member, &group->member_list, head.list) {
187 if (member->head.is_deleted)
188 continue;
189 if (member->address.is_ipv6 != is_ipv6)
190 continue;
191 if (memcmp(&member->address.ip[0], address, size) > 0 ||
192 memcmp(address, &member->address.ip[1], size) > 0)
193 continue;
194 matched = true;
195 break;
196 }
197 return matched;
198}
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c
new file mode 100644
index 000000000000..97527710a72a
--- /dev/null
+++ b/security/tomoyo/network.c
@@ -0,0 +1,771 @@
1/*
2 * security/tomoyo/network.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/* Structure for holding inet domain socket's address. */
11struct tomoyo_inet_addr_info {
12 __be16 port; /* In network byte order. */
13 const __be32 *address; /* In network byte order. */
14 bool is_ipv6;
15};
16
17/* Structure for holding unix domain socket's address. */
18struct tomoyo_unix_addr_info {
19 u8 *addr; /* This may not be '\0' terminated string. */
20 unsigned int addr_len;
21};
22
23/* Structure for holding socket address. */
24struct tomoyo_addr_info {
25 u8 protocol;
26 u8 operation;
27 struct tomoyo_inet_addr_info inet;
28 struct tomoyo_unix_addr_info unix0;
29};
30
31/* String table for socket's protocols. */
32const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX] = {
33 [SOCK_STREAM] = "stream",
34 [SOCK_DGRAM] = "dgram",
35 [SOCK_RAW] = "raw",
36 [SOCK_SEQPACKET] = "seqpacket",
37 [0] = " ", /* Dummy for avoiding NULL pointer dereference. */
38 [4] = " ", /* Dummy for avoiding NULL pointer dereference. */
39};
40
41/**
42 * tomoyo_parse_ipaddr_union - Parse an IP address.
43 *
44 * @param: Pointer to "struct tomoyo_acl_param".
45 * @ptr: Pointer to "struct tomoyo_ipaddr_union".
46 *
47 * Returns true on success, false otherwise.
48 */
49bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
50 struct tomoyo_ipaddr_union *ptr)
51{
52 u8 * const min = ptr->ip[0].in6_u.u6_addr8;
53 u8 * const max = ptr->ip[1].in6_u.u6_addr8;
54 char *address = tomoyo_read_token(param);
55 const char *end;
56
57 if (!strchr(address, ':') &&
58 in4_pton(address, -1, min, '-', &end) > 0) {
59 ptr->is_ipv6 = false;
60 if (!*end)
61 ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
62 else if (*end++ != '-' ||
63 in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
64 return false;
65 return true;
66 }
67 if (in6_pton(address, -1, min, '-', &end) > 0) {
68 ptr->is_ipv6 = true;
69 if (!*end)
70 memmove(max, min, sizeof(u16) * 8);
71 else if (*end++ != '-' ||
72 in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
73 return false;
74 return true;
75 }
76 return false;
77}
78
79/**
80 * tomoyo_print_ipv4 - Print an IPv4 address.
81 *
82 * @buffer: Buffer to write to.
83 * @buffer_len: Size of @buffer.
84 * @min_ip: Pointer to __be32.
85 * @max_ip: Pointer to __be32.
86 *
87 * Returns nothing.
88 */
89static void tomoyo_print_ipv4(char *buffer, const unsigned int buffer_len,
90 const __be32 *min_ip, const __be32 *max_ip)
91{
92 snprintf(buffer, buffer_len, "%pI4%c%pI4", min_ip,
93 *min_ip == *max_ip ? '\0' : '-', max_ip);
94}
95
96/**
97 * tomoyo_print_ipv6 - Print an IPv6 address.
98 *
99 * @buffer: Buffer to write to.
100 * @buffer_len: Size of @buffer.
101 * @min_ip: Pointer to "struct in6_addr".
102 * @max_ip: Pointer to "struct in6_addr".
103 *
104 * Returns nothing.
105 */
106static void tomoyo_print_ipv6(char *buffer, const unsigned int buffer_len,
107 const struct in6_addr *min_ip,
108 const struct in6_addr *max_ip)
109{
110 snprintf(buffer, buffer_len, "%pI6c%c%pI6c", min_ip,
111 !memcmp(min_ip, max_ip, 16) ? '\0' : '-', max_ip);
112}
113
114/**
115 * tomoyo_print_ip - Print an IP address.
116 *
117 * @buf: Buffer to write to.
118 * @size: Size of @buf.
119 * @ptr: Pointer to "struct ipaddr_union".
120 *
121 * Returns nothing.
122 */
123void tomoyo_print_ip(char *buf, const unsigned int size,
124 const struct tomoyo_ipaddr_union *ptr)
125{
126 if (ptr->is_ipv6)
127 tomoyo_print_ipv6(buf, size, &ptr->ip[0], &ptr->ip[1]);
128 else
129 tomoyo_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0],
130 &ptr->ip[1].s6_addr32[0]);
131}
132
133/*
134 * Mapping table from "enum tomoyo_network_acl_index" to
135 * "enum tomoyo_mac_index" for inet domain socket.
136 */
137static const u8 tomoyo_inet2mac
138[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
139 [SOCK_STREAM] = {
140 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
141 [TOMOYO_NETWORK_LISTEN] =
142 TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
143 [TOMOYO_NETWORK_CONNECT] =
144 TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
145 },
146 [SOCK_DGRAM] = {
147 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
148 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
149 },
150 [SOCK_RAW] = {
151 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_RAW_BIND,
152 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_RAW_SEND,
153 },
154};
155
156/*
157 * Mapping table from "enum tomoyo_network_acl_index" to
158 * "enum tomoyo_mac_index" for unix domain socket.
159 */
160static const u8 tomoyo_unix2mac
161[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
162 [SOCK_STREAM] = {
163 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
164 [TOMOYO_NETWORK_LISTEN] =
165 TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
166 [TOMOYO_NETWORK_CONNECT] =
167 TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
168 },
169 [SOCK_DGRAM] = {
170 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
171 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
172 },
173 [SOCK_SEQPACKET] = {
174 [TOMOYO_NETWORK_BIND] =
175 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
176 [TOMOYO_NETWORK_LISTEN] =
177 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
178 [TOMOYO_NETWORK_CONNECT] =
179 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
180 },
181};
182
183/**
184 * tomoyo_same_inet_acl - Check for duplicated "struct tomoyo_inet_acl" entry.
185 *
186 * @a: Pointer to "struct tomoyo_acl_info".
187 * @b: Pointer to "struct tomoyo_acl_info".
188 *
189 * Returns true if @a == @b except permission bits, false otherwise.
190 */
191static bool tomoyo_same_inet_acl(const struct tomoyo_acl_info *a,
192 const struct tomoyo_acl_info *b)
193{
194 const struct tomoyo_inet_acl *p1 = container_of(a, typeof(*p1), head);
195 const struct tomoyo_inet_acl *p2 = container_of(b, typeof(*p2), head);
196
197 return p1->protocol == p2->protocol &&
198 tomoyo_same_ipaddr_union(&p1->address, &p2->address) &&
199 tomoyo_same_number_union(&p1->port, &p2->port);
200}
201
202/**
203 * tomoyo_same_unix_acl - Check for duplicated "struct tomoyo_unix_acl" entry.
204 *
205 * @a: Pointer to "struct tomoyo_acl_info".
206 * @b: Pointer to "struct tomoyo_acl_info".
207 *
208 * Returns true if @a == @b except permission bits, false otherwise.
209 */
210static bool tomoyo_same_unix_acl(const struct tomoyo_acl_info *a,
211 const struct tomoyo_acl_info *b)
212{
213 const struct tomoyo_unix_acl *p1 = container_of(a, typeof(*p1), head);
214 const struct tomoyo_unix_acl *p2 = container_of(b, typeof(*p2), head);
215
216 return p1->protocol == p2->protocol &&
217 tomoyo_same_name_union(&p1->name, &p2->name);
218}
219
220/**
221 * tomoyo_merge_inet_acl - Merge duplicated "struct tomoyo_inet_acl" entry.
222 *
223 * @a: Pointer to "struct tomoyo_acl_info".
224 * @b: Pointer to "struct tomoyo_acl_info".
225 * @is_delete: True for @a &= ~@b, false for @a |= @b.
226 *
227 * Returns true if @a is empty, false otherwise.
228 */
229static bool tomoyo_merge_inet_acl(struct tomoyo_acl_info *a,
230 struct tomoyo_acl_info *b,
231 const bool is_delete)
232{
233 u8 * const a_perm =
234 &container_of(a, struct tomoyo_inet_acl, head)->perm;
235 u8 perm = *a_perm;
236 const u8 b_perm = container_of(b, struct tomoyo_inet_acl, head)->perm;
237
238 if (is_delete)
239 perm &= ~b_perm;
240 else
241 perm |= b_perm;
242 *a_perm = perm;
243 return !perm;
244}
245
246/**
247 * tomoyo_merge_unix_acl - Merge duplicated "struct tomoyo_unix_acl" entry.
248 *
249 * @a: Pointer to "struct tomoyo_acl_info".
250 * @b: Pointer to "struct tomoyo_acl_info".
251 * @is_delete: True for @a &= ~@b, false for @a |= @b.
252 *
253 * Returns true if @a is empty, false otherwise.
254 */
255static bool tomoyo_merge_unix_acl(struct tomoyo_acl_info *a,
256 struct tomoyo_acl_info *b,
257 const bool is_delete)
258{
259 u8 * const a_perm =
260 &container_of(a, struct tomoyo_unix_acl, head)->perm;
261 u8 perm = *a_perm;
262 const u8 b_perm = container_of(b, struct tomoyo_unix_acl, head)->perm;
263
264 if (is_delete)
265 perm &= ~b_perm;
266 else
267 perm |= b_perm;
268 *a_perm = perm;
269 return !perm;
270}
271
272/**
273 * tomoyo_write_inet_network - Write "struct tomoyo_inet_acl" list.
274 *
275 * @param: Pointer to "struct tomoyo_acl_param".
276 *
277 * Returns 0 on success, negative value otherwise.
278 *
279 * Caller holds tomoyo_read_lock().
280 */
281int tomoyo_write_inet_network(struct tomoyo_acl_param *param)
282{
283 struct tomoyo_inet_acl e = { .head.type = TOMOYO_TYPE_INET_ACL };
284 int error = -EINVAL;
285 u8 type;
286 const char *protocol = tomoyo_read_token(param);
287 const char *operation = tomoyo_read_token(param);
288
289 for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
290 if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
291 break;
292 for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
293 if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
294 e.perm |= 1 << type;
295 if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
296 return -EINVAL;
297 if (param->data[0] == '@') {
298 param->data++;
299 e.address.group =
300 tomoyo_get_group(param, TOMOYO_ADDRESS_GROUP);
301 if (!e.address.group)
302 return -ENOMEM;
303 } else {
304 if (!tomoyo_parse_ipaddr_union(param, &e.address))
305 goto out;
306 }
307 if (!tomoyo_parse_number_union(param, &e.port) ||
308 e.port.values[1] > 65535)
309 goto out;
310 error = tomoyo_update_domain(&e.head, sizeof(e), param,
311 tomoyo_same_inet_acl,
312 tomoyo_merge_inet_acl);
313out:
314 tomoyo_put_group(e.address.group);
315 tomoyo_put_number_union(&e.port);
316 return error;
317}
318
319/**
320 * tomoyo_write_unix_network - Write "struct tomoyo_unix_acl" list.
321 *
322 * @param: Pointer to "struct tomoyo_acl_param".
323 *
324 * Returns 0 on success, negative value otherwise.
325 */
326int tomoyo_write_unix_network(struct tomoyo_acl_param *param)
327{
328 struct tomoyo_unix_acl e = { .head.type = TOMOYO_TYPE_UNIX_ACL };
329 int error;
330 u8 type;
331 const char *protocol = tomoyo_read_token(param);
332 const char *operation = tomoyo_read_token(param);
333
334 for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
335 if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
336 break;
337 for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
338 if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
339 e.perm |= 1 << type;
340 if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
341 return -EINVAL;
342 if (!tomoyo_parse_name_union(param, &e.name))
343 return -EINVAL;
344 error = tomoyo_update_domain(&e.head, sizeof(e), param,
345 tomoyo_same_unix_acl,
346 tomoyo_merge_unix_acl);
347 tomoyo_put_name_union(&e.name);
348 return error;
349}
350
351/**
352 * tomoyo_audit_net_log - Audit network log.
353 *
354 * @r: Pointer to "struct tomoyo_request_info".
355 * @family: Name of socket family ("inet" or "unix").
356 * @protocol: Name of protocol in @family.
357 * @operation: Name of socket operation.
358 * @address: Name of address.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
362static int tomoyo_audit_net_log(struct tomoyo_request_info *r,
363 const char *family, const u8 protocol,
364 const u8 operation, const char *address)
365{
366 return tomoyo_supervisor(r, "network %s %s %s %s\n", family,
367 tomoyo_proto_keyword[protocol],
368 tomoyo_socket_keyword[operation], address);
369}
370
371/**
372 * tomoyo_audit_inet_log - Audit INET network log.
373 *
374 * @r: Pointer to "struct tomoyo_request_info".
375 *
376 * Returns 0 on success, negative value otherwise.
377 */
378static int tomoyo_audit_inet_log(struct tomoyo_request_info *r)
379{
380 char buf[128];
381 int len;
382 const __be32 *address = r->param.inet_network.address;
383
384 if (r->param.inet_network.is_ipv6)
385 tomoyo_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
386 address, (const struct in6_addr *) address);
387 else
388 tomoyo_print_ipv4(buf, sizeof(buf), address, address);
389 len = strlen(buf);
390 snprintf(buf + len, sizeof(buf) - len, " %u",
391 r->param.inet_network.port);
392 return tomoyo_audit_net_log(r, "inet", r->param.inet_network.protocol,
393 r->param.inet_network.operation, buf);
394}
395
396/**
397 * tomoyo_audit_unix_log - Audit UNIX network log.
398 *
399 * @r: Pointer to "struct tomoyo_request_info".
400 *
401 * Returns 0 on success, negative value otherwise.
402 */
403static int tomoyo_audit_unix_log(struct tomoyo_request_info *r)
404{
405 return tomoyo_audit_net_log(r, "unix", r->param.unix_network.protocol,
406 r->param.unix_network.operation,
407 r->param.unix_network.address->name);
408}
409
410/**
411 * tomoyo_check_inet_acl - Check permission for inet domain socket operation.
412 *
413 * @r: Pointer to "struct tomoyo_request_info".
414 * @ptr: Pointer to "struct tomoyo_acl_info".
415 *
416 * Returns true if granted, false otherwise.
417 */
418static bool tomoyo_check_inet_acl(struct tomoyo_request_info *r,
419 const struct tomoyo_acl_info *ptr)
420{
421 const struct tomoyo_inet_acl *acl =
422 container_of(ptr, typeof(*acl), head);
423 const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
424
425 if (!(acl->perm & (1 << r->param.inet_network.operation)) ||
426 !tomoyo_compare_number_union(r->param.inet_network.port,
427 &acl->port))
428 return false;
429 if (acl->address.group)
430 return tomoyo_address_matches_group
431 (r->param.inet_network.is_ipv6,
432 r->param.inet_network.address, acl->address.group);
433 return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
434 memcmp(&acl->address.ip[0],
435 r->param.inet_network.address, size) <= 0 &&
436 memcmp(r->param.inet_network.address,
437 &acl->address.ip[1], size) <= 0;
438}
439
440/**
441 * tomoyo_check_unix_acl - Check permission for unix domain socket operation.
442 *
443 * @r: Pointer to "struct tomoyo_request_info".
444 * @ptr: Pointer to "struct tomoyo_acl_info".
445 *
446 * Returns true if granted, false otherwise.
447 */
448static bool tomoyo_check_unix_acl(struct tomoyo_request_info *r,
449 const struct tomoyo_acl_info *ptr)
450{
451 const struct tomoyo_unix_acl *acl =
452 container_of(ptr, typeof(*acl), head);
453
454 return (acl->perm & (1 << r->param.unix_network.operation)) &&
455 tomoyo_compare_name_union(r->param.unix_network.address,
456 &acl->name);
457}
458
459/**
460 * tomoyo_inet_entry - Check permission for INET network operation.
461 *
462 * @address: Pointer to "struct tomoyo_addr_info".
463 *
464 * Returns 0 on success, negative value otherwise.
465 */
466static int tomoyo_inet_entry(const struct tomoyo_addr_info *address)
467{
468 const int idx = tomoyo_read_lock();
469 struct tomoyo_request_info r;
470 int error = 0;
471 const u8 type = tomoyo_inet2mac[address->protocol][address->operation];
472
473 if (type && tomoyo_init_request_info(&r, NULL, type)
474 != TOMOYO_CONFIG_DISABLED) {
475 r.param_type = TOMOYO_TYPE_INET_ACL;
476 r.param.inet_network.protocol = address->protocol;
477 r.param.inet_network.operation = address->operation;
478 r.param.inet_network.is_ipv6 = address->inet.is_ipv6;
479 r.param.inet_network.address = address->inet.address;
480 r.param.inet_network.port = ntohs(address->inet.port);
481 do {
482 tomoyo_check_acl(&r, tomoyo_check_inet_acl);
483 error = tomoyo_audit_inet_log(&r);
484 } while (error == TOMOYO_RETRY_REQUEST);
485 }
486 tomoyo_read_unlock(idx);
487 return error;
488}
489
490/**
491 * tomoyo_check_inet_address - Check permission for inet domain socket's operation.
492 *
493 * @addr: Pointer to "struct sockaddr".
494 * @addr_len: Size of @addr.
495 * @port: Port number.
496 * @address: Pointer to "struct tomoyo_addr_info".
497 *
498 * Returns 0 on success, negative value otherwise.
499 */
500static int tomoyo_check_inet_address(const struct sockaddr *addr,
501 const unsigned int addr_len,
502 const u16 port,
503 struct tomoyo_addr_info *address)
504{
505 struct tomoyo_inet_addr_info *i = &address->inet;
506
507 switch (addr->sa_family) {
508 case AF_INET6:
509 if (addr_len < SIN6_LEN_RFC2133)
510 goto skip;
511 i->is_ipv6 = true;
512 i->address = (__be32 *)
513 ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
514 i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
515 break;
516 case AF_INET:
517 if (addr_len < sizeof(struct sockaddr_in))
518 goto skip;
519 i->is_ipv6 = false;
520 i->address = (__be32 *)
521 &((struct sockaddr_in *) addr)->sin_addr;
522 i->port = ((struct sockaddr_in *) addr)->sin_port;
523 break;
524 default:
525 goto skip;
526 }
527 if (address->protocol == SOCK_RAW)
528 i->port = htons(port);
529 return tomoyo_inet_entry(address);
530skip:
531 return 0;
532}
533
534/**
535 * tomoyo_unix_entry - Check permission for UNIX network operation.
536 *
537 * @address: Pointer to "struct tomoyo_addr_info".
538 *
539 * Returns 0 on success, negative value otherwise.
540 */
541static int tomoyo_unix_entry(const struct tomoyo_addr_info *address)
542{
543 const int idx = tomoyo_read_lock();
544 struct tomoyo_request_info r;
545 int error = 0;
546 const u8 type = tomoyo_unix2mac[address->protocol][address->operation];
547
548 if (type && tomoyo_init_request_info(&r, NULL, type)
549 != TOMOYO_CONFIG_DISABLED) {
550 char *buf = address->unix0.addr;
551 int len = address->unix0.addr_len - sizeof(sa_family_t);
552
553 if (len <= 0) {
554 buf = "anonymous";
555 len = 9;
556 } else if (buf[0]) {
557 len = strnlen(buf, len);
558 }
559 buf = tomoyo_encode2(buf, len);
560 if (buf) {
561 struct tomoyo_path_info addr;
562
563 addr.name = buf;
564 tomoyo_fill_path_info(&addr);
565 r.param_type = TOMOYO_TYPE_UNIX_ACL;
566 r.param.unix_network.protocol = address->protocol;
567 r.param.unix_network.operation = address->operation;
568 r.param.unix_network.address = &addr;
569 do {
570 tomoyo_check_acl(&r, tomoyo_check_unix_acl);
571 error = tomoyo_audit_unix_log(&r);
572 } while (error == TOMOYO_RETRY_REQUEST);
573 kfree(buf);
574 } else
575 error = -ENOMEM;
576 }
577 tomoyo_read_unlock(idx);
578 return error;
579}
580
581/**
582 * tomoyo_check_unix_address - Check permission for unix domain socket's operation.
583 *
584 * @addr: Pointer to "struct sockaddr".
585 * @addr_len: Size of @addr.
586 * @address: Pointer to "struct tomoyo_addr_info".
587 *
588 * Returns 0 on success, negative value otherwise.
589 */
590static int tomoyo_check_unix_address(struct sockaddr *addr,
591 const unsigned int addr_len,
592 struct tomoyo_addr_info *address)
593{
594 struct tomoyo_unix_addr_info *u = &address->unix0;
595
596 if (addr->sa_family != AF_UNIX)
597 return 0;
598 u->addr = ((struct sockaddr_un *) addr)->sun_path;
599 u->addr_len = addr_len;
600 return tomoyo_unix_entry(address);
601}
602
603/**
604 * tomoyo_kernel_service - Check whether I'm kernel service or not.
605 *
606 * Returns true if I'm kernel service, false otherwise.
607 */
608static bool tomoyo_kernel_service(void)
609{
610 /* Nothing to do if I am a kernel service. */
611 return segment_eq(get_fs(), KERNEL_DS);
612}
613
614/**
615 * tomoyo_sock_family - Get socket's family.
616 *
617 * @sk: Pointer to "struct sock".
618 *
619 * Returns one of PF_INET, PF_INET6, PF_UNIX or 0.
620 */
621static u8 tomoyo_sock_family(struct sock *sk)
622{
623 u8 family;
624
625 if (tomoyo_kernel_service())
626 return 0;
627 family = sk->sk_family;
628 switch (family) {
629 case PF_INET:
630 case PF_INET6:
631 case PF_UNIX:
632 return family;
633 default:
634 return 0;
635 }
636}
637
638/**
639 * tomoyo_socket_listen_permission - Check permission for listening a socket.
640 *
641 * @sock: Pointer to "struct socket".
642 *
643 * Returns 0 on success, negative value otherwise.
644 */
645int tomoyo_socket_listen_permission(struct socket *sock)
646{
647 struct tomoyo_addr_info address;
648 const u8 family = tomoyo_sock_family(sock->sk);
649 const unsigned int type = sock->type;
650 struct sockaddr_storage addr;
651 int addr_len;
652
653 if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
654 return 0;
655 {
656 const int error = sock->ops->getname(sock, (struct sockaddr *)
657 &addr, &addr_len, 0);
658
659 if (error)
660 return error;
661 }
662 address.protocol = type;
663 address.operation = TOMOYO_NETWORK_LISTEN;
664 if (family == PF_UNIX)
665 return tomoyo_check_unix_address((struct sockaddr *) &addr,
666 addr_len, &address);
667 return tomoyo_check_inet_address((struct sockaddr *) &addr, addr_len,
668 0, &address);
669}
670
671/**
672 * tomoyo_socket_connect_permission - Check permission for setting the remote address of a socket.
673 *
674 * @sock: Pointer to "struct socket".
675 * @addr: Pointer to "struct sockaddr".
676 * @addr_len: Size of @addr.
677 *
678 * Returns 0 on success, negative value otherwise.
679 */
680int tomoyo_socket_connect_permission(struct socket *sock,
681 struct sockaddr *addr, int addr_len)
682{
683 struct tomoyo_addr_info address;
684 const u8 family = tomoyo_sock_family(sock->sk);
685 const unsigned int type = sock->type;
686
687 if (!family)
688 return 0;
689 address.protocol = type;
690 switch (type) {
691 case SOCK_DGRAM:
692 case SOCK_RAW:
693 address.operation = TOMOYO_NETWORK_SEND;
694 break;
695 case SOCK_STREAM:
696 case SOCK_SEQPACKET:
697 address.operation = TOMOYO_NETWORK_CONNECT;
698 break;
699 default:
700 return 0;
701 }
702 if (family == PF_UNIX)
703 return tomoyo_check_unix_address(addr, addr_len, &address);
704 return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
705 &address);
706}
707
708/**
709 * tomoyo_socket_bind_permission - Check permission for setting the local address of a socket.
710 *
711 * @sock: Pointer to "struct socket".
712 * @addr: Pointer to "struct sockaddr".
713 * @addr_len: Size of @addr.
714 *
715 * Returns 0 on success, negative value otherwise.
716 */
717int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
718 int addr_len)
719{
720 struct tomoyo_addr_info address;
721 const u8 family = tomoyo_sock_family(sock->sk);
722 const unsigned int type = sock->type;
723
724 if (!family)
725 return 0;
726 switch (type) {
727 case SOCK_STREAM:
728 case SOCK_DGRAM:
729 case SOCK_RAW:
730 case SOCK_SEQPACKET:
731 address.protocol = type;
732 address.operation = TOMOYO_NETWORK_BIND;
733 break;
734 default:
735 return 0;
736 }
737 if (family == PF_UNIX)
738 return tomoyo_check_unix_address(addr, addr_len, &address);
739 return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
740 &address);
741}
742
743/**
744 * tomoyo_socket_sendmsg_permission - Check permission for sending a datagram.
745 *
746 * @sock: Pointer to "struct socket".
747 * @msg: Pointer to "struct msghdr".
748 * @size: Unused.
749 *
750 * Returns 0 on success, negative value otherwise.
751 */
752int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
753 int size)
754{
755 struct tomoyo_addr_info address;
756 const u8 family = tomoyo_sock_family(sock->sk);
757 const unsigned int type = sock->type;
758
759 if (!msg->msg_name || !family ||
760 (type != SOCK_DGRAM && type != SOCK_RAW))
761 return 0;
762 address.protocol = type;
763 address.operation = TOMOYO_NETWORK_SEND;
764 if (family == PF_UNIX)
765 return tomoyo_check_unix_address((struct sockaddr *)
766 msg->msg_name,
767 msg->msg_namelen, &address);
768 return tomoyo_check_inet_address((struct sockaddr *) msg->msg_name,
769 msg->msg_namelen,
770 sock->sk->sk_protocol, &address);
771}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 6c601bd300f3..738bbdf8d4c7 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -15,17 +15,19 @@
15#include "../../fs/internal.h" 15#include "../../fs/internal.h"
16 16
17/** 17/**
18 * tomoyo_encode: Convert binary string to ascii string. 18 * tomoyo_encode2 - Encode binary string to ascii string.
19 * 19 *
20 * @str: String in binary format. 20 * @str: String in binary format.
21 * @str_len: Size of @str in byte.
21 * 22 *
22 * Returns pointer to @str in ascii format on success, NULL otherwise. 23 * Returns pointer to @str in ascii format on success, NULL otherwise.
23 * 24 *
24 * This function uses kzalloc(), so caller must kfree() if this function 25 * This function uses kzalloc(), so caller must kfree() if this function
25 * didn't return NULL. 26 * didn't return NULL.
26 */ 27 */
27char *tomoyo_encode(const char *str) 28char *tomoyo_encode2(const char *str, int str_len)
28{ 29{
30 int i;
29 int len = 0; 31 int len = 0;
30 const char *p = str; 32 const char *p = str;
31 char *cp; 33 char *cp;
@@ -33,8 +35,9 @@ char *tomoyo_encode(const char *str)
33 35
34 if (!p) 36 if (!p)
35 return NULL; 37 return NULL;
36 while (*p) { 38 for (i = 0; i < str_len; i++) {
37 const unsigned char c = *p++; 39 const unsigned char c = p[i];
40
38 if (c == '\\') 41 if (c == '\\')
39 len += 2; 42 len += 2;
40 else if (c > ' ' && c < 127) 43 else if (c > ' ' && c < 127)
@@ -49,8 +52,8 @@ char *tomoyo_encode(const char *str)
49 return NULL; 52 return NULL;
50 cp0 = cp; 53 cp0 = cp;
51 p = str; 54 p = str;
52 while (*p) { 55 for (i = 0; i < str_len; i++) {
53 const unsigned char c = *p++; 56 const unsigned char c = p[i];
54 57
55 if (c == '\\') { 58 if (c == '\\') {
56 *cp++ = '\\'; 59 *cp++ = '\\';
@@ -68,6 +71,21 @@ char *tomoyo_encode(const char *str)
68} 71}
69 72
70/** 73/**
74 * tomoyo_encode - Encode binary string to ascii string.
75 *
76 * @str: String in binary format.
77 *
78 * Returns pointer to @str in ascii format on success, NULL otherwise.
79 *
80 * This function uses kzalloc(), so caller must kfree() if this function
81 * didn't return NULL.
82 */
83char *tomoyo_encode(const char *str)
84{
85 return str ? tomoyo_encode2(str, strlen(str)) : NULL;
86}
87
88/**
71 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root. 89 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
72 * 90 *
73 * @path: Pointer to "struct path". 91 * @path: Pointer to "struct path".
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index f776400a8f31..4b327b691745 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -442,6 +442,64 @@ static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path); 442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
443} 443}
444 444
445/**
446 * tomoyo_socket_listen - Check permission for listen().
447 *
448 * @sock: Pointer to "struct socket".
449 * @backlog: Backlog parameter.
450 *
451 * Returns 0 on success, negative value otherwise.
452 */
453static int tomoyo_socket_listen(struct socket *sock, int backlog)
454{
455 return tomoyo_socket_listen_permission(sock);
456}
457
458/**
459 * tomoyo_socket_connect - Check permission for connect().
460 *
461 * @sock: Pointer to "struct socket".
462 * @addr: Pointer to "struct sockaddr".
463 * @addr_len: Size of @addr.
464 *
465 * Returns 0 on success, negative value otherwise.
466 */
467static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
468 int addr_len)
469{
470 return tomoyo_socket_connect_permission(sock, addr, addr_len);
471}
472
473/**
474 * tomoyo_socket_bind - Check permission for bind().
475 *
476 * @sock: Pointer to "struct socket".
477 * @addr: Pointer to "struct sockaddr".
478 * @addr_len: Size of @addr.
479 *
480 * Returns 0 on success, negative value otherwise.
481 */
482static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
483 int addr_len)
484{
485 return tomoyo_socket_bind_permission(sock, addr, addr_len);
486}
487
488/**
489 * tomoyo_socket_sendmsg - Check permission for sendmsg().
490 *
491 * @sock: Pointer to "struct socket".
492 * @msg: Pointer to "struct msghdr".
493 * @size: Size of message.
494 *
495 * Returns 0 on success, negative value otherwise.
496 */
497static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
498 int size)
499{
500 return tomoyo_socket_sendmsg_permission(sock, msg, size);
501}
502
445/* 503/*
446 * tomoyo_security_ops is a "struct security_operations" which is used for 504 * tomoyo_security_ops is a "struct security_operations" which is used for
447 * registering TOMOYO. 505 * registering TOMOYO.
@@ -472,6 +530,10 @@ static struct security_operations tomoyo_security_ops = {
472 .sb_mount = tomoyo_sb_mount, 530 .sb_mount = tomoyo_sb_mount,
473 .sb_umount = tomoyo_sb_umount, 531 .sb_umount = tomoyo_sb_umount,
474 .sb_pivotroot = tomoyo_sb_pivotroot, 532 .sb_pivotroot = tomoyo_sb_pivotroot,
533 .socket_bind = tomoyo_socket_bind,
534 .socket_connect = tomoyo_socket_connect,
535 .socket_listen = tomoyo_socket_listen,
536 .socket_sendmsg = tomoyo_socket_sendmsg,
475}; 537};
476 538
477/* Lock for GC. */ 539/* Lock for GC. */
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index cb7d507b6312..a1c3d9ccebfa 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -42,6 +42,37 @@ const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE, 42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE, 43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE, 44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
45 /* CONFIG::network group */
46 [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] =
47 TOMOYO_MAC_CATEGORY_NETWORK,
48 [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] =
49 TOMOYO_MAC_CATEGORY_NETWORK,
50 [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] =
51 TOMOYO_MAC_CATEGORY_NETWORK,
52 [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] =
53 TOMOYO_MAC_CATEGORY_NETWORK,
54 [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] =
55 TOMOYO_MAC_CATEGORY_NETWORK,
56 [TOMOYO_MAC_NETWORK_INET_RAW_BIND] =
57 TOMOYO_MAC_CATEGORY_NETWORK,
58 [TOMOYO_MAC_NETWORK_INET_RAW_SEND] =
59 TOMOYO_MAC_CATEGORY_NETWORK,
60 [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] =
61 TOMOYO_MAC_CATEGORY_NETWORK,
62 [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] =
63 TOMOYO_MAC_CATEGORY_NETWORK,
64 [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] =
65 TOMOYO_MAC_CATEGORY_NETWORK,
66 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] =
67 TOMOYO_MAC_CATEGORY_NETWORK,
68 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] =
69 TOMOYO_MAC_CATEGORY_NETWORK,
70 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] =
71 TOMOYO_MAC_CATEGORY_NETWORK,
72 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] =
73 TOMOYO_MAC_CATEGORY_NETWORK,
74 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] =
75 TOMOYO_MAC_CATEGORY_NETWORK,
45 /* CONFIG::misc group */ 76 /* CONFIG::misc group */
46 [TOMOYO_MAC_ENVIRON] = TOMOYO_MAC_CATEGORY_MISC, 77 [TOMOYO_MAC_ENVIRON] = TOMOYO_MAC_CATEGORY_MISC,
47}; 78};