aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/xfrm.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/xfrm.c')
-rw-r--r--security/selinux/xfrm.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index a91d205ec0c6..0462cb3ff0a7 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -209,19 +209,26 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
209 NULL) ? 0 : 1); 209 NULL) ? 0 : 1);
210} 210}
211 211
212/* 212static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
213 * LSM hook implementation that checks and/or returns the xfrm sid for the
214 * incoming packet.
215 */
216int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
217{ 213{
218 u32 sid_session = SECSID_NULL; 214 struct dst_entry *dst = skb_dst(skb);
219 struct sec_path *sp; 215 struct xfrm_state *x;
220 216
221 if (skb == NULL) 217 if (dst == NULL)
222 goto out; 218 return SECSID_NULL;
219 x = dst->xfrm;
220 if (x == NULL || !selinux_authorizable_xfrm(x))
221 return SECSID_NULL;
222
223 return x->security->ctx_sid;
224}
225
226static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
227 u32 *sid, int ckall)
228{
229 u32 sid_session = SECSID_NULL;
230 struct sec_path *sp = skb->sp;
223 231
224 sp = skb->sp;
225 if (sp) { 232 if (sp) {
226 int i; 233 int i;
227 234
@@ -248,6 +255,30 @@ out:
248} 255}
249 256
250/* 257/*
258 * LSM hook implementation that checks and/or returns the xfrm sid for the
259 * incoming packet.
260 */
261int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
262{
263 if (skb == NULL) {
264 *sid = SECSID_NULL;
265 return 0;
266 }
267 return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
268}
269
270int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
271{
272 int rc;
273
274 rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
275 if (rc == 0 && *sid == SECSID_NULL)
276 *sid = selinux_xfrm_skb_sid_egress(skb);
277
278 return rc;
279}
280
281/*
251 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. 282 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
252 */ 283 */
253int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 284int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
@@ -327,19 +358,22 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
327 return rc; 358 return rc;
328 359
329 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC); 360 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
330 if (!ctx) 361 if (!ctx) {
331 return -ENOMEM; 362 rc = -ENOMEM;
363 goto out;
364 }
332 365
333 ctx->ctx_doi = XFRM_SC_DOI_LSM; 366 ctx->ctx_doi = XFRM_SC_DOI_LSM;
334 ctx->ctx_alg = XFRM_SC_ALG_SELINUX; 367 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
335 ctx->ctx_sid = secid; 368 ctx->ctx_sid = secid;
336 ctx->ctx_len = str_len; 369 ctx->ctx_len = str_len;
337 memcpy(ctx->ctx_str, ctx_str, str_len); 370 memcpy(ctx->ctx_str, ctx_str, str_len);
338 kfree(ctx_str);
339 371
340 x->security = ctx; 372 x->security = ctx;
341 atomic_inc(&selinux_xfrm_refcount); 373 atomic_inc(&selinux_xfrm_refcount);
342 return 0; 374out:
375 kfree(ctx_str);
376 return rc;
343} 377}
344 378
345/* 379/*