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. | ||||
|  *	@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 | ||||
|  * | ||||
|  * @ib_pkey_access: | ||||
|  | @ -1665,6 +1692,12 @@ union security_list_options { | |||
| 	int (*tun_dev_attach_queue)(void *security); | ||||
| 	int (*tun_dev_attach)(struct sock *sk, 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 */ | ||||
| 
 | ||||
| #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; | ||||
| 	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 */ | ||||
| #ifdef CONFIG_SECURITY_INFINIBAND | ||||
| 	struct list_head ib_pkey_access; | ||||
|  |  | |||
|  | @ -115,6 +115,7 @@ struct xfrm_policy; | |||
| struct xfrm_state; | ||||
| struct xfrm_user_sec_ctx; | ||||
| struct seq_file; | ||||
| struct sctp_endpoint; | ||||
| 
 | ||||
| #ifdef CONFIG_MMU | ||||
| 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(struct sock *sk, 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 */ | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 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 */ | ||||
| 
 | ||||
| #ifdef CONFIG_SECURITY_INFINIBAND | ||||
|  |  | |||
|  | @ -1473,6 +1473,7 @@ void security_inet_conn_established(struct sock *sk, | |||
| { | ||||
| 	call_void_hook(inet_conn_established, sk, skb); | ||||
| } | ||||
| EXPORT_SYMBOL(security_inet_conn_established); | ||||
| 
 | ||||
| int security_secmark_relabel_packet(u32 secid) | ||||
| { | ||||
|  | @ -1528,6 +1529,27 @@ int security_tun_dev_open(void *security) | |||
| } | ||||
| 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 */ | ||||
| 
 | ||||
| #ifdef CONFIG_SECURITY_INFINIBAND | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Richard Haines
						Richard Haines