diff options
Diffstat (limited to 'security/selinux/xfrm.c')
-rw-r--r-- | security/selinux/xfrm.c | 62 |
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 | /* | 212 | static 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 | */ | ||
216 | int 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 | |||
226 | static 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 | */ | ||
261 | int 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 | |||
270 | int 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 | */ |
253 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | 284 | int 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; | 374 | out: |
375 | kfree(ctx_str); | ||
376 | return rc; | ||
343 | } | 377 | } |
344 | 378 | ||
345 | /* | 379 | /* |