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

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

[MLSXFRM]: Default labeling of socket specific IPSec policies



This defaults the label of socket-specific IPSec policies to be the
same as the socket they are set on.

Signed-off-by: default avatarVenkat Yekkirala <vyekkirala@TrustedCS.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent beb8d13b
Loading
Loading
Loading
Loading
+16 −3
Original line number Original line Diff line number Diff line
@@ -827,8 +827,10 @@ struct swap_info_struct;
 *	used by the XFRM system.
 *	used by the XFRM system.
 *	@sec_ctx contains the security context information being provided by
 *	@sec_ctx contains the security context information being provided by
 *	the user-level policy update program (e.g., setkey).
 *	the user-level policy update program (e.g., setkey).
 *	@sk refers to the sock from which to derive the security context.
 *	Allocate a security structure to the xp->security field; the security
 *	Allocate a security structure to the xp->security field; the security
 *	field is initialized to NULL when the xfrm_policy is allocated.
 *	field is initialized to NULL when the xfrm_policy is allocated. Only
 *	one of sec_ctx or sock can be specified.
 *	Return 0 if operation was successful (memory to allocate, legal context)
 *	Return 0 if operation was successful (memory to allocate, legal context)
 * @xfrm_policy_clone_security:
 * @xfrm_policy_clone_security:
 *	@old contains an existing xfrm_policy in the SPD.
 *	@old contains an existing xfrm_policy in the SPD.
@@ -1359,7 +1361,8 @@ struct security_operations {
#endif	/* CONFIG_SECURITY_NETWORK */
#endif	/* CONFIG_SECURITY_NETWORK */


#ifdef CONFIG_SECURITY_NETWORK_XFRM
#ifdef CONFIG_SECURITY_NETWORK_XFRM
	int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
	int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp,
			struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk);
	int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
	int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
	void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
	void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
	int (*xfrm_policy_delete_security) (struct xfrm_policy *xp);
	int (*xfrm_policy_delete_security) (struct xfrm_policy *xp);
@@ -3057,7 +3060,12 @@ static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
#ifdef CONFIG_SECURITY_NETWORK_XFRM
#ifdef CONFIG_SECURITY_NETWORK_XFRM
static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
{
{
	return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
	return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL);
}

static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
{
	return security_ops->xfrm_policy_alloc_security(xp, NULL, sk);
}
}


static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
@@ -3132,6 +3140,11 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
	return 0;
	return 0;
}
}


static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
{
	return 0;
}

static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
{
{
	return 0;
	return 0;
+1 −1
Original line number Original line Diff line number Diff line
@@ -362,7 +362,7 @@ struct xfrm_mgr
	char			*id;
	char			*id;
	int			(*notify)(struct xfrm_state *x, struct km_event *c);
	int			(*notify)(struct xfrm_state *x, struct km_event *c);
	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
	struct xfrm_policy	*(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir);
	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
	int			(*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
	int			(*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
};
};
+11 −4
Original line number Original line Diff line number Diff line
@@ -2843,14 +2843,14 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
}
}


static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
                                                u8 *data, int len, int *dir)
                                                u8 *data, int len, int *dir)
{
{
	struct xfrm_policy *xp;
	struct xfrm_policy *xp;
	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
	struct sadb_x_sec_ctx *sec_ctx;
	struct sadb_x_sec_ctx *sec_ctx;


	switch (family) {
	switch (sk->sk_family) {
	case AF_INET:
	case AF_INET:
		if (opt != IP_IPSEC_POLICY) {
		if (opt != IP_IPSEC_POLICY) {
			*dir = -EOPNOTSUPP;
			*dir = -EOPNOTSUPP;
@@ -2891,7 +2891,7 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
	xp->lft.hard_byte_limit = XFRM_INF;
	xp->lft.hard_byte_limit = XFRM_INF;
	xp->lft.soft_packet_limit = XFRM_INF;
	xp->lft.soft_packet_limit = XFRM_INF;
	xp->lft.hard_packet_limit = XFRM_INF;
	xp->lft.hard_packet_limit = XFRM_INF;
	xp->family = family;
	xp->family = sk->sk_family;


	xp->xfrm_nr = 0;
	xp->xfrm_nr = 0;
	if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&
	if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&
@@ -2907,8 +2907,10 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
		p += pol->sadb_x_policy_len*8;
		p += pol->sadb_x_policy_len*8;
		sec_ctx = (struct sadb_x_sec_ctx *)p;
		sec_ctx = (struct sadb_x_sec_ctx *)p;
		if (len < pol->sadb_x_policy_len*8 +
		if (len < pol->sadb_x_policy_len*8 +
		    sec_ctx->sadb_x_sec_len)
		    sec_ctx->sadb_x_sec_len) {
			*dir = -EINVAL;
			goto out;
			goto out;
		}
		if ((*dir = verify_sec_ctx_len(p)))
		if ((*dir = verify_sec_ctx_len(p)))
			goto out;
			goto out;
		uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
		uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
@@ -2918,6 +2920,11 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
		if (*dir)
		if (*dir)
			goto out;
			goto out;
	}
	}
	else {
		*dir = security_xfrm_sock_policy_alloc(xp, sk);
		if (*dir)
			goto out;
	}


	*dir = pol->sadb_x_policy_dir-1;
	*dir = pol->sadb_x_policy_dir-1;
	return xp;
	return xp;
+1 −1
Original line number Original line Diff line number Diff line
@@ -1026,7 +1026,7 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
	err = -EINVAL;
	err = -EINVAL;
	read_lock(&xfrm_km_lock);
	read_lock(&xfrm_km_lock);
	list_for_each_entry(km, &xfrm_km_list, list) {
	list_for_each_entry(km, &xfrm_km_list, list) {
		pol = km->compile_policy(sk->sk_family, optname, data,
		pol = km->compile_policy(sk, optname, data,
					 optlen, &err);
					 optlen, &err);
		if (err >= 0)
		if (err >= 0)
			break;
			break;
+11 −2
Original line number Original line Diff line number Diff line
@@ -1757,7 +1757,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
/* User gives us xfrm_user_policy_info followed by an array of 0
/* User gives us xfrm_user_policy_info followed by an array of 0
 * or more templates.
 * or more templates.
 */
 */
static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
					       u8 *data, int len, int *dir)
					       u8 *data, int len, int *dir)
{
{
	struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
	struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
@@ -1765,7 +1765,7 @@ static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
	struct xfrm_policy *xp;
	struct xfrm_policy *xp;
	int nr;
	int nr;


	switch (family) {
	switch (sk->sk_family) {
	case AF_INET:
	case AF_INET:
		if (opt != IP_XFRM_POLICY) {
		if (opt != IP_XFRM_POLICY) {
			*dir = -EOPNOTSUPP;
			*dir = -EOPNOTSUPP;
@@ -1807,6 +1807,15 @@ static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
	copy_from_user_policy(xp, p);
	copy_from_user_policy(xp, p);
	copy_templates(xp, ut, nr);
	copy_templates(xp, ut, nr);


	if (!xp->security) {
		int err = security_xfrm_sock_policy_alloc(xp, sk);
		if (err) {
			kfree(xp);
			*dir = err;
			return NULL;
		}
	}

	*dir = p->dir;
	*dir = p->dir;


	return xp;
	return xp;
Loading