mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	security: pass asoc to sctp_assoc_request and sctp_sk_clone
This patch is to move secid and peer_secid from endpoint to association,
and pass asoc to sctp_assoc_request and sctp_sk_clone instead of ep. As
ep is the local endpoint and asoc represents a connection, and in SCTP
one sk/ep could have multiple asoc/connection, saving secid/peer_secid
for new asoc will overwrite the old asoc's.
Note that since asoc can be passed as NULL, security_sctp_assoc_request()
is moved to the place right after the new_asoc is created in
sctp_sf_do_5_1B_init() and sctp_sf_do_unexpected_init().
v1->v2:
  - fix the description of selinux_netlbl_skbuff_setsid(), as Jakub noticed.
  - fix the annotation in selinux_sctp_assoc_request(), as Richard Noticed.
Fixes: 72e89f5008 ("security: Add support for SCTP security hooks")
Reported-by: Prashanth Prahlad <pprahlad@redhat.com>
Reviewed-by: Richard Haines <richard_c_haines@btinternet.com>
Tested-by: Richard Haines <richard_c_haines@btinternet.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									843c3cbbdf
								
							
						
					
					
						commit
						c081d53f97
					
				
					 11 changed files with 76 additions and 77 deletions
				
			
		| 
						 | 
					@ -26,11 +26,11 @@ described in the `SCTP SELinux Support`_ chapter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
security_sctp_assoc_request()
 | 
					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.
 | 
					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.
 | 
					    @skb - pointer to skbuff of association packet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,9 +117,9 @@ Called whenever a new socket is created by **accept**\(2)
 | 
				
			||||||
calls **sctp_peeloff**\(3).
 | 
					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 current sock structure.
 | 
				
			||||||
    @sk - pointer to new sock structure.
 | 
					    @newsk - pointer to new sock structure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
security_inet_conn_established()
 | 
					security_inet_conn_established()
 | 
				
			||||||
| 
						 | 
					@ -200,22 +200,22 @@ hooks with the SELinux specifics expanded below::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
security_sctp_assoc_request()
 | 
					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.
 | 
					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.
 | 
					    @skb - pointer to skbuff of association packet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The security module performs the following operations:
 | 
					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
 | 
					     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.
 | 
					     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
 | 
					     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
 | 
					     TCP style sockets and peeled off connections as they cause a new socket
 | 
				
			||||||
     to be generated.
 | 
					     to be generated.
 | 
				
			||||||
| 
						 | 
					@ -259,13 +259,13 @@ security_sctp_sk_clone()
 | 
				
			||||||
Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
 | 
					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
 | 
					socket) or when a socket is 'peeled off' e.g userspace calls
 | 
				
			||||||
**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
 | 
					**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
 | 
				
			||||||
sockets sid and peer sid to that contained in the ``@ep sid`` and
 | 
					sockets sid and peer sid to that contained in the ``@asoc sid`` and
 | 
				
			||||||
``@ep peer sid`` respectively.
 | 
					``@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 current sock structure.
 | 
				
			||||||
    @sk - pointer to new sock structure.
 | 
					    @newsk - pointer to new sock structure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
security_inet_conn_established()
 | 
					security_inet_conn_established()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,11 +329,11 @@ 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_queue, void *security)
 | 
				
			||||||
LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, 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, 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)
 | 
						 struct sk_buff *skb)
 | 
				
			||||||
LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
 | 
					LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
 | 
				
			||||||
	 struct sockaddr *address, int addrlen)
 | 
						 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)
 | 
						 struct sock *sk, struct sock *newsk)
 | 
				
			||||||
#endif /* CONFIG_SECURITY_NETWORK */
 | 
					#endif /* CONFIG_SECURITY_NETWORK */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1027,9 +1027,9 @@
 | 
				
			||||||
 * Security hooks for SCTP
 | 
					 * Security hooks for SCTP
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @sctp_assoc_request:
 | 
					 * @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.
 | 
					 *	the security module.
 | 
				
			||||||
 *	@ep pointer to sctp endpoint structure.
 | 
					 *	@asoc pointer to sctp association structure.
 | 
				
			||||||
 *	@skb pointer to skbuff of association packet.
 | 
					 *	@skb pointer to skbuff of association packet.
 | 
				
			||||||
 *	Return 0 on success, error on failure.
 | 
					 *	Return 0 on success, error on failure.
 | 
				
			||||||
 * @sctp_bind_connect:
 | 
					 * @sctp_bind_connect:
 | 
				
			||||||
