1 |
From 4c064c00aa3e71ea0f1f8db73d2f053a4df6a227 Mon Sep 17 00:00:00 2001 |
2 |
From: Sasha Levin <sashal@kernel.org> |
3 |
Date: Tue, 18 Jan 2022 16:00:14 -0800 |
4 |
Subject: xfrm: Fix xfrm migrate issues when address family changes |
5 |
|
6 |
From: Yan Yan <evitayan@google.com> |
7 |
|
8 |
[ Upstream commit e03c3bba351f99ad932e8f06baa9da1afc418e02 ] |
9 |
|
10 |
xfrm_migrate cannot handle address family change of an xfrm_state. |
11 |
The symptons are the xfrm_state will be migrated to a wrong address, |
12 |
and sending as well as receiving packets wil be broken. |
13 |
|
14 |
This commit fixes it by breaking the original xfrm_state_clone |
15 |
method into two steps so as to update the props.family before |
16 |
running xfrm_init_state. As the result, xfrm_state's inner mode, |
17 |
outer mode, type and IP header length in xfrm_state_migrate can |
18 |
be updated with the new address family. |
19 |
|
20 |
Tested with additions to Android's kernel unit test suite: |
21 |
https://android-review.googlesource.com/c/kernel/tests/+/1885354 |
22 |
|
23 |
Signed-off-by: Yan Yan <evitayan@google.com> |
24 |
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> |
25 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
26 |
--- |
27 |
net/xfrm/xfrm_state.c | 8 +++++--- |
28 |
1 file changed, 5 insertions(+), 3 deletions(-) |
29 |
|
30 |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c |
31 |
index 291236d7676f..f7bfa1916968 100644 |
32 |
--- a/net/xfrm/xfrm_state.c |
33 |
+++ b/net/xfrm/xfrm_state.c |
34 |
@@ -1578,9 +1578,6 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, |
35 |
memcpy(&x->mark, &orig->mark, sizeof(x->mark)); |
36 |
memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark)); |
37 |
|
38 |
- if (xfrm_init_state(x) < 0) |
39 |
- goto error; |
40 |
- |
41 |
x->props.flags = orig->props.flags; |
42 |
x->props.extra_flags = orig->props.extra_flags; |
43 |
|
44 |
@@ -1667,6 +1664,11 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, |
45 |
if (!xc) |
46 |
return NULL; |
47 |
|
48 |
+ xc->props.family = m->new_family; |
49 |
+ |
50 |
+ if (xfrm_init_state(xc) < 0) |
51 |
+ goto error; |
52 |
+ |
53 |
memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr)); |
54 |
memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr)); |
55 |
|
56 |
-- |
57 |
2.34.1 |
58 |
|