forked from mirrors/linux
		
	security: Add support for SCTP security hooks
The SCTP security hooks are explained in: Documentation/security/LSM-sctp.rst Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
		
							parent
							
								
									213d7f9477
								
							
						
					
					
						commit
						72e89f5008
					
				
					 4 changed files with 258 additions and 0 deletions
				
			
		
							
								
								
									
										175
									
								
								Documentation/security/LSM-sctp.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								Documentation/security/LSM-sctp.rst
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,175 @@ | ||||||
|  | SCTP LSM Support | ||||||
|  | ================ | ||||||
|  | 
 | ||||||
|  | For security module support, three SCTP specific hooks have been implemented:: | ||||||
|  | 
 | ||||||
|  |     security_sctp_assoc_request() | ||||||
|  |     security_sctp_bind_connect() | ||||||
|  |     security_sctp_sk_clone() | ||||||
|  | 
 | ||||||
|  | Also the following security hook has been utilised:: | ||||||
|  | 
 | ||||||
|  |     security_inet_conn_established() | ||||||
|  | 
 | ||||||
|  | The usage of these hooks are described below with the SELinux implementation | ||||||
|  | described in ``Documentation/security/SELinux-sctp.rst`` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | security_sctp_assoc_request() | ||||||
|  | ----------------------------- | ||||||
|  | Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the | ||||||
|  | security module. Returns 0 on success, error on failure. | ||||||
|  | :: | ||||||
|  | 
 | ||||||
|  |     @ep - pointer to sctp endpoint structure. | ||||||
|  |     @skb - pointer to skbuff of association packet. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | security_sctp_bind_connect() | ||||||
|  | ----------------------------- | ||||||
|  | Passes one or more ipv4/ipv6 addresses to the security module for validation | ||||||
|  | based on the ``@optname`` that will result in either a bind or connect | ||||||
|  | service as shown in the permission check tables below. | ||||||
|  | Returns 0 on success, error on failure. | ||||||
|  | :: | ||||||
|  | 
 | ||||||
|  |     @sk      - Pointer to sock structure. | ||||||
|  |     @optname - Name of the option to validate. | ||||||
|  |     @address - One or more ipv4 / ipv6 addresses. | ||||||
|  |     @addrlen - The total length of address(s). This is calculated on each | ||||||
|  |                ipv4 or ipv6 address using sizeof(struct sockaddr_in) or | ||||||
|  |                sizeof(struct sockaddr_in6). | ||||||
|  | 
 | ||||||
|  |   ------------------------------------------------------------------ | ||||||
|  |   |                     BIND Type Checks                           | | ||||||
|  |   |       @optname             |         @address contains         | | ||||||
|  |   |----------------------------|-----------------------------------| | ||||||
|  |   | SCTP_SOCKOPT_BINDX_ADD     | One or more ipv4 / ipv6 addresses | | ||||||
|  |   | SCTP_PRIMARY_ADDR          | Single ipv4 or ipv6 address       | | ||||||
|  |   | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address       | | ||||||
|  |   ------------------------------------------------------------------ | ||||||
|  | 
 | ||||||
|  |   ------------------------------------------------------------------ | ||||||
|  |   |                   CONNECT Type Checks                          | | ||||||
|  |   |       @optname             |         @address contains         | | ||||||
|  |   |----------------------------|-----------------------------------| | ||||||
|  |   | SCTP_SOCKOPT_CONNECTX      | One or more ipv4 / ipv6 addresses | | ||||||
|  |   | SCTP_PARAM_ADD_IP          | One or more ipv4 / ipv6 addresses | | ||||||
|  |   | SCTP_SENDMSG_CONNECT       | Single ipv4 or ipv6 address       | | ||||||
|  |   | SCTP_PARAM_SET_PRIMARY     | Single ipv4 or ipv6 address       | | ||||||
|  |   ------------------------------------------------------------------ | ||||||
|  | 
 | ||||||
|  | A summary of the ``@optname`` entries is as follows:: | ||||||
|  | 
 | ||||||
|  |     SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be | ||||||
|  |                              associated after (optionally) calling | ||||||
|  |                              bind(3). | ||||||
|  |                              sctp_bindx(3) adds a set of bind | ||||||
|  |                              addresses on a socket. | ||||||
|  | 
 | ||||||
|  |     SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple | ||||||
|  |                             addresses for reaching a peer | ||||||
|  |                             (multi-homed). | ||||||
|  |                             sctp_connectx(3) initiates a connection | ||||||
|  |                             on an SCTP socket using multiple | ||||||
|  |                             destination addresses. | ||||||
|  | 
 | ||||||
