public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Yan Yan <evitayan@google.com>,
	Steffen Klassert <steffen.klassert@secunet.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.4 25/43] xfrm: Check if_id in xfrm_migrate
Date: Thu, 17 Mar 2022 13:45:36 +0100	[thread overview]
Message-ID: <20220317124528.374694054@linuxfoundation.org> (raw)
In-Reply-To: <20220317124527.672236844@linuxfoundation.org>

From: Yan Yan <evitayan@google.com>

[ Upstream commit c1aca3080e382886e2e58e809787441984a2f89b ]

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>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 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 614f19bbad74..96faf0918694 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1663,14 +1663,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 907d04a47459..406e13478b01 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2627,7 +2627,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 404823c5eb7d..3ecb77c58c44 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4271,7 +4271,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;
@@ -4280,7 +4280,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;
@@ -4292,7 +4293,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;
@@ -4408,7 +4410,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;
@@ -4427,14 +4429,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 1423e2b7cb42..83ee3d337a60 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1563,7 +1563,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;
@@ -1579,6 +1580,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,
@@ -1594,6 +1597,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 ddcf569d852f..bd44a800e7db 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2374,6 +2374,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;
@@ -2398,7 +2399,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 			return 0;
 	}
 
-	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




  parent reply	other threads:[~2022-03-17 12:48 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-17 12:45 [PATCH 5.4 00/43] 5.4.186-rc1 review Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 01/43] Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0" Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 02/43] sctp: fix the processing for INIT chunk Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 03/43] arm64: Add part number for Arm Cortex-A77 Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 04/43] arm64: Add Neoverse-N2, Cortex-A710 CPU part definition Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 05/43] arm64: add ID_AA64ISAR2_EL1 sys register Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 06/43] arm64: Add Cortex-X2 CPU part definition Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 07/43] arm64: entry.S: Add ventry overflow sanity checks Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 08/43] arm64: entry: Make the trampoline cleanup optional Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 09/43] arm64: entry: Free up another register on kptis tramp_exit path Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 10/43] arm64: entry: Move the trampoline data page before the text page Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 11/43] arm64: entry: Allow tramp_alias to access symbols after the 4K boundary Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 12/43] arm64: entry: Dont assume tramp_vectors is the start of the vectors Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 13/43] arm64: entry: Move trampoline macros out of ifdefd section Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 14/43] arm64: entry: Make the kpti trampolines kpti sequence optional Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 15/43] arm64: entry: Allow the trampoline text to occupy multiple pages Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 16/43] arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 17/43] arm64: entry: Add vectors that have the bhb mitigation sequences Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 18/43] arm64: entry: Add macro for reading symbol addresses from the trampoline Greg Kroah-Hartman
2022-03-17 20:48   ` Florian Fainelli
2022-03-18 12:11     ` James Morse
2022-03-18 16:18       ` Greg Kroah-Hartman
2022-03-18 16:21         ` Greg Kroah-Hartman
2022-03-18 17:37           ` fixup for [PATCH 5.4 18/43] arm64 entry: Add macro for reading symbol address " James Morse
2022-03-19  8:17             ` Greg Kroah-Hartman
2022-03-18 16:33       ` [PATCH 5.4 18/43] arm64: entry: Add macro for reading symbol addresses " Florian Fainelli
2022-03-17 12:45 ` [PATCH 5.4 19/43] arm64: Add percpu vectors for EL1 Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 20/43] arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of Spectre-v2 Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 21/43] KVM: arm64: Add templates for BHB mitigation sequences Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 22/43] arm64: Mitigate spectre style branch history side channels Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 23/43] KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 24/43] arm64: Use the clearbhb instruction in mitigations Greg Kroah-Hartman
2022-03-17 12:45 ` Greg Kroah-Hartman [this message]
2022-03-17 12:45 ` [PATCH 5.4 26/43] xfrm: Fix xfrm migrate issues when address family changes Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 27/43] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 28/43] arm64: dts: rockchip: reorder rk3399 hdmi clocks Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 29/43] arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg" Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 30/43] ARM: dts: rockchip: reorder rk322x hmdi clocks Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 31/43] ARM: dts: rockchip: fix a typo on rk3288 crypto-controller Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 32/43] mac80211: refuse aggregations sessions before authorized Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 33/43] MIPS: smp: fill in sibling and core maps earlier Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 34/43] ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 35/43] can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when fully ready Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 36/43] atm: firestream: check the return value of ioremap() in fs_init() Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 37/43] iwlwifi: dont advertise TWT support Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 38/43] drm/vrr: Set VRR capable prop only if it is attached to connector Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 39/43] nl80211: Update bss channel on channel switch for P2P_CLIENT Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 40/43] tcp: make tcp_read_sock() more robust Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 41/43] sfc: extend the locking on mcdi->seqno Greg Kroah-Hartman
2022-03-17 12:45 ` [PATCH 5.4 42/43] bnx2: Fix an error message Greg Kroah-Hartman
2022-03-18 17:32   ` Marion & Christophe JAILLET
2022-03-17 12:45 ` [PATCH 5.4 43/43] kselftest/vm: fix tests build with old libc Greg Kroah-Hartman
2022-03-17 20:48 ` [PATCH 5.4 00/43] 5.4.186-rc1 review Florian Fainelli
2022-03-18  2:18 ` Guenter Roeck
2022-03-18 12:03 ` Naresh Kamboju
2022-03-18 16:30 ` Sudip Mukherjee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220317124528.374694054@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=evitayan@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=steffen.klassert@secunet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox