aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-04-12 22:07:52 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-12 22:07:52 -0400
commit03e1ad7b5d871d4189b1da3125c2f12d1b5f7d0b (patch)
tree1e7f291ac6bd0c1f3a95e8252c32fcce7ff47ea7 /security
parent00447872a643787411c2c0cb1df6169dda8b0c47 (diff)
LSM: Make the Labeled IPsec hooks more stack friendly
The xfrm_get_policy() and xfrm_add_pol_expire() put some rather large structs on the stack to work around the LSM API. This patch attempts to fix that problem by changing the LSM API to require only the relevant "security" pointers instead of the entire SPD entry; we do this for all of the security_xfrm_policy*() functions to keep things consistent. Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c14
-rw-r--r--security/security.c21
-rw-r--r--security/selinux/include/xfrm.h13
-rw-r--r--security/selinux/xfrm.c39
4 files changed, 42 insertions, 45 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 78d8f92310a4..480366f9c41d 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -876,22 +876,23 @@ static inline void dummy_req_classify_flow(const struct request_sock *req,
876#endif /* CONFIG_SECURITY_NETWORK */ 876#endif /* CONFIG_SECURITY_NETWORK */
877 877
878#ifdef CONFIG_SECURITY_NETWORK_XFRM 878#ifdef CONFIG_SECURITY_NETWORK_XFRM
879static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, 879static int dummy_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,
880 struct xfrm_user_sec_ctx *sec_ctx) 880 struct xfrm_user_sec_ctx *sec_ctx)
881{ 881{
882 return 0; 882 return 0;
883} 883}
884 884
885static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new) 885static inline int dummy_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx,
886 struct xfrm_sec_ctx **new_ctxp)
886{ 887{
887 return 0; 888 return 0;
888} 889}
889 890
890static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp) 891static void dummy_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx)
891{ 892{
892} 893}
893 894
894static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp) 895static int dummy_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx)
895{ 896{
896 return 0; 897 return 0;
897} 898}
@@ -911,7 +912,8 @@ static int dummy_xfrm_state_delete_security(struct xfrm_state *x)
911 return 0; 912 return 0;
912} 913}
913 914
914static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) 915static int dummy_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx,
916 u32 sk_sid, u8 dir)
915{ 917{
916 return 0; 918 return 0;
917} 919}
diff --git a/security/security.c b/security/security.c
index b1387a6b416d..c9ff7d18c2f4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1014,26 +1014,27 @@ void security_inet_conn_established(struct sock *sk,
1014 1014
1015#ifdef CONFIG_SECURITY_NETWORK_XFRM 1015#ifdef CONFIG_SECURITY_NETWORK_XFRM
1016 1016
1017int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) 1017int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx)
1018{ 1018{
1019 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); 1019 return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx);
1020} 1020}
1021EXPORT_SYMBOL(security_xfrm_policy_alloc); 1021EXPORT_SYMBOL(security_xfrm_policy_alloc);
1022 1022
1023int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 1023int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
1024 struct xfrm_sec_ctx **new_ctxp)
1024{ 1025{
1025 return security_ops->xfrm_policy_clone_security(old, new); 1026 return security_ops->xfrm_policy_clone_security(old_ctx, new_ctxp);
1026} 1027}
1027 1028
1028void security_xfrm_policy_free(struct xfrm_policy *xp) 1029void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
1029{ 1030{
1030 security_ops->xfrm_policy_free_security(xp); 1031 security_ops->xfrm_policy_free_security(ctx);
1031} 1032}
1032EXPORT_SYMBOL(security_xfrm_policy_free); 1033EXPORT_SYMBOL(security_xfrm_policy_free);
1033 1034
1034int security_xfrm_policy_delete(struct xfrm_policy *xp) 1035int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
1035{ 1036{
1036 return security_ops->xfrm_policy_delete_security(xp); 1037 return security_ops->xfrm_policy_delete_security(ctx);
1037} 1038}
1038 1039
1039int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) 1040int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
@@ -1065,9 +1066,9 @@ void security_xfrm_state_free(struct xfrm_state *x)
1065 security_ops->xfrm_state_free_security(x); 1066 security_ops->xfrm_state_free_security(x);
1066} 1067}
1067 1068
1068int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 1069int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
1069{ 1070{
1070 return security_ops->xfrm_policy_lookup(xp, fl_secid, dir); 1071 return security_ops->xfrm_policy_lookup(ctx, fl_secid, dir);
1071} 1072}
1072 1073
1073int security_xfrm_state_pol_flow_match(struct xfrm_state *x, 1074int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 36b0510efa7b..289e24b39e3e 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -7,16 +7,17 @@
7#ifndef _SELINUX_XFRM_H_ 7#ifndef _SELINUX_XFRM_H_
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_sec_ctx **ctxp,
11 struct xfrm_user_sec_ctx *sec_ctx); 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_sec_ctx *old_ctx,
13void selinux_xfrm_policy_free(struct xfrm_policy *xp); 13 struct xfrm_sec_ctx **new_ctxp);
14int selinux_xfrm_policy_delete(struct xfrm_policy *xp); 14void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
15int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
15int selinux_xfrm_state_alloc(struct xfrm_state *x, 16int selinux_xfrm_state_alloc(struct xfrm_state *x,
16 struct xfrm_user_sec_ctx *sec_ctx, u32 secid); 17 struct xfrm_user_sec_ctx *sec_ctx, u32 secid);
17void selinux_xfrm_state_free(struct xfrm_state *x); 18void selinux_xfrm_state_free(struct xfrm_state *x);
18int selinux_xfrm_state_delete(struct xfrm_state *x); 19int selinux_xfrm_state_delete(struct xfrm_state *x);
19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 20int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 21int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
21 struct xfrm_policy *xp, struct flowi *fl); 22 struct xfrm_policy *xp, struct flowi *fl);
22 23
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 7e158205d081..874d17c83c61 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -77,20 +77,18 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
77 * LSM hook implementation that authorizes that a flow can use 77 * LSM hook implementation that authorizes that a flow can use
78 * a xfrm policy rule. 78 * a xfrm policy rule.
79 */ 79 */
80int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 80int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
81{ 81{
82 int rc; 82 int rc;
83 u32 sel_sid; 83 u32 sel_sid;
84 struct xfrm_sec_ctx *ctx;
85 84
86 /* Context sid is either set to label or ANY_ASSOC */ 85 /* Context sid is either set to label or ANY_ASSOC */
87 if ((ctx = xp->security)) { 86 if (ctx) {
88 if (!selinux_authorizable_ctx(ctx)) 87 if (!selinux_authorizable_ctx(ctx))
89 return -EINVAL; 88 return -EINVAL;
90 89
91 sel_sid = ctx->ctx_sid; 90 sel_sid = ctx->ctx_sid;
92 } 91 } else
93 else
94 /* 92 /*
95 * All flows should be treated as polmatch'ing an 93 * All flows should be treated as polmatch'ing an
96 * otherwise applicable "non-labeled" policy. This 94 * otherwise applicable "non-labeled" policy. This
@@ -103,7 +101,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
103 NULL); 101 NULL);
104 102
105 if (rc == -EACCES) 103 if (rc == -EACCES)
106 rc = -ESRCH; 104 return -ESRCH;
107 105
108 return rc; 106 return rc;
109} 107}
@@ -287,15 +285,14 @@ out2:
287 * LSM hook implementation that allocs and transfers uctx spec to 285 * LSM hook implementation that allocs and transfers uctx spec to
288 * xfrm_policy. 286 * xfrm_policy.
289 */ 287 */
290int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, 288int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
291 struct xfrm_user_sec_ctx *uctx) 289 struct xfrm_user_sec_ctx *uctx)
292{ 290{
293 int err; 291 int err;
294 292
295 BUG_ON(!xp);
296 BUG_ON(!uctx); 293 BUG_ON(!uctx);
297 294
298 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0); 295 err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
299 if (err == 0) 296 if (err == 0)
300 atomic_inc(&selinux_xfrm_refcount); 297 atomic_inc(&selinux_xfrm_refcount);
301 298
@@ -307,32 +304,29 @@ int selinux_xfrm_policy_alloc(struct xfrm_policy *xp,
307 * LSM hook implementation that copies security data structure from old to 304 * LSM hook implementation that copies security data structure from old to
308 * new for policy cloning. 305 * new for policy cloning.
309 */ 306 */
310int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 307int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
308 struct xfrm_sec_ctx **new_ctxp)
311{ 309{
312 struct xfrm_sec_ctx *old_ctx, *new_ctx; 310 struct xfrm_sec_ctx *new_ctx;
313
314 old_ctx = old->security;
315 311
316 if (old_ctx) { 312 if (old_ctx) {
317 new_ctx = new->security = kmalloc(sizeof(*new_ctx) + 313 new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
318 old_ctx->ctx_len, 314 GFP_KERNEL);
319 GFP_KERNEL);
320
321 if (!new_ctx) 315 if (!new_ctx)
322 return -ENOMEM; 316 return -ENOMEM;
323 317
324 memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); 318 memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
325 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); 319 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
320 *new_ctxp = new_ctx;
326 } 321 }
327 return 0; 322 return 0;
328} 323}
329 324
330/* 325/*
331 * LSM hook implementation that frees xfrm_policy security information. 326 * LSM hook implementation that frees xfrm_sec_ctx security information.
332 */ 327 */
333void selinux_xfrm_policy_free(struct xfrm_policy *xp) 328void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
334{ 329{
335 struct xfrm_sec_ctx *ctx = xp->security;
336 if (ctx) 330 if (ctx)
337 kfree(ctx); 331 kfree(ctx);
338} 332}
@@ -340,10 +334,9 @@ void selinux_xfrm_policy_free(struct xfrm_policy *xp)
340/* 334/*
341 * LSM hook implementation that authorizes deletion of labeled policies. 335 * LSM hook implementation that authorizes deletion of labeled policies.
342 */ 336 */
343int selinux_xfrm_policy_delete(struct xfrm_policy *xp) 337int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
344{ 338{
345 struct task_security_struct *tsec = current->security; 339 struct task_security_struct *tsec = current->security;
346 struct xfrm_sec_ctx *ctx = xp->security;
347 int rc = 0; 340 int rc = 0;
348 341
349 if (ctx) { 342 if (ctx) {