|  |     SCTP_SENDMSG_CONNECT  - Initiate a connection that is generated by a | ||||||
|  |                             sendmsg(2) or sctp_sendmsg(3) on a new asociation. | ||||||
|  | 
 | ||||||
|  |     SCTP_PRIMARY_ADDR     - Set local primary address. | ||||||
|  | 
 | ||||||
|  |     SCTP_SET_PEER_PRIMARY_ADDR - Request peer sets address as | ||||||
|  |                                  association primary. | ||||||
|  | 
 | ||||||
|  |     SCTP_PARAM_ADD_IP          - These are used when Dynamic Address | ||||||
|  |     SCTP_PARAM_SET_PRIMARY     - Reconfiguration is enabled as explained below. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | To support Dynamic Address Reconfiguration the following parameters must be | ||||||
|  | enabled on both endpoints (or use the appropriate **setsockopt**\(2)):: | ||||||
|  | 
 | ||||||
|  |     /proc/sys/net/sctp/addip_enable | ||||||
|  |     /proc/sys/net/sctp/addip_noauth_enable | ||||||
|  | 
 | ||||||
|  | then the following *_PARAM_*'s are sent to the peer in an | ||||||
|  | ASCONF chunk when the corresponding ``@optname``'s are present:: | ||||||
|  | 
 | ||||||
|  |           @optname                      ASCONF Parameter | ||||||
|  |          ----------                    ------------------ | ||||||
|  |     SCTP_SOCKOPT_BINDX_ADD     ->   SCTP_PARAM_ADD_IP | ||||||
|  |     SCTP_SET_PEER_PRIMARY_ADDR ->   SCTP_PARAM_SET_PRIMARY | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | security_sctp_sk_clone() | ||||||
|  | ------------------------- | ||||||
|  | Called whenever a new socket is created by **accept**\(2) | ||||||
|  | (i.e. a TCP style socket) or when a socket is 'peeled off' e.g userspace | ||||||
|  | calls **sctp_peeloff**\(3). | ||||||
|  | :: | ||||||
|  | 
 | ||||||
|  |     @ep - pointer to current sctp endpoint structure. | ||||||
|  |     @sk - pointer to current sock structure. | ||||||
|  |     @sk - pointer to new sock structure. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | security_inet_conn_established() | ||||||
|  | --------------------------------- | ||||||
|  | Called when a COOKIE ACK is received:: | ||||||
|  | 
 | ||||||
|  |     @sk  - pointer to sock structure. | ||||||
|  |     @skb - pointer to skbuff of the COOKIE ACK packet. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Security Hooks used for Association Establishment | ||||||
|  | ================================================= | ||||||
|  | The following diagram shows the use of ``security_sctp_bind_connect()``, | ||||||
|  | ``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when | ||||||
|  | establishing an association. | ||||||
|  | :: | ||||||
|  | 
 | ||||||