| 
						 | 
					@ -1047,9 +1047,9 @@
 | 
				
			||||||
 *	Called whenever a new socket is created by accept(2) (i.e. a TCP
 | 
					 *	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
 | 
					 *	style socket) or when a socket is 'peeled off' e.g userspace
 | 
				
			||||||
 *	calls sctp_peeloff(3).
 | 
					 *	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 current sock structure.
 | 
				
			||||||
 *	@sk pointer to new sock structure.
 | 
					 *	@newsk pointer to new sock structure.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Security hooks for Infiniband
 | 
					 * Security hooks for Infiniband
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,7 +179,7 @@ struct xfrm_policy;
 | 
				
			||||||
struct xfrm_state;
 | 
					struct xfrm_state;
 | 
				
			||||||
struct xfrm_user_sec_ctx;
 | 
					struct xfrm_user_sec_ctx;
 | 
				
			||||||
struct seq_file;
 | 
					struct seq_file;
 | 
				
			||||||
struct sctp_endpoint;
 | 
					struct sctp_association;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_MMU
 | 
					#ifdef CONFIG_MMU
 | 
				
			||||||
extern unsigned long mmap_min_addr;
 | 
					extern unsigned long mmap_min_addr;
 | 
				
			||||||
| 
						 | 
					@ -1425,10 +1425,10 @@ int security_tun_dev_create(void);
 | 
				
			||||||
int security_tun_dev_attach_queue(void *security);
 | 
					int security_tun_dev_attach_queue(void *security);
 | 
				
			||||||
int security_tun_dev_attach(struct sock *sk, void *security);
 | 
					int security_tun_dev_attach(struct sock *sk, void *security);
 | 
				
			||||||
int security_tun_dev_open(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,
 | 
					int security_sctp_bind_connect(struct sock *sk, int optname,
 | 
				
			||||||
			       struct sockaddr *address, int addrlen);
 | 
								       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);
 | 
								    struct sock *newsk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else	/* CONFIG_SECURITY_NETWORK */
 | 
					#else	/* CONFIG_SECURITY_NETWORK */
 | 
				
			||||||
| 
						 | 
					@ -1631,7 +1631,7 @@ static inline int security_tun_dev_open(void *security)
 | 
				
			||||||
	return 0;
 | 
						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)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -1644,7 +1644,7 @@ static inline int security_sctp_bind_connect(struct sock *sk, int optname,
 | 
				
			||||||
	return 0;
 | 
						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 *sk,
 | 
				
			||||||
					  struct sock *newsk)
 | 
										  struct sock *newsk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1355,16 +1355,6 @@ struct sctp_endpoint {
 | 
				
			||||||
	      reconf_enable:1;
 | 
						      reconf_enable:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__u8  strreset_enable;
 | 
						__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. */
 | 
					/* Recover the outter endpoint structure. */
 | 
				
			||||||
| 
						 | 
					@ -2104,6 +2094,16 @@ struct sctp_association {
 | 
				
			||||||
	__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
 | 
						__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
 | 
				
			||||||
	__u64 abandoned_sent[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;
 | 
						struct rcu_head rcu;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,11 +326,6 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
 | 
				
			||||||
	struct sctp_packet *packet;
 | 
						struct sctp_packet *packet;
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update socket peer label if first association. */
 | 
					 | 
				
			||||||
	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
 | 
					 | 
				
			||||||
					chunk->skb))
 | 
					 | 
				
			||||||
		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* 6.10 Bundling
 | 
						/* 6.10 Bundling
 | 
				
			||||||
	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 | 
						 * An endpoint MUST NOT bundle INIT, INIT ACK or
 | 
				
			||||||
	 * SHUTDOWN COMPLETE with any other chunks.
 | 
						 * SHUTDOWN COMPLETE with any other chunks.
 | 
				
			||||||
| 
						 | 
					@ -415,6 +410,12 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
 | 
				
			||||||
	if (!new_asoc)
 | 
						if (!new_asoc)
 | 
				
			||||||
		goto nomem;
 | 
							goto nomem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update socket peer label if first association. */
 | 
				
			||||||
 | 
						if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
 | 
				
			||||||
 | 
							sctp_association_free(new_asoc);
 | 
				
			||||||
 | 
							return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
 | 
						if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
 | 
				
			||||||
					     sctp_scope(sctp_source(chunk)),
 | 
										     sctp_scope(sctp_source(chunk)),
 | 
				
			||||||
					     GFP_ATOMIC) < 0)
 | 
										     GFP_ATOMIC) < 0)
 | 
				
			||||||
