mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
[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: Venkat Yekkirala <vyekkirala@TrustedCS.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
beb8d13bed
commit
cb969f072b
8 changed files with 66 additions and 24 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -815,7 +815,8 @@ static inline void dummy_sk_getsecid(struct sock *sk, u32 *secid)
|
||||||
#endif /* CONFIG_SECURITY_NETWORK */
|
#endif /* CONFIG_SECURITY_NETWORK */
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||||
static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
|
static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp,
|
||||||
|
struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#ifndef _SELINUX_XFRM_H_
|
#ifndef _SELINUX_XFRM_H_
|
||||||
#define _SELINUX_XFRM_H_
|
#define _SELINUX_XFRM_H_
|
||||||
|
|
||||||
int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
|
int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
|
||||||
|
struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk);
|
||||||
int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
|
int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
|
||||||
void selinux_xfrm_policy_free(struct xfrm_policy *xp);
|
void selinux_xfrm_policy_free(struct xfrm_policy *xp);
|
||||||
int selinux_xfrm_policy_delete(struct xfrm_policy *xp);
|
int selinux_xfrm_policy_delete(struct xfrm_policy *xp);
|
||||||
|
|
|
@ -208,10 +208,8 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
|
||||||
|
|
||||||
BUG_ON(uctx && pol);
|
BUG_ON(uctx && pol);
|
||||||
|
|
||||||
if (pol)
|
if (!uctx)
|
||||||
goto from_policy;
|
goto not_from_user;
|
||||||
|
|
||||||
BUG_ON(!uctx);
|
|
||||||
|
|
||||||
if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
|
if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -251,11 +249,14 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
from_policy:
|
not_from_user:
|
||||||
BUG_ON(!pol);
|
if (pol) {
|
||||||
rc = security_sid_mls_copy(pol->ctx_sid, sid, &ctx_sid);
|
rc = security_sid_mls_copy(pol->ctx_sid, sid, &ctx_sid);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ctx_sid = sid;
|
||||||
|
|
||||||
rc = security_sid_to_context(ctx_sid, &ctx_str, &str_len);
|
rc = security_sid_to_context(ctx_sid, &ctx_str, &str_len);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -293,13 +294,23 @@ out2:
|
||||||
* LSM hook implementation that allocs and transfers uctx spec to
|
* LSM hook implementation that allocs and transfers uctx spec to
|
||||||
* xfrm_policy.
|
* xfrm_policy.
|
||||||
*/
|
*/
|
||||||
int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx)
|
int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
|
||||||
|
struct xfrm_user_sec_ctx *uctx, struct sock *sk)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
u32 sid;
|
||||||
|
|
||||||
BUG_ON(!xp);
|
BUG_ON(!xp);
|
||||||
|
BUG_ON(uctx && sk);
|
||||||
|
|
||||||
err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, NULL, 0);
|
if (sk) {
|
||||||
|
struct sk_security_struct *ssec = sk->sk_security;
|
||||||
|
sid = ssec->sid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sid = SECSID_NULL;
|
||||||
|
|
||||||
|
err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, NULL, sid);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue