/* * LSM hook implementation that authorizes that a flow can use a xfrm policy * rule.
*/ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
{ int rc;
/* All flows should be treated as polmatch'ing an otherwise applicable
* "non-labeled" policy. This would prevent inadvertent "leaks". */ if (!ctx) return 0;
/* Context sid is either set to label or ANY_ASSOC */ if (!selinux_authorizable_ctx(ctx)) return -EINVAL;
/* * LSM hook implementation that authorizes that a state matches * the given policy, flow combo.
*/ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, conststruct flowi_common *flic)
{
u32 state_sid;
u32 flic_sid;
if (!xp->security) if (x->security) /* unlabeled policy and labeled SA can't match */ return 0; else /* unlabeled policy and unlabeled SA match all flows */ return 1; else if (!x->security) /* unlabeled SA and labeled policy can't match */ return 0; else if (!selinux_authorizable_xfrm(x)) /* Not a SELinux-labeled SA */ return 0;
/* We don't need a separate SA Vs. policy polmatch check since the SA * is now of the same label as the flow and a flow Vs. policy polmatch
* check had already happened in selinux_xfrm_policy_lookup() above. */ return (avc_has_perm(flic_sid, state_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
NULL) ? 0 : 1);
}
/* * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
*/ int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx,
gfp_t gfp)
{ return selinux_xfrm_alloc_user(ctxp, uctx, gfp);
}
/* * LSM hook implementation that copies security data structure from old to new * for policy cloning.
*/ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp)
{ struct xfrm_sec_ctx *new_ctx;
/* * LSM hook implementation that authorizes deletion of labeled policies.
*/ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
{ return selinux_xfrm_delete(ctx);
}
/* * LSM hook implementation that allocates a xfrm_sec_state, populates it using * the supplied security context, and assigns it to the xfrm_state.
*/ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx)
{ return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL);
}
/* * LSM hook implementation that allocates a xfrm_sec_state and populates based * on a secid.
*/ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid)
{ int rc; struct xfrm_sec_ctx *ctx; char *ctx_str = NULL;
u32 str_len;
if (!polsec) return 0;
if (secid == 0) return -EINVAL;
rc = security_sid_to_context(secid, &ctx_str,
&str_len); if (rc) return rc;
/* * LSM hook implementation that authorizes deletion of labeled SAs.
*/ int selinux_xfrm_state_delete(struct xfrm_state *x)
{ return selinux_xfrm_delete(x->security);
}
/* * LSM hook that controls access to unlabelled packets. If * a xfrm_state is authorizable (defined by macro) then it was * already authorized by the IPSec process. If not, then * we need to check for unlabelled access since this may not have * gone thru the IPSec process.
*/ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, struct common_audit_data *ad)
{ int i; struct sec_path *sp = skb_sec_path(skb);
u32 peer_sid = SECINITSID_UNLABELED;
if (sp) { for (i = 0; i < sp->len; i++) { struct xfrm_state *x = sp->xvec[i];
/* This check even when there's no association involved is intended, * according to Trent Jaeger, to make sure a process can't engage in
* non-IPsec communication unless explicitly allowed by policy. */ return avc_has_perm(sk_sid, peer_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
}
/* * POSTROUTE_LAST hook's XFRM processing: * If we have no security association, then we need to determine * whether the socket is allowed to send to an unlabelled destination. * If we do have a authorizable security association, then it has already been * checked in the selinux_xfrm_state_pol_flow_match hook above.
*/ int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, struct common_audit_data *ad, u8 proto)
{ struct dst_entry *dst;
switch (proto) { case IPPROTO_AH: case IPPROTO_ESP: case IPPROTO_COMP: /* We should have already seen this packet once before it * underwent xfrm(s). No need to subject it to the unlabeled
* check. */ return 0; default: break;
}
dst = skb_dst(skb); if (dst) { struct dst_entry *iter;
for (iter = dst; iter != NULL; iter = xfrm_dst_child(iter)) { struct xfrm_state *x = iter->xfrm;
if (x && selinux_authorizable_xfrm(x)) return 0;
}
}
/* This check even when there's no association involved is intended, * according to Trent Jaeger, to make sure a process can't engage in
* non-IPsec communication unless explicitly allowed by policy. */ return avc_has_perm(sk_sid, SECINITSID_UNLABELED,
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.