|  |       SCTP endpoint "A"                                SCTP endpoint "Z" | ||||||
|  |       =================                                ================= | ||||||
|  |     sctp_sf_do_prm_asoc() | ||||||
|  |  Association setup can be initiated | ||||||
|  |  by a connect(2), sctp_connectx(3), | ||||||
|  |  sendmsg(2) or sctp_sendmsg(3). | ||||||
|  |  These will result in a call to | ||||||
|  |  security_sctp_bind_connect() to | ||||||
|  |  initiate an association to | ||||||
|  |  SCTP peer endpoint "Z". | ||||||
|  |          INIT ---------------------------------------------> | ||||||
|  |                                                    sctp_sf_do_5_1B_init() | ||||||
|  |                                                  Respond to an INIT chunk. | ||||||
|  |                                              SCTP peer endpoint "A" is | ||||||
|  |                                              asking for an association. Call | ||||||
|  |                                              security_sctp_assoc_request() | ||||||
|  |                                              to set the peer label if first | ||||||
|  |                                              association. | ||||||
|  |                                              If not first association, check | ||||||
|  |                                              whether allowed, IF so send: | ||||||
|  |           <----------------------------------------------- INIT ACK | ||||||
|  |           |                                  ELSE audit event and silently | ||||||
|  |           |                                       discard the packet. | ||||||
|  |           | | ||||||
|  |     COOKIE ECHO ------------------------------------------> | ||||||
|  |                                                           | | ||||||
|  |                                                           | | ||||||
|  |                                                           | | ||||||
|  |           <------------------------------------------- COOKIE ACK | ||||||
|  |           |                                               | | ||||||
|  |     sctp_sf_do_5_1E_ca                                    | | ||||||
|  |  Call security_inet_conn_established()                    | | ||||||
|  |  to set the peer label.                                   | | ||||||
|  |           |                                               | | ||||||
|  |           |                               If SCTP_SOCKET_TCP or peeled off | ||||||
|  |           |                               socket security_sctp_sk_clone() is | ||||||
|  |           |                               called to clone the new socket. | ||||||
|  |           |                                               | | ||||||
|  |       ESTABLISHED                                    ESTABLISHED | ||||||
|  |           |                                               | | ||||||
|  |     ------------------------------------------------------------------ | ||||||
|  |     |                     Association Established                    | | ||||||
|  |     ------------------------------------------------------------------ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -906,6 +906,33 @@ | ||||||
|  *	associated with the TUN device's security structure. |  *	associated with the TUN device's security structure. | ||||||
|  *	@security pointer to the TUN devices's security structure. |  *	@security pointer to the TUN devices's security structure. | ||||||
|  * |  * | ||||||
|  |  * Security hooks for SCTP | ||||||
|  |  * | ||||||
|  |  * @sctp_assoc_request: | ||||||
|  |  *	Passes the @ep and @chunk->skb of the association INIT packet to | ||||||
|  |  *	the security module. | ||||||
|  |  *	@ep pointer to sctp endpoint structure. | ||||||
|  |  *	@skb pointer to skbuff of association packet. | ||||||
|  |  *	Return 0 on success, error on failure. | ||||||
|  |  * @sctp_bind_connect: | ||||||
|  |  *	Validiate permissions required for each address associated with sock | ||||||
|  |  *	@sk. Depending on @optname, the addresses will be treated as either | ||||||
|  |  *	for a connect or bind service. The @addrlen is calculated on each | ||||||
|  |  *	ipv4 and ipv6 address using sizeof(struct sockaddr_in) or | ||||||
|  |  *	sizeof(struct sockaddr_in6). | ||||||
|  |  *	@sk pointer to sock structure. | ||||||
|  |  *	@optname name of the option to validate. | ||||||
|  |  *	@address list containing one or more ipv4/ipv6 addresses. | ||||||
|  |  *	@addrlen total length of address(s). | ||||||
|  |  *	Return 0 on success, error on failure. | ||||||
|  |  * @sctp_sk_clone: | ||||||
|  |  *	Called whenever a new socket is created by accept(2) (i.e. a TCP | ||||||
|  |  *	style socket) or when a socket is 'peeled off' e.g userspace | ||||||
|  |  *	calls sctp_peeloff(3). | ||||||
|  |  *	@ep pointer to current sctp endpoint structure. | ||||||
|  |  *	@sk pointer to current sock structure. | ||||||
|  |  *	@sk pointer to new sock structure. | ||||||
|  |  * | ||||||
|  * Security hooks for Infiniband |  * Security hooks for Infiniband | ||||||
|  * |  * | ||||||
|  * @ib_pkey_access: |  * @ib_pkey_access: | ||||||
|  | @ -1665,6 +1692,12 @@ union security_list_options { | ||||||
| 	int (*tun_dev_attach_queue)(void *security); | 	int (*tun_dev_attach_queue)(void *security); | ||||||
| 	int (*tun_dev_attach)(struct sock *sk, void *security); | 	int (*tun_dev_attach)(struct sock *sk, void *security); | ||||||
| 	int (*tun_dev_open)(void *security); | 	int (*tun_dev_open)(void *security); | ||||||
|  | 	int (*sctp_assoc_request)(struct sctp_endpoint *ep, | ||||||
|  | 				  struct sk_buff *skb); | ||||||
|  | 	int (*sctp_bind_connect)(struct sock *sk, int optname, | ||||||
|  | 				 struct sockaddr *address, int addrlen); | ||||||
|  | 	void (*sctp_sk_clone)(struct sctp_endpoint *ep, struct sock *sk, | ||||||
|  | 			      struct sock *newsk); | ||||||
| #endif	/* CONFIG_SECURITY_NETWORK */ | #endif	/* CONFIG_SECURITY_NETWORK */ | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SECURITY_INFINIBAND | #ifdef CONFIG_SECURITY_INFINIBAND | ||||||
|  | @ -1914,6 +1947,9 @@ struct security_hook_heads { | ||||||
| 	struct list_head tun_dev_attach_queue; | 	struct list_head tun_dev_attach_queue; | ||||||
| 	struct list_head tun_dev_attach; | 	struct list_head tun_dev_attach; | ||||||
| 	struct list_head tun_dev_open; | 	struct list_head tun_dev_open; | ||||||
|  | 	struct list_head sctp_assoc_request; | ||||||
|  | 	struct list_head sctp_bind_connect; | ||||||
|  | 	struct list_head sctp_sk_clone; | ||||||
| #endif	/* CONFIG_SECURITY_NETWORK */ | #endif	/* CONFIG_SECURITY_NETWORK */ | ||||||
| #ifdef CONFIG_SECURITY_INFINIBAND | #ifdef CONFIG_SECURITY_INFINIBAND | ||||||
| 	struct list_head ib_pkey_access; | 	struct list_head ib_pkey_access; | ||||||
|  |  | ||||||
|  | @ -115,6 +115,7 @@ struct xfrm_policy; | ||||||
| struct xfrm_state; | struct xfrm_state; | ||||||
| struct xfrm_user_sec_ctx; | struct xfrm_user_sec_ctx; | ||||||
| struct seq_file; | struct seq_file; | ||||||
|  | struct sctp_endpoint; | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_MMU | #ifdef CONFIG_MMU | ||||||
| extern unsigned long mmap_min_addr; | extern unsigned long mmap_min_addr; | ||||||
|  | @ -1229,6 +1230,11 @@ int security_tun_dev_create(void); | ||||||
| int security_tun_dev_attach_queue(void *security); | int security_tun_dev_attach_queue(void *security); | ||||||
| int security_tun_dev_attach(struct sock *sk, void *security); | int security_tun_dev_attach(struct sock *sk, void *security); | ||||||
| int security_tun_dev_open(void *security); | int security_tun_dev_open(void *security); | ||||||
|  | int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb); | ||||||
|  | int security_sctp_bind_connect(struct sock *sk, int optname, | ||||||
|  | 			       struct sockaddr *address, int addrlen); | ||||||
|  | void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, | ||||||
|  | 			    struct sock *newsk); | ||||||
| 
 | 
 | ||||||
