diff options
author | Paul Moore <paul.moore@hp.com> | 2008-04-12 22:07:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-12 22:07:52 -0400 |
commit | 03e1ad7b5d871d4189b1da3125c2f12d1b5f7d0b (patch) | |
tree | 1e7f291ac6bd0c1f3a95e8252c32fcce7ff47ea7 /security/selinux | |
parent | 00447872a643787411c2c0cb1df6169dda8b0c47 (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/selinux')
-rw-r--r-- | security/selinux/include/xfrm.h | 13 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 39 |
2 files changed, 23 insertions, 29 deletions
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 | ||
10 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, | 10 | int 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); |
12 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); | 12 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
13 | void selinux_xfrm_policy_free(struct xfrm_policy *xp); | 13 | struct xfrm_sec_ctx **new_ctxp); |
14 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp); | 14 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
15 | int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); | ||
15 | int selinux_xfrm_state_alloc(struct xfrm_state *x, | 16 | int 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); |
17 | void selinux_xfrm_state_free(struct xfrm_state *x); | 18 | void selinux_xfrm_state_free(struct xfrm_state *x); |
18 | int selinux_xfrm_state_delete(struct xfrm_state *x); | 19 | int selinux_xfrm_state_delete(struct xfrm_state *x); |
19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 20 | int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); |
20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 21 | int 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 | */ |
80 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 80 | int 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 | */ |
290 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, | 288 | int 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 | */ |
310 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 307 | int 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 | */ |
333 | void selinux_xfrm_policy_free(struct xfrm_policy *xp) | 328 | void 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 | */ |
343 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp) | 337 | int 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) { |