aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2018-02-19 01:44:07 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2018-02-20 02:38:57 -0500
commit013cb81e89f8a70deef086ca29a923faf5585ab0 (patch)
treea464f9903eef9b342c093857b655e0df297ef08c
parent143a4454daaf0e80a2b9f37159a0d6d2b61e64ed (diff)
xfrm: Fix infinite loop in xfrm_get_dst_nexthop with transport mode.
On transport mode we forget to fetch the child dst_entry before we continue the while loop, this leads to an infinite loop. Fix this by fetching the child dst_entry before we continue the while loop. Fixes: 0f6c480f23f4 ("xfrm: Move dst->path into struct xfrm_dst") Reported-by: syzbot+7d03c810e50aaedef98a@syzkaller.appspotmail.com Tested-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/xfrm/xfrm_policy.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 150d46633ce6..625b3fca5704 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2732,14 +2732,14 @@ static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
2732 while (dst->xfrm) { 2732 while (dst->xfrm) {
2733 const struct xfrm_state *xfrm = dst->xfrm; 2733 const struct xfrm_state *xfrm = dst->xfrm;
2734 2734
2735 dst = xfrm_dst_child(dst);
2736
2735 if (xfrm->props.mode == XFRM_MODE_TRANSPORT) 2737 if (xfrm->props.mode == XFRM_MODE_TRANSPORT)
2736 continue; 2738 continue;
2737 if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR) 2739 if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR)
2738 daddr = xfrm->coaddr; 2740 daddr = xfrm->coaddr;
2739 else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) 2741 else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
2740 daddr = &xfrm->id.daddr; 2742 daddr = &xfrm->id.daddr;
2741
2742 dst = xfrm_dst_child(dst);
2743 } 2743 }
2744 return daddr; 2744 return daddr;
2745} 2745}