All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Moore <paul@paul-moore.com>
To: Richard Haines <richard_c_haines@btinternet.com>
Cc: selinux@tycho.nsa.gov, netdev@vger.kernel.org,
	linux-sctp@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	Vlad Yasevich <vyasevich@gmail.com>,
	nhorman@tuxdriver.com, Stephen Smalley <sds@tycho.nsa.gov>,
	Eric Paris <eparis@parisplace.org>,
	marcelo.leitner@gmail.com
Subject: Re: [RFC PATCH 1/5] security: Add support for SCTP security hooks
Date: Mon, 6 Nov 2017 17:35:57 -0500	[thread overview]
Message-ID: <CAHC9VhQcJZ740fP+9C-Ht-qUQDJUB4N66CRJYvJWKjGtAB+5tQ@mail.gmail.com> (raw)
In-Reply-To: <20171017140247.4604-1-richard_c_haines@btinternet.com>

On Tue, Oct 17, 2017 at 10:02 AM, Richard Haines
<richard_c_haines@btinternet.com> wrote:
> The SCTP security hooks are explained in:
> Documentation/security/LSM-sctp.txt
>
> Signed-off-by: Richard Haines <richard_c_haines@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 ..."

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

WARNING: multiple messages have this Message-ID (diff)
From: Paul Moore <paul@paul-moore.com>
To: linux-security-module@vger.kernel.org
Subject: Re: [RFC PATCH 1/5] security: Add support for SCTP security hooks
Date: Mon, 06 Nov 2017 22:35:57 +0000	[thread overview]
Message-ID: <CAHC9VhQcJZ740fP+9C-Ht-qUQDJUB4N66CRJYvJWKjGtAB+5tQ@mail.gmail.com> (raw)
In-Reply-To: <20171017140247.4604-1-richard_c_haines@btinternet.com>

On Tue, Oct 17, 2017 at 10:02 AM, Richard Haines
<richard_c_haines@btinternet.com> wrote:
> The SCTP security hooks are explained in:
> Documentation/security/LSM-sctp.txt
>
> Signed-off-by: Richard Haines <richard_c_haines@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 ..."

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

WARNING: multiple messages have this Message-ID (diff)
From: paul@paul-moore.com (Paul Moore)
To: linux-security-module@vger.kernel.org
Subject: [RFC PATCH 1/5] security: Add support for SCTP security hooks
Date: Mon, 6 Nov 2017 17:35:57 -0500	[thread overview]
Message-ID: <CAHC9VhQcJZ740fP+9C-Ht-qUQDJUB4N66CRJYvJWKjGtAB+5tQ@mail.gmail.com> (raw)
In-Reply-To: <20171017140247.4604-1-richard_c_haines@btinternet.com>

On Tue, Oct 17, 2017 at 10:02 AM, Richard Haines
<richard_c_haines@btinternet.com> wrote:
> The SCTP security hooks are explained in:
> Documentation/security/LSM-sctp.txt
>
> Signed-off-by: Richard Haines <richard_c_haines@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

  parent reply	other threads:[~2017-11-06 22:36 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-17 14:02 [RFC PATCH 1/5] security: Add support for SCTP security hooks Richard Haines
2017-10-17 14:02 ` Richard Haines
2017-10-17 14:02 ` Richard Haines
2017-10-20  4:53 ` James Morris
2017-10-20  4:53   ` James Morris
2017-10-20  4:53   ` James Morris
2017-10-31 16:41 ` Marcelo Ricardo Leitner
2017-10-31 16:41   ` Marcelo Ricardo Leitner
2017-10-31 16:41   ` Marcelo Ricardo Leitner
2017-11-01 21:38   ` Richard Haines
2017-11-01 21:38     ` Richard Haines
2017-11-01 21:38     ` Richard Haines
2017-11-06 22:35 ` Paul Moore [this message]
2017-11-06 22:35   ` Paul Moore
2017-11-06 22:35   ` Paul Moore

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAHC9VhQcJZ740fP+9C-Ht-qUQDJUB4N66CRJYvJWKjGtAB+5tQ@mail.gmail.com \
    --to=paul@paul-moore.com \
    --cc=eparis@parisplace.org \
    --cc=linux-sctp@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=marcelo.leitner@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    --cc=richard_c_haines@btinternet.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    --cc=vyasevich@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.