diff options
-rw-r--r-- | Documentation/security/LSM-sctp.rst | 175 | ||||
-rw-r--r-- | include/linux/lsm_hooks.h | 36 | ||||
-rw-r--r-- | include/linux/security.h | 25 | ||||
-rw-r--r-- | security/security.c | 22 |
4 files changed, 258 insertions, 0 deletions
diff --git a/Documentation/security/LSM-sctp.rst b/Documentation/security/LSM-sctp.rst new file mode 100644 index 000000000000..6e5a3925a860 --- /dev/null +++ b/Documentation/security/LSM-sctp.rst | |||
@@ -0,0 +1,175 @@ | |||
1 | SCTP LSM Support | ||
2 | ================ | ||
3 | |||
4 | For security module support, three SCTP specific hooks have been implemented:: | ||
5 | |||
6 | security_sctp_assoc_request() | ||
7 | security_sctp_bind_connect() | ||
8 | security_sctp_sk_clone() | ||
9 | |||
10 | Also the following security hook has been utilised:: | ||
11 | |||
12 | security_inet_conn_established() | ||
13 | |||
14 | The usage of these hooks are described below with the SELinux implementation | ||
15 | described in ``Documentation/security/SELinux-sctp.rst`` | ||
16 | |||
17 | |||
18 | security_sctp_assoc_request() | ||
19 | ----------------------------- | ||
20 | Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the | ||
21 | security module. Returns 0 on success, error on failure. | ||
22 | :: | ||
23 | |||
24 | @ep - pointer to sctp endpoint structure. | ||
25 | @skb - pointer to skbuff of association packet. | ||
26 | |||
27 | |||
28 | security_sctp_bind_connect() | ||
29 | ----------------------------- | ||
30 | Passes one or more ipv4/ipv6 addresses to the security module for validation | ||
31 | based on the ``@optname`` that will result in either a bind or connect | ||
32 | service as shown in the permission check tables below. | ||
33 | Returns 0 on success, error on failure. | ||
34 | :: | ||
35 | |||
36 | @sk - Pointer to sock structure. | ||
37 | @optname - Name of the option to validate. | ||
38 | @address - One or more ipv4 / ipv6 addresses. | ||
39 | @addrlen - The total length of address(s). This is calculated on each | ||
40 | ipv4 or ipv6 address using sizeof(struct sockaddr_in) or | ||
41 | sizeof(struct sockaddr_in6). | ||
42 | |||
43 | ------------------------------------------------------------------ | ||
44 | | BIND Type Checks | | ||
45 | | @optname | @address contains | | ||
46 | |----------------------------|-----------------------------------| | ||
47 | | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses | | ||
48 | | SCTP_PRIMARY_ADDR | Single ipv4 or ipv6 address | | ||
49 | | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address | | ||
50 | ------------------------------------------------------------------ | ||
51 | |||
52 | ------------------------------------------------------------------ | ||
53 | | CONNECT Type Checks | | ||
54 | | @optname | @address contains | | ||
55 | |----------------------------|-----------------------------------| | ||
56 | | SCTP_SOCKOPT_CONNECTX | One or more ipv4 / ipv6 addresses | | ||
57 | | SCTP_PARAM_ADD_IP | One or more ipv4 / ipv6 addresses | | ||
58 | | SCTP_SENDMSG_CONNECT | Single ipv4 or ipv6 address | | ||
59 | | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address | | ||
60 | ------------------------------------------------------------------ | ||
61 | |||
62 | A summary of the ``@optname`` entries is as follows:: | ||
63 | |||
64 | SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be | ||
65 | associated after (optionally) calling | ||
66 | bind(3). | ||
67 | sctp_bindx(3) adds a set of bind | ||
68 | addresses on a socket. | ||
69 | |||
70 | SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple | ||
71 | addresses for reaching a peer | ||
72 | (multi-homed). | ||
73 | sctp_connectx(3) initiates a connection | ||
74 | on an SCTP socket using multiple | ||
75 | destination addresses. | ||
76 | |||
77 | SCTP_SENDMSG_CONNECT - Initiate a connection that is generated by a | ||
78 | sendmsg(2) or sctp_sendmsg(3) on a new asociation. | ||
79 | |||
80 | SCTP_PRIMARY_ADDR - Set local primary address. | ||
81 | |||
82 | SCTP_SET_PEER_PRIMARY_ADDR - Request peer sets address as | ||
83 | association primary. | ||
84 | |||
85 | SCTP_PARAM_ADD_IP - These are used when Dynamic Address | ||
86 | SCTP_PARAM_SET_PRIMARY - Reconfiguration is enabled as explained below. | ||
87 | |||
88 | |||
89 | To support Dynamic Address Reconfiguration the following parameters must be | ||
90 | enabled on both endpoints (or use the appropriate **setsockopt**\(2)):: | ||
91 | |||
92 | /proc/sys/net/sctp/addip_enable | ||
93 | /proc/sys/net/sctp/addip_noauth_enable | ||
94 | |||
95 | then the following *_PARAM_*'s are sent to the peer in an | ||
96 | ASCONF chunk when the corresponding ``@optname``'s are present:: | ||
97 | |||
98 | @optname ASCONF Parameter | ||
99 | ---------- ------------------ | ||
100 | SCTP_SOCKOPT_BINDX_ADD -> SCTP_PARAM_ADD_IP | ||
101 | SCTP_SET_PEER_PRIMARY_ADDR -> SCTP_PARAM_SET_PRIMARY | ||
102 | |||
103 | |||
104 | security_sctp_sk_clone() | ||
105 | ------------------------- | ||
106 | Called whenever a new socket is created by **accept**\(2) | ||
107 | (i.e. a TCP style socket) or when a socket is 'peeled off' e.g userspace | ||
108 | calls **sctp_peeloff**\(3). | ||
109 | :: | ||
110 | |||
111 | @ep - pointer to current sctp endpoint structure. | ||
112 | @sk - pointer to current sock structure. | ||
113 | @sk - pointer to new sock structure. | ||
114 | |||
115 | |||
116 | security_inet_conn_established() | ||
117 | --------------------------------- | ||
118 | Called when a COOKIE ACK is received:: | ||
119 | |||
120 | @sk - pointer to sock structure. | ||
121 | @skb - pointer to skbuff of the COOKIE ACK packet. | ||
122 | |||
123 | |||
124 | Security Hooks used for Association Establishment | ||
125 | ================================================= | ||
126 | The following diagram shows the use of ``security_sctp_bind_connect()``, | ||
127 | ``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when | ||
128 | establishing an association. | ||
129 | :: | ||
130 | |||
131 | SCTP endpoint "A" SCTP endpoint "Z" | ||
132 | ================= ================= | ||
133 | sctp_sf_do_prm_asoc() | ||
134 | Association setup can be initiated | ||
135 | by a connect(2), sctp_connectx(3), | ||
136 | sendmsg(2) or sctp_sendmsg(3). | ||
137 | These will result in a call to | ||
138 | security_sctp_bind_connect() to | ||
139 | initiate an association to | ||
140 | SCTP peer endpoint "Z". | ||
141 | INIT ---------------------------------------------> | ||
142 | sctp_sf_do_5_1B_init() | ||
143 | Respond to an INIT chunk. | ||
144 | SCTP peer endpoint "A" is | ||
145 | asking for an association. Call | ||
146 | security_sctp_assoc_request() | ||
147 | to set the peer label if first | ||
148 | association. | ||
149 | If not first association, check | ||
150 | whether allowed, IF so send: | ||
151 | <----------------------------------------------- INIT ACK | ||
152 | | ELSE audit event and silently | ||
153 | | discard the packet. | ||
154 | | | ||
155 | COOKIE ECHO ------------------------------------------> | ||
156 | | | ||
157 | | | ||
158 | | | ||
159 | <------------------------------------------- COOKIE ACK | ||
160 | | | | ||
161 | sctp_sf_do_5_1E_ca | | ||
162 | Call security_inet_conn_established() | | ||
163 | to set the peer label. | | ||
164 | | | | ||
165 | | If SCTP_SOCKET_TCP or peeled off | ||
166 | | socket security_sctp_sk_clone() is | ||
167 | | called to clone the new socket. | ||
168 | | | | ||
169 | ESTABLISHED ESTABLISHED | ||
170 | | | | ||
171 | ------------------------------------------------------------------ | ||
172 | | Association Established | | ||
173 | ------------------------------------------------------------------ | ||
174 | |||
175 | |||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 7161d8e7ee79..84c0b927ea85 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -906,6 +906,33 @@ | |||
906 | * associated with the TUN device's security structure. | 906 | * associated with the TUN device's security structure. |
907 | * @security pointer to the TUN devices's security structure. | 907 | * @security pointer to the TUN devices's security structure. |
908 | * | 908 | * |
909 | * Security hooks for SCTP | ||
910 | * | ||
911 | * @sctp_assoc_request: | ||
912 | * Passes the @ep and @chunk->skb of the association INIT packet to | ||
913 | * the security module. | ||
914 | * @ep pointer to sctp endpoint structure. | ||
915 | * @skb pointer to skbuff of association packet. | ||
916 | * Return 0 on success, error on failure. | ||
917 | * @sctp_bind_connect: | ||
918 | * Validiate permissions required for each address associated with sock | ||
919 | * @sk. Depending on @optname, the addresses will be treated as either | ||
920 | * for a connect or bind service. The @addrlen is calculated on each | ||
921 | * ipv4 and ipv6 address using sizeof(struct sockaddr_in) or | ||
922 | * sizeof(struct sockaddr_in6). | ||
923 | * @sk pointer to sock structure. | ||
924 | * @optname name of the option to validate. | ||
925 | * @address list containing one or more ipv4/ipv6 addresses. | ||
926 | * @addrlen total length of address(s). | ||
927 | * Return 0 on success, error on failure. | ||
928 | * @sctp_sk_clone: | ||
929 | * Called whenever a new socket is created by accept(2) (i.e. a TCP | ||
930 | * style socket) or when a socket is 'peeled off' e.g userspace | ||
931 | * calls sctp_peeloff(3). | ||
932 | * @ep pointer to current sctp endpoint structure. | ||
933 | * @sk pointer to current sock structure. | ||
934 | * @sk pointer to new sock structure. | ||
935 | * | ||
909 | * Security hooks for Infiniband | 936 | * Security hooks for Infiniband |
910 | * | 937 | * |
911 | * @ib_pkey_access: | 938 | * @ib_pkey_access: |
@@ -1665,6 +1692,12 @@ union security_list_options { | |||
1665 | int (*tun_dev_attach_queue)(void *security); | 1692 | int (*tun_dev_attach_queue)(void *security); |
1666 | int (*tun_dev_attach)(struct sock *sk, void *security); | 1693 | int (*tun_dev_attach)(struct sock *sk, void *security); |
1667 | int (*tun_dev_open)(void *security); | 1694 | int (*tun_dev_open)(void *security); |
1695 | int (*sctp_assoc_request)(struct sctp_endpoint *ep, | ||
1696 | struct sk_buff *skb); | ||
1697 | int (*sctp_bind_connect)(struct sock *sk, int optname, | ||
1698 | struct sockaddr *address, int addrlen); | ||
1699 | void (*sctp_sk_clone)(struct sctp_endpoint *ep, struct sock *sk, | ||
1700 | struct sock *newsk); | ||
1668 | #endif /* CONFIG_SECURITY_NETWORK */ | 1701 | #endif /* CONFIG_SECURITY_NETWORK */ |
1669 | 1702 | ||
1670 | #ifdef CONFIG_SECURITY_INFINIBAND | 1703 | #ifdef CONFIG_SECURITY_INFINIBAND |
@@ -1914,6 +1947,9 @@ struct security_hook_heads { | |||
1914 | struct list_head tun_dev_attach_queue; | 1947 | struct list_head tun_dev_attach_queue; |
1915 | struct list_head tun_dev_attach; | 1948 | struct list_head tun_dev_attach; |
1916 | struct list_head tun_dev_open; | 1949 | struct list_head tun_dev_open; |
1950 | struct list_head sctp_assoc_request; | ||
1951 | struct list_head sctp_bind_connect; | ||
1952 | struct list_head sctp_sk_clone; | ||
1917 | #endif /* CONFIG_SECURITY_NETWORK */ | 1953 | #endif /* CONFIG_SECURITY_NETWORK */ |
1918 | #ifdef CONFIG_SECURITY_INFINIBAND | 1954 | #ifdef CONFIG_SECURITY_INFINIBAND |
1919 | struct list_head ib_pkey_access; | 1955 | struct list_head ib_pkey_access; |
diff --git a/include/linux/security.h b/include/linux/security.h index 73f1ef625d40..2ff5f5777a53 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -115,6 +115,7 @@ struct xfrm_policy; | |||
115 | struct xfrm_state; | 115 | struct xfrm_state; |
116 | struct xfrm_user_sec_ctx; | 116 | struct xfrm_user_sec_ctx; |
117 | struct seq_file; | 117 | struct seq_file; |
118 | struct sctp_endpoint; | ||
118 | 119 | ||
119 | #ifdef CONFIG_MMU | 120 | #ifdef CONFIG_MMU |
120 | extern unsigned long mmap_min_addr; | 121 | extern unsigned long mmap_min_addr; |
@@ -1229,6 +1230,11 @@ int security_tun_dev_create(void); | |||
1229 | int security_tun_dev_attach_queue(void *security); | 1230 | int security_tun_dev_attach_queue(void *security); |
1230 | int security_tun_dev_attach(struct sock *sk, void *security); | 1231 | int security_tun_dev_attach(struct sock *sk, void *security); |
1231 | int security_tun_dev_open(void *security); | 1232 | int security_tun_dev_open(void *security); |
1233 | int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb); | ||
1234 | int security_sctp_bind_connect(struct sock *sk, int optname, | ||
1235 | struct sockaddr *address, int addrlen); | ||
1236 | void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, | ||
1237 | struct sock *newsk); | ||
1232 | 1238 | ||
1233 | #else /* CONFIG_SECURITY_NETWORK */ | 1239 | #else /* CONFIG_SECURITY_NETWORK */ |
1234 | static inline int security_unix_stream_connect(struct sock *sock, | 1240 | static inline int security_unix_stream_connect(struct sock *sock, |
@@ -1421,6 +1427,25 @@ static inline int security_tun_dev_open(void *security) | |||
1421 | { | 1427 | { |
1422 | return 0; | 1428 | return 0; |
1423 | } | 1429 | } |
1430 | |||
1431 | static inline int security_sctp_assoc_request(struct sctp_endpoint *ep, | ||
1432 | struct sk_buff *skb) | ||
1433 | { | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static inline int security_sctp_bind_connect(struct sock *sk, int optname, | ||
1438 | struct sockaddr *address, | ||
1439 | int addrlen) | ||
1440 | { | ||
1441 | return 0; | ||
1442 | } | ||
1443 | |||
1444 | static inline void security_sctp_sk_clone(struct sctp_endpoint *ep, | ||
1445 | struct sock *sk, | ||
1446 | struct sock *newsk) | ||
1447 | { | ||
1448 | } | ||
1424 | #endif /* CONFIG_SECURITY_NETWORK */ | 1449 | #endif /* CONFIG_SECURITY_NETWORK */ |
1425 | 1450 | ||
1426 | #ifdef CONFIG_SECURITY_INFINIBAND | 1451 | #ifdef CONFIG_SECURITY_INFINIBAND |
diff --git a/security/security.c b/security/security.c index 1cd8526cb0b7..133bc9915f18 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1473,6 +1473,7 @@ void security_inet_conn_established(struct sock *sk, | |||
1473 | { | 1473 | { |
1474 | call_void_hook(inet_conn_established, sk, skb); | 1474 | call_void_hook(inet_conn_established, sk, skb); |
1475 | } | 1475 | } |
1476 | EXPORT_SYMBOL(security_inet_conn_established); | ||
1476 | 1477 | ||
1477 | int security_secmark_relabel_packet(u32 secid) | 1478 | int security_secmark_relabel_packet(u32 secid) |
1478 | { | 1479 | { |
@@ -1528,6 +1529,27 @@ int security_tun_dev_open(void *security) | |||
1528 | } | 1529 | } |
1529 | EXPORT_SYMBOL(security_tun_dev_open); | 1530 | EXPORT_SYMBOL(security_tun_dev_open); |
1530 | 1531 | ||
1532 | int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) | ||
1533 | { | ||
1534 | return call_int_hook(sctp_assoc_request, 0, ep, skb); | ||
1535 | } | ||
1536 | EXPORT_SYMBOL(security_sctp_assoc_request); | ||
1537 | |||
1538 | int security_sctp_bind_connect(struct sock *sk, int optname, | ||
1539 | struct sockaddr *address, int addrlen) | ||
1540 | { | ||
1541 | return call_int_hook(sctp_bind_connect, 0, sk, optname, | ||
1542 | address, addrlen); | ||
1543 | } | ||
1544 | EXPORT_SYMBOL(security_sctp_bind_connect); | ||
1545 | |||
1546 | void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, | ||
1547 | struct sock *newsk) | ||
1548 | { | ||
1549 | call_void_hook(sctp_sk_clone, ep, sk, newsk); | ||
1550 | } | ||
1551 | EXPORT_SYMBOL(security_sctp_sk_clone); | ||
1552 | |||
1531 | #endif /* CONFIG_SECURITY_NETWORK */ | 1553 | #endif /* CONFIG_SECURITY_NETWORK */ |
1532 | 1554 | ||
1533 | #ifdef CONFIG_SECURITY_INFINIBAND | 1555 | #ifdef CONFIG_SECURITY_INFINIBAND |