| 
						 | 
					@ -780,7 +781,6 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Delay state machine commands until later.
 | 
						/* Delay state machine commands until later.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * Re-build the bind address for the association is done in
 | 
						 * Re-build the bind address for the association is done in
 | 
				
			||||||
| 
						 | 
					@ -1517,11 +1517,6 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
 | 
				
			||||||
	struct sctp_packet *packet;
 | 
						struct sctp_packet *packet;
 | 
				
			||||||
	int len;
 | 
						int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update socket peer label if first association. */
 | 
					 | 
				
			||||||
	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
 | 
					 | 
				
			||||||
					chunk->skb))
 | 
					 | 
				
			||||||
		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* 6.10 Bundling
 | 
						/* 6.10 Bundling
 | 
				
			||||||
	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 | 
						 * An endpoint MUST NOT bundle INIT, INIT ACK or
 | 
				
			||||||
	 * SHUTDOWN COMPLETE with any other chunks.
 | 
						 * SHUTDOWN COMPLETE with any other chunks.
 | 
				
			||||||
| 
						 | 
					@ -1594,6 +1589,12 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
 | 
				
			||||||
	if (!new_asoc)
 | 
						if (!new_asoc)
 | 
				
			||||||
		goto nomem;
 | 
							goto nomem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update socket peer label if first association. */
 | 
				
			||||||
 | 
						if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
 | 
				
			||||||
 | 
							sctp_association_free(new_asoc);
 | 
				
			||||||
 | 
							return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
 | 
						if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
 | 
				
			||||||
				sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
 | 
									sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
 | 
				
			||||||
		goto nomem;
 | 
							goto nomem;
 | 
				
			||||||
