Skip to content

Commit 8680407

Browse files
Benedict Wongklassert
authored andcommitted
xfrm: Check if_id in inbound policy/secpath match
This change ensures that if configured in the policy, the if_id set in the policy and secpath states match during the inbound policy check. Without this, there is potential for ambiguity where entries in the secpath differing by only the if_id could be mismatched. Notably, this is checked in the outbound direction when resolving templates to SAs, but not on the inbound path when matching SAs and policies. Test: Tested against Android kernel unit tests & CTS Signed-off-by: Benedict Wong <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent cf3128a commit 8680407

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,7 +3312,7 @@ xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl)
33123312

33133313
static inline int
33143314
xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x,
3315-
unsigned short family)
3315+
unsigned short family, u32 if_id)
33163316
{
33173317
if (xfrm_state_kern(x))
33183318
return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family);
@@ -3323,7 +3323,8 @@ xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x,
33233323
(tmpl->allalgs || (tmpl->aalgos & (1<<x->props.aalgo)) ||
33243324
!(xfrm_id_proto_match(tmpl->id.proto, IPSEC_PROTO_ANY))) &&
33253325
!(x->props.mode != XFRM_MODE_TRANSPORT &&
3326-
xfrm_state_addr_cmp(tmpl, x, family));
3326+
xfrm_state_addr_cmp(tmpl, x, family)) &&
3327+
(if_id == 0 || if_id == x->if_id);
33273328
}
33283329

33293330
/*
@@ -3335,7 +3336,7 @@ xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x,
33353336
*/
33363337
static inline int
33373338
xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int start,
3338-
unsigned short family)
3339+
unsigned short family, u32 if_id)
33393340
{
33403341
int idx = start;
33413342

@@ -3345,7 +3346,7 @@ xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int star
33453346
} else
33463347
start = -1;
33473348
for (; idx < sp->len; idx++) {
3348-
if (xfrm_state_ok(tmpl, sp->xvec[idx], family))
3349+
if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id))
33493350
return ++idx;
33503351
if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) {
33513352
if (start == -1)
@@ -3724,7 +3725,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
37243725
* are implied between each two transformations.
37253726
*/
37263727
for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
3727-
k = xfrm_policy_ok(tpp[i], sp, k, family);
3728+
k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
37283729
if (k < 0) {
37293730
if (k < -1)
37303731
/* "-2 - errored_index" returned */

0 commit comments

Comments
 (0)