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

Commit 4237c75c authored by Venkat Yekkirala's avatar Venkat Yekkirala Committed by David S. Miller
Browse files

[MLSXFRM]: Auto-labeling of child sockets



This automatically labels the TCP, Unix stream, and dccp child sockets
as well as openreqs to be at the same MLS level as the peer. This will
result in the selection of appropriately labeled IPSec Security
Associations.

This also uses the sock's sid (as opposed to the isec sid) in SELinux
enforcement of secmark in rcv_skb and postroute_last hooks.

Signed-off-by: default avatarVenkat Yekkirala <vyekkirala@TrustedCS.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cb969f07
Loading
Loading
Loading
Loading
+55 −0
Original line number Original line Diff line number Diff line
@@ -90,6 +90,7 @@ extern int cap_netlink_recv(struct sk_buff *skb, int cap);
struct nfsctl_arg;
struct nfsctl_arg;
struct sched_param;
struct sched_param;
struct swap_info_struct;
struct swap_info_struct;
struct request_sock;


/* bprm_apply_creds unsafe reasons */
/* bprm_apply_creds unsafe reasons */
#define LSM_UNSAFE_SHARE	1
#define LSM_UNSAFE_SHARE	1
@@ -819,6 +820,14 @@ struct swap_info_struct;
 * @sk_getsecid:
 * @sk_getsecid:
 *	Retrieve the LSM-specific secid for the sock to enable caching of network
 *	Retrieve the LSM-specific secid for the sock to enable caching of network
 *	authorizations.
 *	authorizations.
 * @sock_graft:
 *	Sets the socket's isec sid to the sock's sid.
 * @inet_conn_request:
 *	Sets the openreq's sid to socket's sid with MLS portion taken from peer sid.
 * @inet_csk_clone:
 *	Sets the new child socket's sid to the openreq sid.
 * @req_classify_flow:
 *	Sets the flow's sid to the openreq sid.
 *
 *
 * Security hooks for XFRM operations.
 * Security hooks for XFRM operations.
 *
 *
@@ -1358,6 +1367,11 @@ struct security_operations {
	void (*sk_free_security) (struct sock *sk);
	void (*sk_free_security) (struct sock *sk);
	void (*sk_clone_security) (const struct sock *sk, struct sock *newsk);
	void (*sk_clone_security) (const struct sock *sk, struct sock *newsk);
	void (*sk_getsecid) (struct sock *sk, u32 *secid);
	void (*sk_getsecid) (struct sock *sk, u32 *secid);
	void (*sock_graft)(struct sock* sk, struct socket *parent);
	int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb,
					struct request_sock *req);
	void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req);
	void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl);
#endif	/* CONFIG_SECURITY_NETWORK */
#endif	/* CONFIG_SECURITY_NETWORK */


#ifdef CONFIG_SECURITY_NETWORK_XFRM
#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2926,6 +2940,28 @@ static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
{
{
	security_ops->sk_getsecid(sk, &fl->secid);
	security_ops->sk_getsecid(sk, &fl->secid);
}
}

static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
{
	security_ops->req_classify_flow(req, fl);
}

static inline void security_sock_graft(struct sock* sk, struct socket *parent)
{
	security_ops->sock_graft(sk, parent);
}

static inline int security_inet_conn_request(struct sock *sk,
			struct sk_buff *skb, struct request_sock *req)
{
	return security_ops->inet_conn_request(sk, skb, req);
}

static inline void security_inet_csk_clone(struct sock *newsk,
			const struct request_sock *req)
{
	security_ops->inet_csk_clone(newsk, req);
}
#else	/* CONFIG_SECURITY_NETWORK */
#else	/* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct socket * sock,
static inline int security_unix_stream_connect(struct socket * sock,
					       struct socket * other, 
					       struct socket * other, 
@@ -3055,6 +3091,25 @@ static inline void security_sk_clone(const struct sock *sk, struct sock *newsk)
static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
{
{
}
}

static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
{
}

static inline void security_sock_graft(struct sock* sk, struct socket *parent)
{
}

static inline int security_inet_conn_request(struct sock *sk,
			struct sk_buff *skb, struct request_sock *req)
{
	return 0;
}

static inline void security_inet_csk_clone(struct sock *newsk,
			const struct request_sock *req)
{
}
#endif	/* CONFIG_SECURITY_NETWORK */
#endif	/* CONFIG_SECURITY_NETWORK */


#ifdef CONFIG_SECURITY_NETWORK_XFRM
#ifdef CONFIG_SECURITY_NETWORK_XFRM
+1 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ struct request_sock {
	unsigned long			expires;
	unsigned long			expires;
	struct request_sock_ops		*rsk_ops;
	struct request_sock_ops		*rsk_ops;
	struct sock			*sk;
	struct sock			*sk;
	u32				secid;
};
};


static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
+1 −0
Original line number Original line Diff line number Diff line
@@ -969,6 +969,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
	sk->sk_sleep = &parent->wait;
	sk->sk_sleep = &parent->wait;
	parent->sk = sk;
	parent->sk = sk;
	sk->sk_socket = parent;
	sk->sk_socket = parent;
	security_sock_graft(sk, parent);
	write_unlock_bh(&sk->sk_callback_lock);
	write_unlock_bh(&sk->sk_callback_lock);
}
}


+3 −0
Original line number Original line Diff line number Diff line
@@ -501,6 +501,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)


	dccp_openreq_init(req, &dp, skb);
	dccp_openreq_init(req, &dp, skb);


	if (security_inet_conn_request(sk, skb, req))
		goto drop_and_free;

	ireq = inet_rsk(req);
	ireq = inet_rsk(req);
	ireq->loc_addr = daddr;
	ireq->loc_addr = daddr;
	ireq->rmt_addr = saddr;
	ireq->rmt_addr = saddr;
+5 −2
Original line number Original line Diff line number Diff line
@@ -424,7 +424,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
	fl.oif = ireq6->iif;
	fl.oif = ireq6->iif;
	fl.fl_ip_dport = inet_rsk(req)->rmt_port;
	fl.fl_ip_dport = inet_rsk(req)->rmt_port;
	fl.fl_ip_sport = inet_sk(sk)->sport;
	fl.fl_ip_sport = inet_sk(sk)->sport;
	security_sk_classify_flow(sk, &fl);
	security_req_classify_flow(req, &fl);


	if (dst == NULL) {
	if (dst == NULL) {
		opt = np->opt;
		opt = np->opt;
@@ -626,7 +626,7 @@ static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb,
	fl.oif = inet6_iif(rxskb);
	fl.oif = inet6_iif(rxskb);
	fl.fl_ip_dport = dh->dccph_dport;
	fl.fl_ip_dport = dh->dccph_dport;
	fl.fl_ip_sport = dh->dccph_sport;
	fl.fl_ip_sport = dh->dccph_sport;
	security_skb_classify_flow(rxskb, &fl);
	security_req_classify_flow(req, &fl);


	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
@@ -709,6 +709,9 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)


	dccp_openreq_init(req, &dp, skb);
	dccp_openreq_init(req, &dp, skb);


	if (security_inet_conn_request(sk, skb, req))
		goto drop_and_free;

	ireq6 = inet6_rsk(req);
	ireq6 = inet6_rsk(req);
	ireq = inet_rsk(req);
	ireq = inet_rsk(req);
	ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
	ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
Loading