Skip to content

Commit ccf17cc

Browse files
pcmooreeparis
authored andcommitted
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>
1 parent 2e5aa86 commit ccf17cc

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

security/selinux/xfrm.c

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,33 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
121121
return rc;
122122
}
123123

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+
124151
/*
125152
* LSM hook implementation that authorizes that a flow can use
126153
* a xfrm policy rule.
@@ -258,17 +285,16 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
258285
{
259286
struct xfrm_sec_ctx *new_ctx;
260287

261-
if (old_ctx) {
262-
new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
263-
GFP_ATOMIC);
264-
if (!new_ctx)
265-
return -ENOMEM;
288+
if (!old_ctx)
289+
return 0;
290+
291+
new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, GFP_ATOMIC);
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;
266297

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-
}
272298
return 0;
273299
}
274300

@@ -277,23 +303,15 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
277303
*/
278304
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
279305
{
280-
atomic_dec(&selinux_xfrm_refcount);
281-
kfree(ctx);
306+
selinux_xfrm_free(ctx);
282307
}
283308

284309
/*
285310
* LSM hook implementation that authorizes deletion of labeled policies.
286311
*/
287312
int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
288313
{
289-
const struct task_security_struct *tsec = current_security();
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);
314+
return selinux_xfrm_delete(ctx);
297315
}
298316

299317
/*
@@ -349,24 +367,15 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
349367
*/
350368
void selinux_xfrm_state_free(struct xfrm_state *x)
351369
{
352-
atomic_dec(&selinux_xfrm_refcount);
353-
kfree(x->security);
370+
selinux_xfrm_free(x->security);
354371
}
355372

356373
/*
357374
* LSM hook implementation that authorizes deletion of labeled SAs.
358375
*/
359376
int selinux_xfrm_state_delete(struct xfrm_state *x)
360377
{
361-
const struct task_security_struct *tsec = current_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);
378+
return selinux_xfrm_delete(x->security);
370379
}
371380

372381
/*

0 commit comments

Comments
 (0)