Commit 2bd080b0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sctp-=security-hook-fixes'



Xin Long says:

====================
security: fixups for the security hooks in sctp

There are a couple of problems in the currect security hooks in sctp:

1. The hooks incorrectly treat sctp_endpoint in SCTP as request_sock in
   TCP, while it's in fact no more than an extension of the sock, and
   represents the local host. It is created when sock is created, not
   when a conn request comes. sctp_association is actually the correct
   one to represent the connection, and created when a conn request
   arrives.

2. security_sctp_assoc_request() hook should also be called in processing
   COOKIE ECHO, as that's the place where the real assoc is created and
   used in the future.

The problems above may cause accept sk, peeloff sk or client sk having
the incorrect security labels.

So this patchset is to change some hooks and pass asoc into them and save
these secids into asoc, as well as add the missing sctp_assoc_request
hook into the COOKIE ECHO processing.

v1->v2:
  - See each patch, and thanks the help from Ondrej, Paul and Richard.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 843c3cbb e7310c94
Loading
Loading
Loading
Loading
+33 −32
Original line number Diff line number Diff line
@@ -15,10 +15,7 @@ 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()
    security_sctp_assoc_established()

The usage of these hooks are described below with the SELinux implementation
described in the `SCTP SELinux Support`_ chapter.
@@ -26,11 +23,11 @@ described in the `SCTP SELinux Support`_ chapter.

security_sctp_assoc_request()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
Passes the ``@asoc`` 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.
    @asoc - pointer to sctp association structure.
    @skb - pointer to skbuff of association packet.


@@ -117,16 +114,17 @@ Called whenever a new socket is created by **accept**\(2)
calls **sctp_peeloff**\(3).
::

    @ep - pointer to current sctp endpoint structure.
    @asoc - pointer to current sctp association structure.
    @sk - pointer to current sock structure.
    @sk - pointer to new sock structure.
    @newsk - pointer to new sock structure.


security_inet_conn_established()
security_sctp_assoc_established()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Called when a COOKIE ACK is received::
Called when a COOKIE ACK is received, and the peer secid will be
saved into ``@asoc->peer_secid`` for client::

    @sk  - pointer to sock structure.
    @asoc - pointer to sctp association structure.
    @skb - pointer to skbuff of the COOKIE ACK packet.


@@ -134,7 +132,7 @@ 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
``security_sctp_assoc_request()``, ``security_sctp_assoc_established()`` when
establishing an association.
::

@@ -151,9 +149,9 @@ establishing an association.
         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()
                                             SCTP peer endpoint "A" is asking
                                             for a temporary association.
                                             Call security_sctp_assoc_request()
                                             to set the peer label if first
                                             association.
                                             If not first association, check
@@ -163,13 +161,16 @@ establishing an association.
          |                                       discard the packet.
          |
    COOKIE ECHO ------------------------------------------>
                                                          |
                                                          |
                                                          |
                                                  sctp_sf_do_5_1D_ce()
                                             Respond to an COOKIE ECHO chunk.
                                             Confirm the cookie and create a
                                             permanent association.
                                             Call security_sctp_assoc_request() to
                                             do the same as for INIT chunk Response.
          <------------------------------------------- COOKIE ACK
          |                                               |
    sctp_sf_do_5_1E_ca                                    |
 Call security_inet_conn_established()                    |
 Call security_sctp_assoc_established()                   |
 to set the peer label.                                   |
          |                                               |
          |                               If SCTP_SOCKET_TCP or peeled off
@@ -195,27 +196,27 @@ hooks with the SELinux specifics expanded below::
    security_sctp_assoc_request()
    security_sctp_bind_connect()
    security_sctp_sk_clone()
    security_inet_conn_established()
    security_sctp_assoc_established()


security_sctp_assoc_request()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
Passes the ``@asoc`` 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.
    @asoc - pointer to sctp association structure.
    @skb - pointer to skbuff of association packet.

The security module performs the following operations:
     IF this is the first association on ``@ep->base.sk``, then set the peer
     IF this is the first association on ``@asoc->base.sk``, then set the peer
     sid to that in ``@skb``. This will ensure there is only one peer sid
     assigned to ``@ep->base.sk`` that may support multiple associations.
     assigned to ``@asoc->base.sk`` that may support multiple associations.

     ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
     ELSE validate the ``@asoc->base.sk peer_sid`` against the ``@skb peer sid``
     to determine whether the association should be allowed or denied.

     Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
     Set the sctp ``@asoc sid`` to socket's sid (from ``asoc->base.sk``) with
     MLS portion taken from ``@skb peer sid``. This will be used by SCTP
     TCP style sockets and peeled off connections as they cause a new socket
     to be generated.