| 
						 | 
					@ -2255,8 +2256,7 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update socket peer label if first association. */
 | 
						/* Update socket peer label if first association. */
 | 
				
			||||||
	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
 | 
						if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
 | 
				
			||||||
					chunk->skb)) {
 | 
					 | 
				
			||||||
		sctp_association_free(new_asoc);
 | 
							sctp_association_free(new_asoc);
 | 
				
			||||||
		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
							return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9412,7 +9412,6 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
 | 
				
			||||||
	struct inet_sock *inet = inet_sk(sk);
 | 
						struct inet_sock *inet = inet_sk(sk);
 | 
				
			||||||
	struct inet_sock *newinet;
 | 
						struct inet_sock *newinet;
 | 
				
			||||||
	struct sctp_sock *sp = sctp_sk(sk);
 | 
						struct sctp_sock *sp = sctp_sk(sk);
 | 
				
			||||||
	struct sctp_endpoint *ep = sp->ep;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newsk->sk_type = sk->sk_type;
 | 
						newsk->sk_type = sk->sk_type;
 | 
				
			||||||
	newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
 | 
						newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
 | 
				
			||||||
| 
						 | 
					@ -9457,9 +9456,9 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
 | 
				
			||||||
		net_enable_timestamp();
 | 
							net_enable_timestamp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set newsk security attributes from original sk and connection
 | 
						/* Set newsk security attributes from original sk and connection
 | 
				
			||||||
	 * security attribute from ep.
 | 
						 * security attribute from asoc.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	security_sctp_sk_clone(ep, sk, newsk);
 | 
						security_sctp_sk_clone(asoc, sk, newsk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void sctp_copy_descendant(struct sock *sk_to,
 | 
					static inline void sctp_copy_descendant(struct sock *sk_to,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2367,9 +2367,9 @@ int security_tun_dev_open(void *security)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(security_tun_dev_open);
 | 
					EXPORT_SYMBOL(security_tun_dev_open);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return call_int_hook(sctp_assoc_request, 0, ep, skb);
 | 
						return call_int_hook(sctp_assoc_request, 0, asoc, skb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(security_sctp_assoc_request);
 | 
					EXPORT_SYMBOL(security_sctp_assoc_request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2381,10 +2381,10 @@ int security_sctp_bind_connect(struct sock *sk, int optname,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(security_sctp_bind_connect);
 | 
					EXPORT_SYMBOL(security_sctp_bind_connect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
								    struct sock *newsk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	call_void_hook(sctp_sk_clone, ep, sk, newsk);
 | 
						call_void_hook(sctp_sk_clone, asoc, sk, newsk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(security_sctp_sk_clone);
 | 
					EXPORT_SYMBOL(security_sctp_sk_clone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5339,10 +5339,10 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
 | 
				
			||||||
 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
 | 
					 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
 | 
				
			||||||
 * already present).
 | 
					 * already present).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
					static int selinux_sctp_assoc_request(struct sctp_association *asoc,
 | 
				
			||||||
				      struct sk_buff *skb)
 | 
									      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_security_struct *sksec = ep->base.sk->sk_security;
 | 
						struct sk_security_struct *sksec = asoc->base.sk->sk_security;
 | 
				
			||||||
	struct common_audit_data ad;
 | 
						struct common_audit_data ad;
 | 
				
			||||||
	struct lsm_network_audit net = {0,};
 | 
						struct lsm_network_audit net = {0,};
 | 
				
			||||||
	u8 peerlbl_active;
 | 
						u8 peerlbl_active;
 | 
				
			||||||
| 
						 | 
					@ -5359,7 +5359,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
				
			||||||
		/* This will return peer_sid = SECSID_NULL if there are
 | 
							/* This will return peer_sid = SECSID_NULL if there are
 | 
				
			||||||
		 * no peer labels, see security_net_peersid_resolve().
 | 
							 * no peer labels, see security_net_peersid_resolve().
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
 | 
							err = selinux_skb_peerlbl_sid(skb, asoc->base.sk->sk_family,
 | 
				
			||||||
					      &peer_sid);
 | 
										      &peer_sid);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
| 
						 | 
					@ -5383,7 +5383,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		ad.type = LSM_AUDIT_DATA_NET;
 | 
							ad.type = LSM_AUDIT_DATA_NET;
 | 
				
			||||||
		ad.u.net = &net;
 | 
							ad.u.net = &net;
 | 
				
			||||||
		ad.u.net->sk = ep->base.sk;
 | 
							ad.u.net->sk = asoc->base.sk;
 | 
				
			||||||
		err = avc_has_perm(&selinux_state,
 | 
							err = avc_has_perm(&selinux_state,
 | 
				
			||||||
				   sksec->peer_sid, peer_sid, sksec->sclass,
 | 
									   sksec->peer_sid, peer_sid, sksec->sclass,
 | 
				
			||||||
				   SCTP_SOCKET__ASSOCIATION, &ad);
 | 
									   SCTP_SOCKET__ASSOCIATION, &ad);
 | 
				
			||||||
| 
						 | 
					@ -5392,7 +5392,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Compute the MLS component for the connection and store
 | 
						/* Compute the MLS component for the connection and store
 | 
				
			||||||
	 * the information in ep. This will be used by SCTP TCP type
 | 
						 * the information in asoc. This will be used by SCTP TCP type
 | 
				
			||||||
	 * sockets and peeled off connections as they cause a new
 | 
						 * sockets and peeled off connections as they cause a new
 | 
				
			||||||
	 * socket to be generated. selinux_sctp_sk_clone() will then
 | 
						 * socket to be generated. selinux_sctp_sk_clone() will then
 | 
				
			||||||
	 * plug this into the new socket.
 | 
						 * plug this into the new socket.
 | 
				
			||||||
| 
						 | 
					@ -5401,11 +5401,11 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ep->secid = conn_sid;
 | 
						asoc->secid = conn_sid;
 | 
				
			||||||
	ep->peer_secid = peer_sid;
 | 
						asoc->peer_secid = peer_sid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set any NetLabel labels including CIPSO/CALIPSO options. */
 | 
						/* Set any NetLabel labels including CIPSO/CALIPSO options. */
 | 
				
			||||||
	return selinux_netlbl_sctp_assoc_request(ep, skb);
 | 
						return selinux_netlbl_sctp_assoc_request(asoc, skb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
 | 
					/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
 | 
				
			||||||
| 
						 | 
					@ -5490,7 +5490,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
 | 
					/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
 | 
				
			||||||
static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
 | 
					static void selinux_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
 | 
				
			||||||
				  struct sock *newsk)
 | 
									  struct sock *newsk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_security_struct *sksec = sk->sk_security;
 | 
						struct sk_security_struct *sksec = sk->sk_security;
 | 
				
			||||||
| 
						 | 
					@ -5502,8 +5502,8 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
 | 
				
			||||||
	if (!selinux_policycap_extsockclass())
 | 
						if (!selinux_policycap_extsockclass())
 | 
				
			||||||
		return selinux_sk_clone_security(sk, newsk);
 | 
							return selinux_sk_clone_security(sk, newsk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newsksec->sid = ep->secid;
 | 
						newsksec->sid = asoc->secid;
 | 
				
			||||||
	newsksec->peer_sid = ep->peer_secid;
 | 
						newsksec->peer_sid = asoc->peer_secid;
 | 
				
			||||||
	newsksec->sclass = sksec->sclass;
 | 
						newsksec->sclass = sksec->sclass;
 | 
				
			||||||
	selinux_netlbl_sctp_sk_clone(sk, newsk);
 | 
						selinux_netlbl_sctp_sk_clone(sk, newsk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 | 
				
			||||||
int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 | 
					int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 | 
				
			||||||
				 u16 family,
 | 
									 u16 family,
 | 
				
			||||||
				 u32 sid);
 | 
									 u32 sid);
 | 
				
			||||||
int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
					int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
 | 
				
			||||||
				     struct sk_buff *skb);
 | 
									     struct sk_buff *skb);
 | 
				
			||||||
