[RFC PATCH 1/5] security: Add support for SCTP security hooks

Paul Moore paul at paul-moore.com
Mon Nov 6 22:35:57 UTC 2017


On Tue, Oct 17, 2017 at 10:02 AM, Richard Haines
<richard_c_haines at btinternet.com> wrote:
> The SCTP security hooks are explained in:
> Documentation/security/LSM-sctp.txt
>
> Signed-off-by: Richard Haines <richard_c_haines at btinternet.com>
> ---
>  Documentation/security/LSM-sctp.txt | 212 ++++++++++++++++++++++++++++++++++++
>  include/linux/lsm_hooks.h           |  37 +++++++
>  include/linux/security.h            |  27 +++++
>  security/security.c                 |  23 ++++
>  4 files changed, 299 insertions(+)
>  create mode 100644 Documentation/security/LSM-sctp.txt

Hi Richard,

Thanks for sticking with this, I really appreciate the effort you're
putting into this and I apologize it has taken me a few weeks to get
to reviewing this patchset ... comments below.

> diff --git a/Documentation/security/LSM-sctp.txt b/Documentation/security/LSM-sctp.txt
> new file mode 100644
> index 0000000..30fe9b5
> --- /dev/null
> +++ b/Documentation/security/LSM-sctp.txt
> @@ -0,0 +1,212 @@

There is a push to convert the docs under Documentation/ to use the
reStructuredText format; from what I can tell this shouldn't have a
major impact on what you've already written, just a few formatting
tweaks.  If you can convert the SCTP/LSM/SELinux docs over to RST that
would be very nice.

> +                               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.txt
> +
> +
> +security_sctp_assoc_request()
> +------------------------------
> +This new hook has been added to net/sctp/sm_statefuns.c where it passes the

I would probably avoid calling out specific source files in this
document as the code is almost certain to change at some point (moving
the LSM hook) and I can almost guarantee we'll forget to update this
document.  I think it's better to say something like this:

  "This new hook passes the @ep ..."

> + at ep and @chunk->skb (the association INIT or INIT ACK 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.
> +    @sctp_cid - set to sctp packet type (SCTP_CID_INIT or SCTP_CID_INIT_ACK).

Once again, I must beg patience with my poor understanding of SCTP,
I'm quickly skimming through the RFCs but I'm sure to get some things
wrong.

> +The security module performs the following operations:
> +  1) If this is the first association on @ep->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.

Conceptually this is similar to selinux_inet_conn_request(), yes?
Setting the peer label of a new connection/association triggered by a
remote request.

I'm sure we'll get into this later once I get to the code itself, but
I wonder if we should be tracking the peer label in the endpoint?
Would we ever want to allow multiple different peer labels on a single
endpoint?  That seems a bit crazy to me.  Although it might just be
easier from an implementation perspective to reuse the existing
sksec->peer_sid field ...

> +  2) If not the first association, validate the @ep->base.sk peer_sid against
> +     the @skb peer sid to determine whether the association should be allowed
> +     or denied.

This is possible because SCTP allows multiple associations per
endpoint, yes?  I imagine that most (all?) LSMs would want to restrict
this such that all associations for a given endpoint have the same
label.

> +  3) If @sctp_cid = SCTP_CID_INIT, then set the sctp @ep sid to socket's sid
> +     (from ep->base.sk) with MLS portion taken from @skb peer sid. This will
> +     only be used by SCTP TCP style sockets and peeled off connections as they
> +     cause a new socket to be generated.

Once again, the same logic as in
selinux_inet_conn_request()/selinux_conn_sid(), yes?

Presumably we don't need to do anything special for the
SCTP_CID_INIT_ACK case as this is the client side of the connection,
yes?

> +     If IP security options are configured (CIPSO/CALIPSO), then the ip options
> +     are set on the socket.
> +
> +     To support this hook include/net/sctp/structs.h "struct sctp_endpoint"
> +     has been updated with the following:
> +
> +       /* 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;

I would drop the filename and code details for the reasons mentioned above.

> +security_sctp_bind_connect()
> +-----------------------------
> +This new hook has been added to net/sctp/socket.c and net/sctp/sm_make_chunk.c.

See previous comments on filenames/code.

> +It 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       |
> +  ------------------------------------------------------------------

I'm guessing/hoping the reasons for multiplexing all of these
operations onto a single LSM hook will make sense when I get to the
code.

> +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 setsockopts):
> +    /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()
> +-------------------------
> +This new hook has been added to net/sctp/socket.c sctp_sock_migrate() that is

See my previous comments on filenames/code.

> +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).

You can only "peeloff" a socket from a one-to-many socket, not a
one-to-one socket, yes?

(If I'm understanding SCTP correctly, it wouldn't make sense to have a
many-to-one socket, yes?)

> +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.
> +
> +    @ep - pointer to old sctp endpoint structure.
> +    @sk - pointer to old sock structure.
> +    @sk - pointer to new sock structure.
> +
> +security_inet_conn_established()
> +---------------------------------
> +This hook has been added to net/sctp/sm_statefuns.c COOKIE ECHO processing

See my previous comments on filenames/code.

> +where it sets the connection's peer sid to that in @skb.
> +
> +    @sk  - pointer to sock structure.
> +    @skb - pointer to skbuff of the COOKIE ECHO packet.
> +
> +
> +Security Hooks used for Association Establishment
> +==================================================
> +The following diagram shows the use of security_sctp_connect_bind(),
> +security_sctp_assoc_request(), security_inet_conn_established() in
> +net/sctp/sm_statefuns.c and security_sctp_sk_clone() in net/sctp/socket.c,
> +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.

I'm guessing there is no IETF/RFC guidance on using SCTP in a labeled
network environment?  I was just wondering if we should send a ICMP
error back to the other end of the association; I'm guessing we should
defer to the underlying protocol.  While CIPSO predates SCTP, it seems
in keeping with the CIPSO protocol that we would send an ICMP error,
however I imagine that with CALIPSO we would want to silently drop the
packet.

> +    sctp_sf_do_5_1C_ack
> + Respond to an INIT ACK chunk.
> + SCTP peer endpoint"A" initiated
> + this association to SCTP peer
> + endpoint "Z". Call
> + security_sctp_assoc_request()
> + to set the peer label if first
> + association. If not first
> + association, check whether
> + allowed, IF so send:
> +    COOKIE ECHO ------------------------------------------>
> + ELSE audit event and silently                            |
> +      discard the packet.                                 |

Same as above with respect to handling LSM denials.

> +                                                          |
> +          <------------------------------------------- COOKIE ACK
> +          |                                               |
> +    sctp_sf_do_5_1E_ca                                    |
> + Call security_inet_conn_established()                    |
> + to set the correct peer sid.                             |

We would only get here if this association was the first for a given
endpoint, yes?

> +          |                                               |
> +          |                               net/sctp/socket.c sctp_copy_sock()
> +          |                               If SCTP_SOCKET_TCP or peeled off
> +          |                               socket security_sctp_sk_clone() is
> +          |                               called to clone the new socket.

In this case we are establishing a new association for a given endpoint, yes?

> +          |                                               |
> +      ESTABLISHED                                    ESTABLISHED
> +          |                                               |
> +    ------------------------------------------------------------------
> +    |                     Association Established                    |
> +    ------------------------------------------------------------------
> +
> +

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the Linux-security-module-archive mailing list