This patch automatically labels IPSec policy set on a socket to be
the same as the label of the socket. This would enable applications
that set IPSec policy on their sockets to run without having to be modified
to pass the security context along with the IPSec policy rule.
The next patch will cover auto-labeling of TCP child sockets.
---
include/linux/security.h | 19 +++++++++++++++---
include/net/xfrm.h | 2 -
net/key/af_key.c | 15 ++++++++++----
net/xfrm/xfrm_state.c | 2 -
net/xfrm/xfrm_user.c | 13 ++++++++++--
security/dummy.c | 3 +-
security/selinux/include/xfrm.h | 3 +-
security/selinux/xfrm.c | 31 +++++++++++++++++++++---------
8 files changed, 66 insertions(+), 22 deletions(-)
--- linux-2.6.17.i686.patch11.2/include/linux/security.h 2006-07-05
14:51:16.000000000 -0500
+++ linux-2.6.17.i686/include/linux/security.h 2006-07-06 10:33:07.000000000
-0500
@@ -809,8 +809,10 @@ struct swap_info_struct;
* used by the XFRM system.
* @sec_ctx contains the security context information being provided by
* 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
- * 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)
* @xfrm_policy_clone_security:
* @old contains an existing xfrm_policy in the SPD.
@@ -1318,7 +1320,8 @@ struct security_operations {
#endif /* CONFIG_SECURITY_NETWORK */
#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);
void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
int (*xfrm_state_alloc_security) (struct xfrm_state *x,
@@ -2959,7 +2962,12 @@ static inline void security_sk_sid(struc
#ifdef CONFIG_SECURITY_NETWORK_XFRM
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)
@@ -3020,6 +3028,11 @@ static inline int security_xfrm_policy_a
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)
{
return 0;
--- linux-2.6.17.i686.patch11.2/include/net/xfrm.h 2006-07-06
09:49:35.000000000 -0500
+++ linux-2.6.17.i686/include/net/xfrm.h 2006-07-06 09:51:07.000000000
-0500
@@ -353,7 +353,7 @@ struct xfrm_mgr
char *id;
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);
- 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 (*notify_policy)(struct xfrm_policy *x, int
dir, struct km_event *c);
};
--- linux-2.6.17.i686.patch11.2/security/dummy.c 2006-07-06
11:01:07.000000000 -0500
+++ linux-2.6.17.i686/security/dummy.c 2006-07-06 11:00:53.000000000 -0500
@@ -799,7 +799,8 @@ static inline void dummy_sk_getsid(struc
#endif /* CONFIG_SECURITY_NETWORK */
#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;
}
--- linux-2.6.17.i686.patch11.2/security/selinux/include/xfrm.h 2006-07-05
14:44:23.000000000 -0500
+++ linux-2.6.17.i686/security/selinux/include/xfrm.h 2006-07-06
10:49:09.000000000 -0500
@@ -7,7 +7,8 @@
#ifndef _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);
void selinux_xfrm_policy_free(struct xfrm_policy *xp);
int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx
*sec_ctx,
--- linux-2.6.17.i686.patch11.2/security/selinux/xfrm.c 2006-07-05
14:44:23.000000000 -0500
+++ linux-2.6.17.i686/security/selinux/xfrm.c 2006-07-06 15:28:53.000000000
-0500
@@ -209,8 +209,8 @@ static int selinux_xfrm_sec_ctx_alloc(st
BUG_ON(uctx && pol);
- if (pol)
- goto from_policy;
+ if (!uctx)
+ goto not_from_user;
BUG_ON(!uctx);
@@ -255,11 +255,14 @@ static int selinux_xfrm_sec_ctx_alloc(st
return rc;
-from_policy:
- BUG_ON(!pol);
- rc = security_sid_mls_copy(pol->ctx_sid, sid, &ctx_sid);
- if (rc)
- goto out;
+not_from_user:
+ if (pol) {
+ rc = security_sid_mls_copy(pol->ctx_sid, sid, &ctx_sid);
+ if (rc)
+ goto out;
+ }
+ else
+ ctx_sid = sid;
rc = security_sid_to_context(ctx_sid, &ctx_str, &str_len);
if (rc)
@@ -296,13 +299,23 @@ out:
* LSM hook implementation that allocs and transfers uctx spec to
* 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;
+ u32 sid;
BUG_ON(!xp);
+ BUG_ON(uctx && sk);
+
+ 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, 0);
+ err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, NULL, sid);
return err;
}
--- linux-2.6.17.i686.patch11.2/net/key/af_key.c 2006-07-05
14:38:51.000000000 -0500
+++ linux-2.6.17.i686/net/key/af_key.c 2006-07-06 11:06:17.000000000 -0500
@@ -2839,14 +2839,14 @@ static int pfkey_send_acquire(struct xfr
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)
{
struct xfrm_policy *xp;
struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
struct sadb_x_sec_ctx *sec_ctx;
- switch (family) {
+ switch (sk->sk_family) {
case AF_INET:
if (opt != IP_IPSEC_POLICY) {
*dir = -EOPNOTSUPP;
@@ -2887,7 +2887,7 @@ static struct xfrm_policy *pfkey_compile
xp->lft.hard_byte_limit = XFRM_INF;
xp->lft.soft_packet_limit = XFRM_INF;
xp->lft.hard_packet_limit = XFRM_INF;
- xp->family = family;
+ xp->family = sk->sk_family;
xp->xfrm_nr = 0;
if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&
@@ -2903,8 +2903,10 @@ static struct xfrm_policy *pfkey_compile
p += pol->sadb_x_policy_len*8;
sec_ctx = (struct sadb_x_sec_ctx *)p;
if (len < pol->sadb_x_policy_len*8 +
- sec_ctx->sadb_x_sec_len)
+ sec_ctx->sadb_x_sec_len) {
+ *dir = -EINVAL;
goto out;
+ }
if ((*dir = verify_sec_ctx_len(p)))
goto out;
uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
@@ -2914,6 +2916,11 @@ static struct xfrm_policy *pfkey_compile
if (*dir)
goto out;
}
+ else {
+ *dir = security_xfrm_sock_policy_alloc(xp, sk);
+ if (*dir)
+ goto out;
+ }
*dir = pol->sadb_x_policy_dir-1;
return xp;
--- linux-2.6.17.i686.patch11.2/net/xfrm/xfrm_state.c 2006-07-05
14:38:51.000000000 -0500
+++ linux-2.6.17.i686/net/xfrm/xfrm_state.c 2006-07-06 09:51:22.000000000
-0500
@@ -1025,7 +1025,7 @@ int xfrm_user_policy(struct sock *sk, in
err = -EINVAL;
read_lock(&xfrm_km_lock);
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);
if (err >= 0)
break;
--- linux-2.6.17.i686.patch11.2/net/xfrm/xfrm_user.c 2006-07-05
14:38:51.000000000 -0500
+++ linux-2.6.17.i686/net/xfrm/xfrm_user.c 2006-07-06 13:46:13.000000000
-0500
@@ -1750,7 +1750,7 @@ static int xfrm_send_acquire(struct xfrm
/* User gives us xfrm_user_policy_info followed by an array of 0
* 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)
{
struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
@@ -1758,7 +1758,7 @@ static struct xfrm_policy *xfrm_compile_
struct xfrm_policy *xp;
int nr;
- switch (family) {
+ switch (sk->sk_family) {
case AF_INET:
if (opt != IP_XFRM_POLICY) {
*dir = -EOPNOTSUPP;
@@ -1800,6 +1800,15 @@ static struct xfrm_policy *xfrm_compile_
copy_from_user_policy(xp, p);
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;
return xp;
--
redhat-lspp mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-lspp