@@ -259,21 +260,21 @@ 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). ``security_sctp_sk_clone()`` will set the new
sockets sid and peer sid to that contained in the ``@ep sid`` and
``@ep peer sid`` respectively.
sockets sid and peer sid to that contained in the ``@asoc sid`` and
``@asoc peer sid`` respectively.
::

    @ep - pointer to current sctp endpoint structure.
    @asoc - pointer to current sctp association structure.
    @sk - pointer to current sock structure.
    @sk - pointer to new sock structure.
    @newsk - pointer to new sock structure.


security_inet_conn_established()
security_sctp_assoc_established()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Called when a COOKIE ACK is received where it sets the connection's peer sid
to that in ``@skb``::

    @sk  - pointer to sock structure.
    @asoc - pointer to sctp association structure.
    @skb - pointer to skbuff of the COOKIE ACK packet.


+4 −2
Original line number Diff line number Diff line
@@ -329,12 +329,14 @@ LSM_HOOK(int, 0, tun_dev_create, void)
LSM_HOOK(int, 0, tun_dev_attach_queue, void *security)
LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, void *security)
LSM_HOOK(int, 0, tun_dev_open, void *security)
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_endpoint *ep,
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_association *asoc,
	 struct sk_buff *skb)
LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
	 struct sockaddr *address, int addrlen)
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_endpoint *ep,
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
	 struct sock *sk, struct sock *newsk)
LSM_HOOK(void, LSM_RET_VOID, sctp_assoc_established, struct sctp_association *asoc,
	 struct sk_buff *skb)
#endif /* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_INFINIBAND
+9 −4
Original line number Diff line number Diff line
@@ -1027,9 +1027,9 @@
 * Security hooks for SCTP
 *
 * @sctp_assoc_request:
 *	Passes the @ep and @chunk->skb of the association INIT packet to
 *	Passes the @asoc and @chunk->skb of the association INIT packet to
 *	the security module.
 *	@ep pointer to sctp endpoint structure.
 *	@asoc pointer to sctp association structure.
 *	@skb pointer to skbuff of association packet.
 *	Return 0 on success, error on failure.
 * @sctp_bind_connect:
@@ -1047,9 +1047,14 @@
 *	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.
 *	@asoc pointer to current sctp association structure.
 *	@sk pointer to current sock structure.
 *	@sk pointer to new sock structure.
 *	@newsk pointer to new sock structure.
 * @sctp_assoc_established:
 *	Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet
 *	to the security module.
 *	@asoc pointer to sctp association structure.
 *	@skb pointer to skbuff of association packet.
 *
 * Security hooks for Infiniband
 *
+12 −5
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ struct xfrm_policy;
struct xfrm_state;
struct xfrm_user_sec_ctx;
struct seq_file;
struct sctp_endpoint;
struct sctp_association;

#ifdef CONFIG_MMU
extern unsigned long mmap_min_addr;
@@ -1425,11 +1425,13 @@ 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_assoc_request(struct sctp_association *asoc, 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,
void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
			    struct sock *newsk);
void security_sctp_assoc_established(struct sctp_association *asoc,
				     struct sk_buff *skb);

#else	/* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct sock *sock,
@@ -1631,7 +1633,7 @@ static inline int security_tun_dev_open(void *security)
	return 0;
}

static inline int security_sctp_assoc_request(struct sctp_endpoint *ep,
static inline int security_sctp_assoc_request(struct sctp_association *asoc,
					      struct sk_buff *skb)
{
	return 0;
@@ -1644,11 +1646,16 @@ static inline int security_sctp_bind_connect(struct sock *sk, int optname,
	return 0;
}

static inline void security_sctp_sk_clone(struct sctp_endpoint *ep,
static inline void security_sctp_sk_clone(struct sctp_association *asoc,
					  struct sock *sk,
					  struct sock *newsk)
{
}

static inline void security_sctp_assoc_established(struct sctp_association *asoc,
						   struct sk_buff *skb)
{
}
#endif	/* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_INFINIBAND
+10 −10
Original line number Diff line number Diff line
@@ -1355,16 +1355,6 @@ struct sctp_endpoint {
	      reconf_enable:1;

	__u8  strreset_enable;

	/* Security identifiers from incoming (INIT). These are set by
	 * security_sctp_assoc_request(). These will only be used by
	 * SCTP TCP type sockets and peeled off connections as they
	 * cause a new socket to be generated. security_sctp_sk_clone()
	 * will then plug these into the new socket.
	 */

	u32 secid;
	u32 peer_secid;
};

/* Recover the outter endpoint structure. */
@@ -2104,6 +2094,16 @@ struct sctp_association {
	__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
	__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];

	/* Security identifiers from incoming (INIT). These are set by
	 * security_sctp_assoc_request(). These will only be used by
	 * SCTP TCP type sockets and peeled off connections as they
	 * cause a new socket to be generated. security_sctp_sk_clone()
	 * will then plug these into the new socket.
	 */

	u32 secid;
	u32 peer_secid;

	struct rcu_head rcu;
};

Loading