| #else	/* CONFIG_SECURITY_NETWORK */ | #else	/* CONFIG_SECURITY_NETWORK */ | ||||||
| static inline int security_unix_stream_connect(struct sock *sock, | static inline int security_unix_stream_connect(struct sock *sock, | ||||||
|  | @ -1421,6 +1427,25 @@ static inline int security_tun_dev_open(void *security) | ||||||
| { | { | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | static inline int security_sctp_assoc_request(struct sctp_endpoint *ep, | ||||||
|  | 					      struct sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int security_sctp_bind_connect(struct sock *sk, int optname, | ||||||
|  | 					     struct sockaddr *address, | ||||||
|  | 					     int addrlen) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void security_sctp_sk_clone(struct sctp_endpoint *ep, | ||||||
|  | 					  struct sock *sk, | ||||||
|  | 					  struct sock *newsk) | ||||||
|  | { | ||||||
|  | } | ||||||
| #endif	/* CONFIG_SECURITY_NETWORK */ | #endif	/* CONFIG_SECURITY_NETWORK */ | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SECURITY_INFINIBAND | #ifdef CONFIG_SECURITY_INFINIBAND | ||||||
|  |  | ||||||
|  | @ -1473,6 +1473,7 @@ void security_inet_conn_established(struct sock *sk, | ||||||
| { | { | ||||||
| 	call_void_hook(inet_conn_established, sk, skb); | 	call_void_hook(inet_conn_established, sk, skb); | ||||||
| } | } | ||||||
|  | EXPORT_SYMBOL(security_inet_conn_established); | ||||||
| 
 | 
 | ||||||
| int security_secmark_relabel_packet(u32 secid) | int security_secmark_relabel_packet(u32 secid) | ||||||
| { | { | ||||||
|  | @ -1528,6 +1529,27 @@ int security_tun_dev_open(void *security) | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(security_tun_dev_open); | EXPORT_SYMBOL(security_tun_dev_open); | ||||||
| 
 | 
 | ||||||
|  | int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return call_int_hook(sctp_assoc_request, 0, ep, skb); | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(security_sctp_assoc_request); | ||||||
|  | 
 | ||||||
|  | int security_sctp_bind_connect(struct sock *sk, int optname, | ||||||
|  | 			       struct sockaddr *address, int addrlen) | ||||||
|  | { | ||||||
|  | 	return call_int_hook(sctp_bind_connect, 0, sk, optname, | ||||||
|  | 			     address, addrlen); | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(security_sctp_bind_connect); | ||||||
|  | 
 | ||||||
|  | void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, | ||||||
|  | 			    struct sock *newsk) | ||||||
|  | { | ||||||
|  | 	call_void_hook(sctp_sk_clone, ep, sk, newsk); | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(security_sctp_sk_clone); | ||||||
|  | 
 | ||||||
| #endif	/* CONFIG_SECURITY_NETWORK */ | #endif	/* CONFIG_SECURITY_NETWORK */ | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SECURITY_INFINIBAND | #ifdef CONFIG_SECURITY_INFINIBAND | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Richard Haines
						Richard Haines