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.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 8fef74271f22..9b777140068f 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -115,71 +115,40 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
115 struct flowi *fl) 115 struct flowi *fl)
116{ 116{
117 u32 state_sid; 117 u32 state_sid;
118 u32 pol_sid; 118 int rc;
119 int err;
120 119
121 if (xp->security) { 120 if (!xp->security)
122 if (!x->security)
123 /* unlabeled SA and labeled policy can't match */
124 return 0;
125 else
126 state_sid = x->security->ctx_sid;
127 pol_sid = xp->security->ctx_sid;
128 } else
129 if (x->security) 121 if (x->security)
130 /* unlabeled policy and labeled SA can't match */ 122 /* unlabeled policy and labeled SA can't match */
131 return 0; 123 return 0;
132 else 124 else
133 /* unlabeled policy and unlabeled SA match all flows */ 125 /* unlabeled policy and unlabeled SA match all flows */
134 return 1; 126 return 1;
135
136 err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION,
137 ASSOCIATION__POLMATCH,
138 NULL);
139
140 if (err)
141 return 0;
142
143 err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
144 ASSOCIATION__SENDTO,
145 NULL)? 0:1;
146
147 return err;
148}
149
150/*
151 * LSM hook implementation that authorizes that a particular outgoing flow
152 * can use a given security association.
153 */
154
155int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
156 struct xfrm_policy *xp)
157{
158 int rc = 0;
159 u32 sel_sid = SECINITSID_UNLABELED;
160 struct xfrm_sec_ctx *ctx;
161
162 if (!xp->security)
163 if (!xfrm->security)
164 return 1;
165 else
166 return 0;
167 else 127 else
168 if (!xfrm->security) 128 if (!x->security)
129 /* unlabeled SA and labeled policy can't match */
169 return 0; 130 return 0;
131 else
132 if (!selinux_authorizable_xfrm(x))
133 /* Not a SELinux-labeled SA */
134 return 0;
170 135
171 /* Context sid is either set to label or ANY_ASSOC */ 136 state_sid = x->security->ctx_sid;
172 if ((ctx = xfrm->security)) {
173 if (!selinux_authorizable_ctx(ctx))
174 return 0;
175 137
176 sel_sid = ctx->ctx_sid; 138 if (fl->secid != state_sid)
177 } 139 return 0;
178 140
179 rc = avc_has_perm(fl->secid, sel_sid, SECCLASS_ASSOCIATION, 141 rc = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
180 ASSOCIATION__SENDTO, 142 ASSOCIATION__SENDTO,
181 NULL)? 0:1; 143 NULL)? 0:1;
182 144
145 /*
146 * We don't need a separate SA Vs. policy polmatch check
147 * since the SA is now of the same label as the flow and
148 * a flow Vs. policy polmatch check had already happened
149 * in selinux_xfrm_policy_lookup() above.
150 */
151
183 return rc; 152 return rc;
184} 153}
185 154
@@ -481,6 +450,13 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
481 } 450 }
482 } 451 }
483 452
453 /*
454 * This check even when there's no association involved is
455 * intended, according to Trent Jaeger, to make sure a
456 * process can't engage in non-ipsec communication unless
457 * explicitly allowed by policy.
458 */
459
484 rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION, 460 rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
485 ASSOCIATION__RECVFROM, ad); 461 ASSOCIATION__RECVFROM, ad);
486 462
@@ -492,10 +468,10 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
492 * If we have no security association, then we need to determine 468 * If we have no security association, then we need to determine
493 * whether the socket is allowed to send to an unlabelled destination. 469 * whether the socket is allowed to send to an unlabelled destination.
494 * If we do have a authorizable security association, then it has already been 470 * If we do have a authorizable security association, then it has already been
495 * checked in xfrm_policy_lookup hook. 471 * checked in the selinux_xfrm_state_pol_flow_match hook above.
496 */ 472 */
497int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 473int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
498 struct avc_audit_data *ad) 474 struct avc_audit_data *ad, u8 proto)
499{ 475{
500 struct dst_entry *dst; 476 struct dst_entry *dst;
501 int rc = 0; 477 int rc = 0;
@@ -514,6 +490,27 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
514 } 490 }
515 } 491 }
516 492
493 switch (proto) {
494 case IPPROTO_AH:
495 case IPPROTO_ESP:
496 case IPPROTO_COMP:
497 /*
498 * We should have already seen this packet once before
499 * it underwent xfrm(s). No need to subject it to the
500 * unlabeled check.
501 */
502 goto out;
503 default:
504 break;
505 }
506
507 /*
508 * This check even when there's no association involved is
509 * intended, according to Trent Jaeger, to make sure a
510 * process can't engage in non-ipsec communication unless
511 * explicitly allowed by policy.
512 */
513
517 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 514 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
518 ASSOCIATION__SENDTO, ad); 515 ASSOCIATION__SENDTO, ad);
519out: 516out: