aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-07-23 17:38:39 -0400
committerEric Paris <eparis@redhat.com>2013-07-25 13:01:40 -0400
commitccf17cc4b81537c29f0d5950b38b5548b6cb5858 (patch)
tree7fea247cf0db65b62de2bc36021012c3f93b51e3 /security/selinux
parent2e5aa86609ec1cf37bcc204fd7ba6c24c2f49fec (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.c71
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 */
127static 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 */
139static 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 */
278void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) 304void 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 */
287int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) 312int 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 */
350void selinux_xfrm_state_free(struct xfrm_state *x) 368void 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 */
359int selinux_xfrm_state_delete(struct xfrm_state *x) 376int 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/*