diff options
author | Paul Moore <pmoore@redhat.com> | 2013-07-23 17:38:39 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2013-07-25 13:01:40 -0400 |
commit | ccf17cc4b81537c29f0d5950b38b5548b6cb5858 (patch) | |
tree | 7fea247cf0db65b62de2bc36021012c3f93b51e3 /security/selinux | |
parent | 2e5aa86609ec1cf37bcc204fd7ba6c24c2f49fec (diff) |
selinux: cleanup and consolidate the XFRM alloc/clone/delete/free code
The SELinux labeled IPsec code state management functions have been
long neglected and could use some cleanup and consolidation.
Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/xfrm.c | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 07ae0c06dfc3..f8d71262b45d 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -122,6 +122,33 @@ err: | |||
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * Free the xfrm_sec_ctx structure. | ||
126 | */ | ||
127 | static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx) | ||
128 | { | ||
129 | if (!ctx) | ||
130 | return; | ||
131 | |||
132 | atomic_dec(&selinux_xfrm_refcount); | ||
133 | kfree(ctx); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Authorize the deletion of a labeled SA or policy rule. | ||
138 | */ | ||
139 | static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx) | ||
140 | { | ||
141 | const struct task_security_struct *tsec = current_security(); | ||
142 | |||
143 | if (!ctx) | ||
144 | return 0; | ||
145 | |||
146 | return avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
147 | SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, | ||
148 | NULL); | ||
149 | } | ||
150 | |||
151 | /* | ||
125 | * LSM hook implementation that authorizes that a flow can use | 152 | * LSM hook implementation that authorizes that a flow can use |
126 | * a xfrm policy rule. | 153 | * a xfrm policy rule. |
127 | */ | 154 | */ |
@@ -258,17 +285,16 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, | |||
258 | { | 285 | { |
259 | struct xfrm_sec_ctx *new_ctx; | 286 | struct xfrm_sec_ctx *new_ctx; |
260 | 287 | ||
261 | if (old_ctx) { | 288 | if (!old_ctx) |
262 | new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, | 289 | return 0; |
263 | GFP_ATOMIC); | 290 | |
264 | if (!new_ctx) | 291 | new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, GFP_ATOMIC); |
265 | return -ENOMEM; | 292 | if (!new_ctx) |
293 | return -ENOMEM; | ||
294 | memcpy(new_ctx, old_ctx, sizeof(*old_ctx) + old_ctx->ctx_len); | ||
295 | atomic_inc(&selinux_xfrm_refcount); | ||
296 | *new_ctxp = new_ctx; | ||
266 | 297 | ||
267 | memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); | ||
268 | memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); | ||
269 | atomic_inc(&selinux_xfrm_refcount); | ||
270 | *new_ctxp = new_ctx; | ||
271 | } | ||
272 | return 0; | 298 | return 0; |
273 | } | 299 | } |
274 | 300 | ||
@@ -277,8 +303,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, | |||
277 | */ | 303 | */ |
278 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) | 304 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
279 | { | 305 | { |
280 | atomic_dec(&selinux_xfrm_refcount); | 306 | selinux_xfrm_free(ctx); |
281 | kfree(ctx); | ||
282 | } | 307 | } |
283 | 308 | ||
284 | /* | 309 | /* |
@@ -286,14 +311,7 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) | |||
286 | */ | 311 | */ |
287 | int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) | 312 | int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
288 | { | 313 | { |
289 | const struct task_security_struct *tsec = current_security(); | 314 | return selinux_xfrm_delete(ctx); |
290 | |||
291 | if (!ctx) | ||
292 | return 0; | ||
293 | |||
294 | return avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
295 | SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, | ||
296 | NULL); | ||
297 | } | 315 | } |
298 | 316 | ||
299 | /* | 317 | /* |
@@ -349,8 +367,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, | |||
349 | */ | 367 | */ |
350 | void selinux_xfrm_state_free(struct xfrm_state *x) | 368 | void selinux_xfrm_state_free(struct xfrm_state *x) |
351 | { | 369 | { |
352 | atomic_dec(&selinux_xfrm_refcount); | 370 | selinux_xfrm_free(x->security); |
353 | kfree(x->security); | ||
354 | } | 371 | } |
355 | 372 | ||
356 | /* | 373 | /* |
@@ -358,15 +375,7 @@ void selinux_xfrm_state_free(struct xfrm_state *x) | |||
358 | */ | 375 | */ |
359 | int selinux_xfrm_state_delete(struct xfrm_state *x) | 376 | int selinux_xfrm_state_delete(struct xfrm_state *x) |
360 | { | 377 | { |
361 | const struct task_security_struct *tsec = current_security(); | 378 | return selinux_xfrm_delete(x->security); |
362 | struct xfrm_sec_ctx *ctx = x->security; | ||
363 | |||
364 | if (!ctx) | ||
365 | return 0; | ||
366 | |||
367 | return avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
368 | SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, | ||
369 | NULL); | ||
370 | } | 379 | } |
371 | 380 | ||
372 | /* | 381 | /* |