* [PATCH v1 0/2] Fix issues in xfrm_migrate @ 2022-01-06 0:52 Yan Yan 2022-01-06 0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan 2022-01-06 0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan 0 siblings, 2 replies; 9+ messages in thread From: Yan Yan @ 2022-01-06 0:52 UTC (permalink / raw) To: Steffen Klassert Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo, maze, nharold, benedictwong, Yan Yan This patch series include two patches to fix two issues in xfrm_migrate. PATCH 1/2 enables distinguishing SAs and SPs based on if_id during the xfrm_migrate flow. It fixes the problem that when there are multiple existing SPs with the same direction, the same xfrm_selector and different endpoint addresses, xfrm_migrate might fail. PATCH 2/2 enables xfrm_migrate to handle address family change by breaking the original xfrm_state_clone method into two steps so as to update the props.family before running xfrm_init_state. Yan Yan (2): xfrm: Check if_id in xfrm_migrate xfrm: Fix xfrm migrate issues when address family changes include/net/xfrm.h | 5 +++-- net/key/af_key.c | 2 +- net/xfrm/xfrm_policy.c | 14 ++++++++------ net/xfrm/xfrm_state.c | 40 ++++++++++++++++++++++++++++------------ net/xfrm/xfrm_user.c | 6 +++++- 5 files changed, 45 insertions(+), 22 deletions(-) base-commit: 18343b80691560f41c3339119a2e9314d4672c77 -- 2.34.1.448.ga2b2bfdf31-goog ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate 2022-01-06 0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan @ 2022-01-06 0:52 ` Yan Yan 2022-01-06 12:22 ` kernel test robot 2022-01-06 15:55 ` kernel test robot 2022-01-06 0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan 1 sibling, 2 replies; 9+ messages in thread From: Yan Yan @ 2022-01-06 0:52 UTC (permalink / raw) To: Steffen Klassert Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo, maze, nharold, benedictwong, Yan Yan This patch enables distinguishing SAs and SPs based on if_id during the xfrm_migrate flow. This ensures support for xfrm interfaces throughout the SA/SP lifecycle. When there are multiple existing SPs with the same direction, the same xfrm_selector and different endpoint addresses, xfrm_migrate might fail with ENODATA. Specifically, the code path for performing xfrm_migrate is: Stage 1: find policy to migrate with xfrm_migrate_policy_find(sel, dir, type, net) Stage 2: find and update state(s) with xfrm_migrate_state_find(mp, net) Stage 3: update endpoint address(es) of template(s) with xfrm_policy_migrate(pol, m, num_migrate) Currently "Stage 1" always returns the first xfrm_policy that matches, and "Stage 3" looks for the xfrm_tmpl that matches the old endpoint address. Thus if there are multiple xfrm_policy with same selector, direction, type and net, "Stage 1" might rertun a wrong xfrm_policy and "Stage 3" will fail with ENODATA because it cannot find a xfrm_tmpl with the matching endpoint address. The fix is to allow userspace to pass an if_id and add if_id to the matching rule in Stage 1 and Stage 2 since if_id is a unique ID for xfrm_policy and xfrm_state. For compatibility, if_id will only be checked if the attribute is set. Tested with additions to Android's kernel unit test suite: https://android-review.googlesource.com/c/kernel/tests/+/1668886 Signed-off-by: Yan Yan <evitayan@google.com> --- include/net/xfrm.h | 5 +++-- net/key/af_key.c | 2 +- net/xfrm/xfrm_policy.c | 14 ++++++++------ net/xfrm/xfrm_state.c | 7 ++++++- net/xfrm/xfrm_user.c | 6 +++++- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 83b46da8873d..faee50259fd4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1676,14 +1676,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, const struct xfrm_migrate *m, int num_bundles, const struct xfrm_kmaddress *k, const struct xfrm_encap_tmpl *encap); -struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net); +struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, + u32 if_id); struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, struct xfrm_migrate *m, struct xfrm_encap_tmpl *encap); int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles, struct xfrm_kmaddress *k, struct net *net, - struct xfrm_encap_tmpl *encap); + struct xfrm_encap_tmpl *encap, u32 if_id); #endif int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); diff --git a/net/key/af_key.c b/net/key/af_key.c index de24a7d474df..9bf52a09b5ff 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2623,7 +2623,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, } return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i, - kma ? &k : NULL, net, NULL); + kma ? &k : NULL, net, NULL, 0); out: return err; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 1a06585022ab..cd656b4ec5b9 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4235,7 +4235,7 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, } static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel, - u8 dir, u8 type, struct net *net) + u8 dir, u8 type, struct net *net, u32 if_id) { struct xfrm_policy *pol, *ret = NULL; struct hlist_head *chain; @@ -4244,7 +4244,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector * spin_lock_bh(&net->xfrm.xfrm_policy_lock); chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir); hlist_for_each_entry(pol, chain, bydst) { - if (xfrm_migrate_selector_match(sel, &pol->selector) && + if ((if_id == 0 || pol->if_id == if_id) && + xfrm_migrate_selector_match(sel, &pol->selector) && pol->type == type) { ret = pol; priority = ret->priority; @@ -4256,7 +4257,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector * if ((pol->priority >= priority) && ret) break; - if (xfrm_migrate_selector_match(sel, &pol->selector) && + if ((if_id == 0 || pol->if_id == if_id) && + xfrm_migrate_selector_match(sel, &pol->selector) && pol->type == type) { ret = pol; break; @@ -4372,7 +4374,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate) int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_migrate, struct xfrm_kmaddress *k, struct net *net, - struct xfrm_encap_tmpl *encap) + struct xfrm_encap_tmpl *encap, u32 if_id) { int i, err, nx_cur = 0, nx_new = 0; struct xfrm_policy *pol = NULL; @@ -4391,14 +4393,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, } /* Stage 1 - find policy */ - if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) { + if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) { err = -ENOENT; goto out; } /* Stage 2 - find and update state(s) */ for (i = 0, mp = m; i < num_migrate; i++, mp++) { - if ((x = xfrm_migrate_state_find(mp, net))) { + if (x = xfrm_migrate_state_find(mp, net, if_id)) { x_cur[nx_cur] = x; nx_cur++; xc = xfrm_state_migrate(x, mp, encap); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 0407272a990c..f52767685b13 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1603,7 +1603,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, return NULL; } -struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net) +struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, + u32 if_id) { unsigned int h; struct xfrm_state *x = NULL; @@ -1619,6 +1620,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n continue; if (m->reqid && x->props.reqid != m->reqid) continue; + if (if_id != 0 && x->if_id != if_id) + continue; if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr, m->old_family) || !xfrm_addr_equal(&x->props.saddr, &m->old_saddr, @@ -1634,6 +1637,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n if (x->props.mode != m->mode || x->id.proto != m->proto) continue; + if (if_id != 0 && x->if_id != if_id) + continue; if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr, m->old_family) || !xfrm_addr_equal(&x->props.saddr, &m->old_saddr, diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e3e26f4da6c2..eda02c5544ae 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2580,6 +2580,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, int n = 0; struct net *net = sock_net(skb->sk); struct xfrm_encap_tmpl *encap = NULL; + u32 if_id = 0; if (attrs[XFRMA_MIGRATE] == NULL) return -EINVAL; @@ -2604,7 +2605,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, return -ENOMEM; } - err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap); + if (attrs[XFRMA_IF_ID]) + if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + + err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id); kfree(encap); -- 2.34.1.448.ga2b2bfdf31-goog ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate 2022-01-06 0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan @ 2022-01-06 12:22 ` kernel test robot 2022-01-06 15:55 ` kernel test robot 1 sibling, 0 replies; 9+ messages in thread From: kernel test robot @ 2022-01-06 12:22 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 2870 bytes --] Hi Yan, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77] url: https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 base: 18343b80691560f41c3339119a2e9314d4672c77 config: arc-randconfig-r032-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062019.VFveWcCu-lkp(a)intel.com/config) compiler: arceb-elf-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 git checkout 2be451f5a66efd5951102e188daee7c730f55dc7 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash net/xfrm/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): net/xfrm/xfrm_policy.c: In function 'xfrm_migrate': >> net/xfrm/xfrm_policy.c:4403:21: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 4403 | if (x = xfrm_migrate_state_find(mp, net, if_id)) { | ^ vim +4403 net/xfrm/xfrm_policy.c 4373 4374 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, 4375 struct xfrm_migrate *m, int num_migrate, 4376 struct xfrm_kmaddress *k, struct net *net, 4377 struct xfrm_encap_tmpl *encap, u32 if_id) 4378 { 4379 int i, err, nx_cur = 0, nx_new = 0; 4380 struct xfrm_policy *pol = NULL; 4381 struct xfrm_state *x, *xc; 4382 struct xfrm_state *x_cur[XFRM_MAX_DEPTH]; 4383 struct xfrm_state *x_new[XFRM_MAX_DEPTH]; 4384 struct xfrm_migrate *mp; 4385 4386 /* Stage 0 - sanity checks */ 4387 if ((err = xfrm_migrate_check(m, num_migrate)) < 0) 4388 goto out; 4389 4390 if (dir >= XFRM_POLICY_MAX) { 4391 err = -EINVAL; 4392 goto out; 4393 } 4394 4395 /* Stage 1 - find policy */ 4396 if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) { 4397 err = -ENOENT; 4398 goto out; 4399 } 4400 4401 /* Stage 2 - find and update state(s) */ 4402 for (i = 0, mp = m; i < num_migrate; i++, mp++) { > 4403 if (x = xfrm_migrate_state_find(mp, net, if_id)) { --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate 2022-01-06 0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan @ 2022-01-06 15:55 ` kernel test robot 2022-01-06 15:55 ` kernel test robot 1 sibling, 0 replies; 9+ messages in thread From: kernel test robot @ 2022-01-06 15:55 UTC (permalink / raw) To: Yan Yan; +Cc: llvm, kbuild-all Hi Yan, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77] url: https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 base: 18343b80691560f41c3339119a2e9314d4672c77 config: riscv-randconfig-r002-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062313.QMYcwsyC-lkp@intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 git checkout 2be451f5a66efd5951102e188daee7c730f55dc7 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash net/xfrm/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; ~~~~~~~~~~ ^ >> net/xfrm/xfrm_policy.c:4403:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] if (x = xfrm_migrate_state_find(mp, net, if_id)) { ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ net/xfrm/xfrm_policy.c:4403:9: note: place parentheses around the assignment to silence this warning if (x = xfrm_migrate_state_find(mp, net, if_id)) { ^ ( ) net/xfrm/xfrm_policy.c:4403:9: note: use '==' to turn this assignment into an equality comparison if (x = xfrm_migrate_state_find(mp, net, if_id)) { ^ == 8 warnings generated. vim +4403 net/xfrm/xfrm_policy.c 4373 4374 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, 4375 struct xfrm_migrate *m, int num_migrate, 4376 struct xfrm_kmaddress *k, struct net *net, 4377 struct xfrm_encap_tmpl *encap, u32 if_id) 4378 { 4379 int i, err, nx_cur = 0, nx_new = 0; 4380 struct xfrm_policy *pol = NULL; 4381 struct xfrm_state *x, *xc; 4382 struct xfrm_state *x_cur[XFRM_MAX_DEPTH]; 4383 struct xfrm_state *x_new[XFRM_MAX_DEPTH]; 4384 struct xfrm_migrate *mp; 4385 4386 /* Stage 0 - sanity checks */ 4387 if ((err = xfrm_migrate_check(m, num_migrate)) < 0) 4388 goto out; 4389 4390 if (dir >= XFRM_POLICY_MAX) { 4391 err = -EINVAL; 4392 goto out; 4393 } 4394 4395 /* Stage 1 - find policy */ 4396 if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) { 4397 err = -ENOENT; 4398 goto out; 4399 } 4400 4401 /* Stage 2 - find and update state(s) */ 4402 for (i = 0, mp = m; i < num_migrate; i++, mp++) { > 4403 if (x = xfrm_migrate_state_find(mp, net, if_id)) { --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 1/2] xfrm: Check if_id in xfrm_migrate @ 2022-01-06 15:55 ` kernel test robot 0 siblings, 0 replies; 9+ messages in thread From: kernel test robot @ 2022-01-06 15:55 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 7961 bytes --] Hi Yan, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 18343b80691560f41c3339119a2e9314d4672c77] url: https://github.com/0day-ci/linux/commits/Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 base: 18343b80691560f41c3339119a2e9314d4672c77 config: riscv-randconfig-r002-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062313.QMYcwsyC-lkp(a)intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # https://github.com/0day-ci/linux/commit/2be451f5a66efd5951102e188daee7c730f55dc7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Yan-Yan/Fix-issues-in-xfrm_migrate/20220106-085707 git checkout 2be451f5a66efd5951102e188daee7c730f55dc7 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash net/xfrm/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from net/xfrm/xfrm_policy.c:24: In file included from include/linux/netdevice.h:37: In file included from include/net/net_namespace.h:40: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/riscv/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/riscv/include/asm/io.h:136: include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; ~~~~~~~~~~ ^ >> net/xfrm/xfrm_policy.c:4403:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] if (x = xfrm_migrate_state_find(mp, net, if_id)) { ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ net/xfrm/xfrm_policy.c:4403:9: note: place parentheses around the assignment to silence this warning if (x = xfrm_migrate_state_find(mp, net, if_id)) { ^ ( ) net/xfrm/xfrm_policy.c:4403:9: note: use '==' to turn this assignment into an equality comparison if (x = xfrm_migrate_state_find(mp, net, if_id)) { ^ == 8 warnings generated. vim +4403 net/xfrm/xfrm_policy.c 4373 4374 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, 4375 struct xfrm_migrate *m, int num_migrate, 4376 struct xfrm_kmaddress *k, struct net *net, 4377 struct xfrm_encap_tmpl *encap, u32 if_id) 4378 { 4379 int i, err, nx_cur = 0, nx_new = 0; 4380 struct xfrm_policy *pol = NULL; 4381 struct xfrm_state *x, *xc; 4382 struct xfrm_state *x_cur[XFRM_MAX_DEPTH]; 4383 struct xfrm_state *x_new[XFRM_MAX_DEPTH]; 4384 struct xfrm_migrate *mp; 4385 4386 /* Stage 0 - sanity checks */ 4387 if ((err = xfrm_migrate_check(m, num_migrate)) < 0) 4388 goto out; 4389 4390 if (dir >= XFRM_POLICY_MAX) { 4391 err = -EINVAL; 4392 goto out; 4393 } 4394 4395 /* Stage 1 - find policy */ 4396 if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) { 4397 err = -ENOENT; 4398 goto out; 4399 } 4400 4401 /* Stage 2 - find and update state(s) */ 4402 for (i = 0, mp = m; i < num_migrate; i++, mp++) { > 4403 if (x = xfrm_migrate_state_find(mp, net, if_id)) { --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes 2022-01-06 0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan 2022-01-06 0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan @ 2022-01-06 0:52 ` Yan Yan 2022-01-12 7:57 ` Steffen Klassert 1 sibling, 1 reply; 9+ messages in thread From: Yan Yan @ 2022-01-06 0:52 UTC (permalink / raw) To: Steffen Klassert Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo, maze, nharold, benedictwong, Yan Yan xfrm_migrate cannot handle address family change of an xfrm_state. The symptons are the xfrm_state will be migrated to a wrong address, and sending as well as receiving packets wil be broken. This commit fixes it by breaking the original xfrm_state_clone method into two steps so as to update the props.family before running xfrm_init_state. As the result, xfrm_state's inner mode, outer mode, type and IP header length in xfrm_state_migrate can be updated with the new address family. Tested with additions to Android's kernel unit test suite: https://android-review.googlesource.com/c/kernel/tests/+/1885354 Signed-off-by: Yan Yan <evitayan@google.com> --- net/xfrm/xfrm_state.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f52767685b13..cac212039bf9 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1504,8 +1504,8 @@ static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx *secu return 0; } -static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, - struct xfrm_encap_tmpl *encap) +static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig, + struct xfrm_encap_tmpl *encap) { struct net *net = xs_net(orig); struct xfrm_state *x = xfrm_state_alloc(net); @@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, memcpy(&x->mark, &orig->mark, sizeof(x->mark)); memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark)); - if (xfrm_init_state(x) < 0) - goto error; + return x; + + error: + xfrm_state_put(x); +out: + return NULL; +} + +static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x) +{ + int err = xfrm_init_state(x); + + if (err < 0) + return err; x->props.flags = orig->props.flags; x->props.extra_flags = orig->props.extra_flags; @@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, x->replay = orig->replay; x->preplay = orig->preplay; - return x; - - error: - xfrm_state_put(x); -out: - return NULL; + return 0; } struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, @@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, { struct xfrm_state *xc; - xc = xfrm_state_clone(x, encap); + xc = xfrm_state_clone1(x, encap); if (!xc) return NULL; + xc->props.family = m->new_family; + if (xfrm_state_clone2(x, xc) < 0) + goto error; + memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr)); memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr)); -- 2.34.1.448.ga2b2bfdf31-goog ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes 2022-01-06 0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan @ 2022-01-12 7:57 ` Steffen Klassert 2022-01-19 0:03 ` Yan Yan 0 siblings, 1 reply; 9+ messages in thread From: Steffen Klassert @ 2022-01-12 7:57 UTC (permalink / raw) To: Yan Yan Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, lorenzo, maze, nharold, benedictwong On Wed, Jan 05, 2022 at 04:52:51PM -0800, Yan Yan wrote: ... > -static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > - struct xfrm_encap_tmpl *encap) > +static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig, > + struct xfrm_encap_tmpl *encap) > { > struct net *net = xs_net(orig); > struct xfrm_state *x = xfrm_state_alloc(net); > @@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > memcpy(&x->mark, &orig->mark, sizeof(x->mark)); > memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark)); > > - if (xfrm_init_state(x) < 0) > - goto error; > + return x; > + > + error: > + xfrm_state_put(x); > +out: > + return NULL; > +} > + > +static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x) I'm not a frind of numbering function names, this just invites to create xfrm_state_clone3 :) > +{ > + int err = xfrm_init_state(x); > + > + if (err < 0) > + return err; > > x->props.flags = orig->props.flags; > x->props.extra_flags = orig->props.extra_flags; > @@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > x->replay = orig->replay; > x->preplay = orig->preplay; > > - return x; > - > - error: > - xfrm_state_put(x); > -out: > - return NULL; > + return 0; > } > > struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, > @@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, > { > struct xfrm_state *xc; > > - xc = xfrm_state_clone(x, encap); > + xc = xfrm_state_clone1(x, encap); > if (!xc) > return NULL; > > + xc->props.family = m->new_family; > + if (xfrm_state_clone2(x, xc) < 0) > + goto error; xfrm_state_migrate() is the only function that calls xfrm_state_clone(). Wouldn't it be better to move xfrm_init_state() out of xfrm_state_clone() and call it afterwards? This would also fix the replay window initialization on ESN because currently x->props.flags (which holds XFRM_STATE_ESN) is initialized after xfrm_init_state(). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes 2022-01-12 7:57 ` Steffen Klassert @ 2022-01-19 0:03 ` Yan Yan 0 siblings, 0 replies; 9+ messages in thread From: Yan Yan @ 2022-01-19 0:03 UTC (permalink / raw) To: Steffen Klassert Cc: netdev, Herbert Xu, David S . Miller, Jakub Kicinski, Lorenzo Colitti, Maciej Żenczykowski, nharold, benedictwong Thanks Steffen, I will pull out xfrm_init_state() as you suggested. On Tue, Jan 11, 2022 at 11:57 PM Steffen Klassert <steffen.klassert@secunet.com> wrote: > > On Wed, Jan 05, 2022 at 04:52:51PM -0800, Yan Yan wrote: > > ... > > > -static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > > - struct xfrm_encap_tmpl *encap) > > +static struct xfrm_state *xfrm_state_clone1(struct xfrm_state *orig, > > + struct xfrm_encap_tmpl *encap) > > { > > struct net *net = xs_net(orig); > > struct xfrm_state *x = xfrm_state_alloc(net); > > @@ -1579,8 +1579,20 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > > memcpy(&x->mark, &orig->mark, sizeof(x->mark)); > > memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark)); > > > > - if (xfrm_init_state(x) < 0) > > - goto error; > > + return x; > > + > > + error: > > + xfrm_state_put(x); > > +out: > > + return NULL; > > +} > > + > > +static int xfrm_state_clone2(struct xfrm_state *orig, struct xfrm_state *x) > > I'm not a frind of numbering function names, this just invites to > create xfrm_state_clone3 :) > > > +{ > > + int err = xfrm_init_state(x); > > + > > + if (err < 0) > > + return err; > > > > x->props.flags = orig->props.flags; > > x->props.extra_flags = orig->props.extra_flags; > > @@ -1595,12 +1607,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, > > x->replay = orig->replay; > > x->preplay = orig->preplay; > > > > - return x; > > - > > - error: > > - xfrm_state_put(x); > > -out: > > - return NULL; > > + return 0; > > } > > > > struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, > > @@ -1661,10 +1668,14 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, > > { > > struct xfrm_state *xc; > > > > - xc = xfrm_state_clone(x, encap); > > + xc = xfrm_state_clone1(x, encap); > > if (!xc) > > return NULL; > > > > + xc->props.family = m->new_family; > > + if (xfrm_state_clone2(x, xc) < 0) > > + goto error; > > xfrm_state_migrate() is the only function that calls xfrm_state_clone(). > Wouldn't it be better to move xfrm_init_state() out of xfrm_state_clone() > and call it afterwards? > > This would also fix the replay window initialization on ESN because > currently x->props.flags (which holds XFRM_STATE_ESN) is initialized > after xfrm_init_state(). > -- -- Best, Yan ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v1 0/2] Fix issues in xfrm_migrate @ 2021-12-23 0:45 Yan Yan 0 siblings, 0 replies; 9+ messages in thread From: Yan Yan @ 2021-12-23 0:45 UTC (permalink / raw) To: steffen.klassert Cc: herbert, davem, netdev, nharold, benedictwong, maze, lorenzo, Yan Yan This patch series include two patches to fix two issues in xfrm_migrate. PATCH 1/2 enables distinguishing SAs and SPs based on if_id during the xfrm_migrate flow. It fixes the problem that when there are multiple existing SPs with the same direction, the same xfrm_selector and different endpoint addresses, xfrm_migrate might fail. PATCH 2/2 enables xfrm_migrate to handle address family change by breaking the original xfrm_state_clone method into two steps so as to update the props.family before running xfrm_init_state. Yan Yan (2): xfrm: Check if_id in xfrm_migrate xfrm: Fix xfrm migrate issues when address family changes include/net/xfrm.h | 5 +++-- net/xfrm/xfrm_policy.c | 14 ++++++++------ net/xfrm/xfrm_state.c | 38 +++++++++++++++++++++++++++----------- net/xfrm/xfrm_user.c | 6 +++++- 4 files changed, 43 insertions(+), 20 deletions(-) -- 2.34.1.307.g9b7440fafd-goog ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-01-19 0:03 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-01-06 0:52 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan 2022-01-06 0:52 ` [PATCH v1 1/2] xfrm: Check if_id " Yan Yan 2022-01-06 12:22 ` kernel test robot 2022-01-06 15:55 ` kernel test robot 2022-01-06 15:55 ` kernel test robot 2022-01-06 0:52 ` [PATCH v1 2/2] xfrm: Fix xfrm migrate issues when address family changes Yan Yan 2022-01-12 7:57 ` Steffen Klassert 2022-01-19 0:03 ` Yan Yan -- strict thread matches above, loose matches on Subject: below -- 2021-12-23 0:45 [PATCH v1 0/2] Fix issues in xfrm_migrate Yan Yan
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.