int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
 | 
					int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
 | 
				
			||||||
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
 | 
					void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
					static inline int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
 | 
				
			||||||
						    struct sk_buff *skb)
 | 
											    struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -261,30 +261,30 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association.
 | 
					 * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association.
 | 
				
			||||||
 * @ep: incoming association endpoint.
 | 
					 * @asoc: incoming association.
 | 
				
			||||||
 * @skb: the packet.
 | 
					 * @skb: the packet.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Description:
 | 
					 * Description:
 | 
				
			||||||
 * A new incoming connection is represented by @ep, ......
 | 
					 * A new incoming connection is represented by @asoc, ......
 | 
				
			||||||
 * Returns zero on success, negative values on failure.
 | 
					 * Returns zero on success, negative values on failure.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
					int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
 | 
				
			||||||
				     struct sk_buff *skb)
 | 
									     struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
	struct netlbl_lsm_secattr secattr;
 | 
						struct netlbl_lsm_secattr secattr;
 | 
				
			||||||
	struct sk_security_struct *sksec = ep->base.sk->sk_security;
 | 
						struct sk_security_struct *sksec = asoc->base.sk->sk_security;
 | 
				
			||||||
	struct sockaddr_in addr4;
 | 
						struct sockaddr_in addr4;
 | 
				
			||||||
	struct sockaddr_in6 addr6;
 | 
						struct sockaddr_in6 addr6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ep->base.sk->sk_family != PF_INET &&
 | 
						if (asoc->base.sk->sk_family != PF_INET &&
 | 
				
			||||||
				ep->base.sk->sk_family != PF_INET6)
 | 
						    asoc->base.sk->sk_family != PF_INET6)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netlbl_secattr_init(&secattr);
 | 
						netlbl_secattr_init(&secattr);
 | 
				
			||||||
	rc = security_netlbl_sid_to_secattr(&selinux_state,
 | 
						rc = security_netlbl_sid_to_secattr(&selinux_state,
 | 
				
			||||||
					    ep->secid, &secattr);
 | 
										    asoc->secid, &secattr);
 | 
				
			||||||
	if (rc != 0)
 | 
						if (rc != 0)
 | 
				
			||||||
		goto assoc_request_return;
 | 
							goto assoc_request_return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,11 +294,11 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
 | 
				
			||||||
	if (ip_hdr(skb)->version == 4) {
 | 
						if (ip_hdr(skb)->version == 4) {
 | 
				
			||||||
		addr4.sin_family = AF_INET;
 | 
							addr4.sin_family = AF_INET;
 | 
				
			||||||
		addr4.sin_addr.s_addr = ip_hdr(skb)->saddr;
 | 
							addr4.sin_addr.s_addr = ip_hdr(skb)->saddr;
 | 
				
			||||||
		rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr);
 | 
							rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr4, &secattr);
 | 
				
			||||||
	} else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) {
 | 
						} else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) {
 | 
				
			||||||
		addr6.sin6_family = AF_INET6;
 | 
							addr6.sin6_family = AF_INET6;
 | 
				
			||||||
		addr6.sin6_addr = ipv6_hdr(skb)->saddr;
 | 
							addr6.sin6_addr = ipv6_hdr(skb)->saddr;
 | 
				
			||||||
		rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr);
 | 
							rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr6, &secattr);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		rc = -EAFNOSUPPORT;
 | 
							rc = -EAFNOSUPPORT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue