Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72e89f50 authored by Richard Haines's avatar Richard Haines Committed by Paul Moore
Browse files

security: Add support for SCTP security hooks



The SCTP security hooks are explained in:
Documentation/security/LSM-sctp.rst

Signed-off-by: default avatarRichard Haines <richard_c_haines@btinternet.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 213d7f94
Loading
Loading
Loading
Loading
+175 −0
Original line number Diff line number Diff line
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                    |
    ------------------------------------------------------------------

+36 −0
Original line number Diff line number Diff line
@@ -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;
+25 −0
Original line number Diff line number Diff line
@@ -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
+22 −0
Original line number Diff line number Diff line
@@ -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