aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkat Yekkirala <vyekkirala@trustedcs.com>2006-11-08 18:03:44 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:21:31 -0500
commitc1a856c9640c9ff3d70bbd8214b6a0974609eef8 (patch)
tree76166bf784edd968ffac8c3dcc607d73580c509a
parente8db8c99100750ade5a9b4072b9469cab718a5b7 (diff)
SELinux: Various xfrm labeling fixes
Since the upstreaming of the mlsxfrm modification a few months back, testing has resulted in the identification of the following issues/bugs that are resolved in this patch set. 1. Fix the security context used in the IKE negotiation to be the context of the socket as opposed to the context of the SPD rule. 2. Fix SO_PEERSEC for tcp sockets to return the security context of the peer as opposed to the source. 3. Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. The following would be the result of applying this patchset: - SO_PEERSEC will now correctly return the peer's context. - IKE deamons will receive the context of the source socket/flow as opposed to the SPD rule's context so that the negotiated SA will be at the same context as the source socket/flow. - The SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs: 1. To enable a socket to communicate without using labeled-IPSec SAs: allow socket_t unlabeled_t:association { sendto recvfrom } 2. To enable a socket to communicate with labeled-IPSec SAs: allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom }; This Patch: Pass correct security context to IKE for use in negotiation Fix the security context passed to IKE for use in negotiation to be the context of the socket as opposed to the context of the SPD rule so that the SA carries the label of the originating socket/flow. Signed-off-by: Venkat Yekkirala <vyekkirala@TrustedCS.com> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--include/linux/security.h21
-rw-r--r--security/dummy.c4
-rw-r--r--security/selinux/include/xfrm.h4
-rw-r--r--security/selinux/xfrm.c35
4 files changed, 23 insertions, 41 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index b200b9856f32..a509329a669b 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -836,10 +836,8 @@ struct request_sock;
836 * used by the XFRM system. 836 * used by the XFRM system.
837 * @sec_ctx contains the security context information being provided by 837 * @sec_ctx contains the security context information being provided by
838 * the user-level policy update program (e.g., setkey). 838 * the user-level policy update program (e.g., setkey).
839 * @sk refers to the sock from which to derive the security context.
840 * Allocate a security structure to the xp->security field; the security 839 * Allocate a security structure to the xp->security field; the security
841 * field is initialized to NULL when the xfrm_policy is allocated. Only 840 * field is initialized to NULL when the xfrm_policy is allocated.
842 * one of sec_ctx or sock can be specified.
843 * Return 0 if operation was successful (memory to allocate, legal context) 841 * Return 0 if operation was successful (memory to allocate, legal context)
844 * @xfrm_policy_clone_security: 842 * @xfrm_policy_clone_security:
845 * @old contains an existing xfrm_policy in the SPD. 843 * @old contains an existing xfrm_policy in the SPD.
@@ -858,9 +856,6 @@ struct request_sock;
858 * Database by the XFRM system. 856 * Database by the XFRM system.
859 * @sec_ctx contains the security context information being provided by 857 * @sec_ctx contains the security context information being provided by
860 * the user-level SA generation program (e.g., setkey or racoon). 858 * the user-level SA generation program (e.g., setkey or racoon).
861 * @polsec contains the security context information associated with a xfrm
862 * policy rule from which to take the base context. polsec must be NULL
863 * when sec_ctx is specified.
864 * @secid contains the secid from which to take the mls portion of the context. 859 * @secid contains the secid from which to take the mls portion of the context.
865 * Allocate a security structure to the x->security field; the security 860 * Allocate a security structure to the x->security field; the security
866 * field is initialized to NULL when the xfrm_state is allocated. Set the 861 * field is initialized to NULL when the xfrm_state is allocated. Set the
@@ -1378,12 +1373,12 @@ struct security_operations {
1378 1373
1379#ifdef CONFIG_SECURITY_NETWORK_XFRM 1374#ifdef CONFIG_SECURITY_NETWORK_XFRM
1380 int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, 1375 int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp,
1381 struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk); 1376 struct xfrm_user_sec_ctx *sec_ctx);
1382 int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); 1377 int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
1383 void (*xfrm_policy_free_security) (struct xfrm_policy *xp); 1378 void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
1384 int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); 1379 int (*xfrm_policy_delete_security) (struct xfrm_policy *xp);
1385 int (*xfrm_state_alloc_security) (struct xfrm_state *x, 1380 int (*xfrm_state_alloc_security) (struct xfrm_state *x,
1386 struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *polsec, 1381 struct xfrm_user_sec_ctx *sec_ctx,
1387 u32 secid); 1382 u32 secid);
1388 void (*xfrm_state_free_security) (struct xfrm_state *x); 1383 void (*xfrm_state_free_security) (struct xfrm_state *x);
1389 int (*xfrm_state_delete_security) (struct xfrm_state *x); 1384 int (*xfrm_state_delete_security) (struct xfrm_state *x);
@@ -3120,7 +3115,7 @@ static inline void security_inet_csk_clone(struct sock *newsk,
3120#ifdef CONFIG_SECURITY_NETWORK_XFRM 3115#ifdef CONFIG_SECURITY_NETWORK_XFRM
3121static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) 3116static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
3122{ 3117{
3123 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); 3118 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
3124} 3119}
3125 3120
3126static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 3121static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
@@ -3141,7 +3136,7 @@ static inline int security_xfrm_policy_delete(struct xfrm_policy *xp)
3141static inline int security_xfrm_state_alloc(struct xfrm_state *x, 3136static inline int security_xfrm_state_alloc(struct xfrm_state *x,
3142 struct xfrm_user_sec_ctx *sec_ctx) 3137 struct xfrm_user_sec_ctx *sec_ctx)
3143{ 3138{
3144 return security_ops->xfrm_state_alloc_security(x, sec_ctx, NULL, 0); 3139 return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0);
3145} 3140}
3146 3141
3147static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x, 3142static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
@@ -3149,7 +3144,11 @@ static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
3149{ 3144{
3150 if (!polsec) 3145 if (!polsec)
3151 return 0; 3146 return 0;
3152 return security_ops->xfrm_state_alloc_security(x, NULL, polsec, secid); 3147 /*
3148 * We want the context to be taken from secid which is usually
3149 * from the sock.
3150 */
3151 return security_ops->xfrm_state_alloc_security(x, NULL, secid);
3153} 3152}
3154 3153
3155static inline int security_xfrm_state_delete(struct xfrm_state *x) 3154static inline int security_xfrm_state_delete(struct xfrm_state *x)
diff --git a/security/dummy.c b/security/dummy.c
index 43874c1e6e23..838d8442cf3c 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -836,7 +836,7 @@ static inline void dummy_req_classify_flow(const struct request_sock *req,
836 836
837#ifdef CONFIG_SECURITY_NETWORK_XFRM 837#ifdef CONFIG_SECURITY_NETWORK_XFRM
838static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, 838static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp,
839 struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk) 839 struct xfrm_user_sec_ctx *sec_ctx)
840{ 840{
841 return 0; 841 return 0;
842} 842}
@@ -856,7 +856,7 @@ static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp)
856} 856}
857 857
858static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, 858static int dummy_xfrm_state_alloc_security(struct xfrm_state *x,
859 struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *pol, u32 secid) 859 struct xfrm_user_sec_ctx *sec_ctx, u32 secid)
860{ 860{
861 return 0; 861 return 0;
862} 862}
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 526b28019aca..8e329ddb5e37 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -8,12 +8,12 @@
8#define _SELINUX_XFRM_H_ 8#define _SELINUX_XFRM_H_
9 9
10int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, 10int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
11 struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk); 11 struct xfrm_user_sec_ctx *sec_ctx);
12int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); 12int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
13void selinux_xfrm_policy_free(struct xfrm_policy *xp); 13void selinux_xfrm_policy_free(struct xfrm_policy *xp);
14int selinux_xfrm_policy_delete(struct xfrm_policy *xp); 14int selinux_xfrm_policy_delete(struct xfrm_policy *xp);
15int selinux_xfrm_state_alloc(struct xfrm_state *x, 15int selinux_xfrm_state_alloc(struct xfrm_state *x,
16 struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *pol, u32 secid); 16 struct xfrm_user_sec_ctx *sec_ctx, u32 secid);
17void selinux_xfrm_state_free(struct xfrm_state *x); 17void selinux_xfrm_state_free(struct xfrm_state *x);
18int selinux_xfrm_state_delete(struct xfrm_state *x); 18int selinux_xfrm_state_delete(struct xfrm_state *x);
19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 675b995a67c3..4d5a043cdfa1 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -226,16 +226,15 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
226 * CTX does not have a meaningful value on input 226 * CTX does not have a meaningful value on input
227 */ 227 */
228static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, 228static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
229 struct xfrm_user_sec_ctx *uctx, struct xfrm_sec_ctx *pol, u32 sid) 229 struct xfrm_user_sec_ctx *uctx, u32 sid)
230{ 230{
231 int rc = 0; 231 int rc = 0;
232 struct task_security_struct *tsec = current->security; 232 struct task_security_struct *tsec = current->security;
233 struct xfrm_sec_ctx *ctx = NULL; 233 struct xfrm_sec_ctx *ctx = NULL;
234 char *ctx_str = NULL; 234 char *ctx_str = NULL;
235 u32 str_len; 235 u32 str_len;
236 u32 ctx_sid;
237 236
238 BUG_ON(uctx && pol); 237 BUG_ON(uctx && sid);
239 238
240 if (!uctx) 239 if (!uctx)
241 goto not_from_user; 240 goto not_from_user;
@@ -279,15 +278,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
279 return rc; 278 return rc;
280 279
281not_from_user: 280not_from_user:
282 if (pol) { 281 rc = security_sid_to_context(sid, &ctx_str, &str_len);
283 rc = security_sid_mls_copy(pol->ctx_sid, sid, &ctx_sid);
284 if (rc)
285 goto out;
286 }
287 else
288 ctx_sid = sid;
289
290 rc = security_sid_to_context(ctx_sid, &ctx_str, &str_len);
291 if (rc) 282 if (rc)
292 goto out; 283 goto out;
293 284
@@ -302,7 +293,7 @@ not_from_user:
302 293
303 ctx->ctx_doi = XFRM_SC_DOI_LSM; 294 ctx->ctx_doi = XFRM_SC_DOI_LSM;
304 ctx->ctx_alg = XFRM_SC_ALG_SELINUX; 295 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
305 ctx->ctx_sid = ctx_sid; 296 ctx->ctx_sid = sid;
306 ctx->ctx_len = str_len; 297 ctx->ctx_len = str_len;
307 memcpy(ctx->ctx_str, 298 memcpy(ctx->ctx_str,
308 ctx_str, 299 ctx_str,
@@ -323,22 +314,14 @@ out2:
323 * xfrm_policy. 314 * xfrm_policy.
324 */ 315 */
325int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, 316int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
326 struct xfrm_user_sec_ctx *uctx, struct sock *sk) 317 struct xfrm_user_sec_ctx *uctx)
327{ 318{
328 int err; 319 int err;
329 u32 sid;
330 320
331 BUG_ON(!xp); 321 BUG_ON(!xp);
332 BUG_ON(uctx && sk); 322 BUG_ON(!uctx);
333
334 if (sk) {
335 struct sk_security_struct *ssec = sk->sk_security;
336 sid = ssec->sid;
337 }
338 else
339 sid = SECSID_NULL;
340 323
341 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, NULL, sid); 324 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0);
342 return err; 325 return err;
343} 326}
344 327
@@ -399,13 +382,13 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
399 * xfrm_state. 382 * xfrm_state.
400 */ 383 */
401int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx, 384int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx,
402 struct xfrm_sec_ctx *pol, u32 secid) 385 u32 secid)
403{ 386{
404 int err; 387 int err;
405 388
406 BUG_ON(!x); 389 BUG_ON(!x);
407 390
408 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, pol, secid); 391 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
409 return err; 392 return err;
410} 393}
411 394