All of lore.kernel.org
 help / color / mirror / Atom feed
* Re-adding support for nested IPsec tunnels
@ 2023-05-10  1:30 Benedict Wong
  2023-05-10  1:30 ` [PATCH ipsec 1/2] xfrm: Treat already-verified secpath entries as optional Benedict Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Benedict Wong @ 2023-05-10  1:30 UTC (permalink / raw)
  To: netdev, steffen.klassert, martin; +Cc: nharold, benedictwong, evitayan

This patch set adds support for inbound nested IPsec tunnels within the 
same network namespace by incrementally marking verified secpath entries 
once policy checks are complete. This allows verification that each layer 
of nested tunnels can be verified, even where the outermost headers 
change (src/dst/proto/etc). 

The previous iteration b0355dbbf13c ("Fix XFRM-I support for nested ESP 
tunnels") attempted to clear secpath entries once verified, but that 
caused issues with netfilter policy matching (lack of secpath entries to 
match against), and transport-in-tunnel mode (where the tunnel policies 
are still resolvable, and thus expected). 

Notably, all secpath entries (except where optional) must still have the 
secpath entries validated, but they may now happen in multiple steps.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH ipsec 1/2] xfrm: Treat already-verified secpath entries as optional
  2023-05-10  1:30 Re-adding support for nested IPsec tunnels Benedict Wong
@ 2023-05-10  1:30 ` Benedict Wong
  2023-05-10  1:30 ` [PATCH ipsec 2/2] xfrm: Ensure policies always checked on XFRM-I input path Benedict Wong
  2023-05-31 12:13 ` Re-adding support for nested IPsec tunnels Steffen Klassert
  2 siblings, 0 replies; 4+ messages in thread
From: Benedict Wong @ 2023-05-10  1:30 UTC (permalink / raw)
  To: netdev, steffen.klassert, martin; +Cc: nharold, benedictwong, evitayan

This change allows inbound traffic through nested IPsec tunnels to
successfully match policies and templates, while retaining the secpath
stack trace as necessary for netfilter policies.

Specifically, this patch marks secpath entries that have already matched
against a relevant policy as having been verified, allowing it to be
treated as optional and skipped after a tunnel decapsulation (during
which the src/dst/proto/etc may have changed, and the correct policy
chain no long be resolvable).

This approach is taken as opposed to the iteration in b0355dbbf13c,
where the secpath was cleared, since that breaks subsequent validations
that rely on the existence of the secpath entries (netfilter policies, or
transport-in-tunnel mode, where policies remain resolvable).

Fixes: b0355dbbf13c ("Fix XFRM-I support for nested ESP tunnels")
Test: Tested against Android Kernel Unit Tests
Test: Tested against Android CTS
Signed-off-by: Benedict Wong <benedictwong@google.com>
---
 include/net/xfrm.h     |  1 +
 net/xfrm/xfrm_input.c  |  1 +
 net/xfrm/xfrm_policy.c | 12 ++++++++++++
 3 files changed, 14 insertions(+)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 3e1f70e8e424..47ecf1d4719b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1049,6 +1049,7 @@ struct xfrm_offload {
 struct sec_path {
 	int			len;
 	int			olen;
+	int			verified_cnt;
 
 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
 	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 436d29640ac2..9f294a20dcec 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -131,6 +131,7 @@ struct sec_path *secpath_set(struct sk_buff *skb)
 	memset(sp->ovec, 0, sizeof(sp->ovec));
 	sp->olen = 0;
 	sp->len = 0;
+	sp->verified_cnt = 0;
 
 	return sp;
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6d15788b5123..ff58ce6c030c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3349,6 +3349,13 @@ xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int star
 		if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id))
 			return ++idx;
 		if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) {
+			if (idx < sp->verified_cnt) {
+				/* Secpath entry previously verified, consider optional and
+				 * continue searching
+				 */
+				continue;
+			}
+
 			if (start == -1)
 				start = -2-idx;
 			break;
@@ -3723,6 +3730,9 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 		 * Order is _important_. Later we will implement
 		 * some barriers, but at the moment barriers
 		 * are implied between each two transformations.
+		 * Upon success, marks secpath entries as having been
+		 * verified to allow them to be skipped in future policy
+		 * checks (e.g. nested tunnels).
 		 */
 		for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
 			k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
@@ -3741,6 +3751,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 		}
 
 		xfrm_pols_put(pols, npols);
+		sp->verified_cnt = k;
+
 		return 1;
 	}
 	XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
-- 
2.40.1.521.gf1e218fcd8-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH ipsec 2/2] xfrm: Ensure policies always checked on XFRM-I input path
  2023-05-10  1:30 Re-adding support for nested IPsec tunnels Benedict Wong
  2023-05-10  1:30 ` [PATCH ipsec 1/2] xfrm: Treat already-verified secpath entries as optional Benedict Wong
@ 2023-05-10  1:30 ` Benedict Wong
  2023-05-31 12:13 ` Re-adding support for nested IPsec tunnels Steffen Klassert
  2 siblings, 0 replies; 4+ messages in thread
From: Benedict Wong @ 2023-05-10  1:30 UTC (permalink / raw)
  To: netdev, steffen.klassert, martin; +Cc: nharold, benedictwong, evitayan

This change adds methods in the XFRM-I input path that ensures that
policies are checked prior to processing of the subsequent decapsulated
packet, after which the relevant policies may no longer be resolvable
(due to changing src/dst/proto/etc).

Notably, raw ESP/AH packets did not perform policy checks inherently,
whereas all other encapsulated packets (UDP, TCP encapsulated) do policy
checks after calling xfrm_input handling in the respective encapsulation
layer.

Fixes: b0355dbbf13c ("Fix XFRM-I support for nested ESP tunnels")
Test: Verified with additional Android Kernel Unit tests
Test: Verified against Android CTS
Signed-off-by: Benedict Wong <benedictwong@google.com>
---
 net/xfrm/xfrm_interface_core.c | 54 +++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 4 deletions(-)

diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c
index 1f99dc469027..35279c220bd7 100644
--- a/net/xfrm/xfrm_interface_core.c
+++ b/net/xfrm/xfrm_interface_core.c
@@ -310,6 +310,52 @@ static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet)
 	skb->mark = 0;
 }
 
+static int xfrmi_input(struct sk_buff *skb, int nexthdr, __be32 spi,
+		       int encap_type, unsigned short family)
+{
+	struct sec_path *sp;
+
+	sp = skb_sec_path(skb);
+	if (sp && (sp->len || sp->olen) &&
+	    !xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family))
+		goto discard;
+
+	XFRM_SPI_SKB_CB(skb)->family = family;
+	if (family == AF_INET) {
+		XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
+		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
+	} else {
+		XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
+	}
+
+	return xfrm_input(skb, nexthdr, spi, encap_type);
+discard:
+	kfree_skb(skb);
+	return 0;
+}
+
+static int xfrmi4_rcv(struct sk_buff *skb)
+{
+	return xfrmi_input(skb, ip_hdr(skb)->protocol, 0, 0, AF_INET);
+}
+
+static int xfrmi6_rcv(struct sk_buff *skb)
+{
+	return xfrmi_input(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+			   0, 0, AF_INET6);
+}
+
+static int xfrmi4_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+	return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET);
+}
+
+static int xfrmi6_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+	return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET6);
+}
+
 static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
 {
 	const struct xfrm_mode *inner_mode;
@@ -945,8 +991,8 @@ static struct pernet_operations xfrmi_net_ops = {
 };
 
 static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = {
-	.handler	=	xfrm6_rcv,
-	.input_handler	=	xfrm_input,
+	.handler	=	xfrmi6_rcv,
+	.input_handler	=	xfrmi6_input,
 	.cb_handler	=	xfrmi_rcv_cb,
 	.err_handler	=	xfrmi6_err,
 	.priority	=	10,
@@ -996,8 +1042,8 @@ static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = {
 #endif
 
 static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = {
-	.handler	=	xfrm4_rcv,
-	.input_handler	=	xfrm_input,
+	.handler	=	xfrmi4_rcv,
+	.input_handler	=	xfrmi4_input,
 	.cb_handler	=	xfrmi_rcv_cb,
 	.err_handler	=	xfrmi4_err,
 	.priority	=	10,
-- 
2.40.1.521.gf1e218fcd8-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: Re-adding support for nested IPsec tunnels
  2023-05-10  1:30 Re-adding support for nested IPsec tunnels Benedict Wong
  2023-05-10  1:30 ` [PATCH ipsec 1/2] xfrm: Treat already-verified secpath entries as optional Benedict Wong
  2023-05-10  1:30 ` [PATCH ipsec 2/2] xfrm: Ensure policies always checked on XFRM-I input path Benedict Wong
@ 2023-05-31 12:13 ` Steffen Klassert
  2 siblings, 0 replies; 4+ messages in thread
From: Steffen Klassert @ 2023-05-31 12:13 UTC (permalink / raw)
  To: Benedict Wong; +Cc: netdev, martin, nharold, evitayan

On Wed, May 10, 2023 at 01:30:20AM +0000, Benedict Wong wrote:
> This patch set adds support for inbound nested IPsec tunnels within the 
> same network namespace by incrementally marking verified secpath entries 
> once policy checks are complete. This allows verification that each layer 
> of nested tunnels can be verified, even where the outermost headers 
> change (src/dst/proto/etc). 
> 
> The previous iteration b0355dbbf13c ("Fix XFRM-I support for nested ESP 
> tunnels") attempted to clear secpath entries once verified, but that 
> caused issues with netfilter policy matching (lack of secpath entries to 
> match against), and transport-in-tunnel mode (where the tunnel policies 
> are still resolvable, and thus expected). 
> 
> Notably, all secpath entries (except where optional) must still have the 
> secpath entries validated, but they may now happen in multiple steps.
> 

Series now applied, thanks Ben!

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-05-31 12:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-10  1:30 Re-adding support for nested IPsec tunnels Benedict Wong
2023-05-10  1:30 ` [PATCH ipsec 1/2] xfrm: Treat already-verified secpath entries as optional Benedict Wong
2023-05-10  1:30 ` [PATCH ipsec 2/2] xfrm: Ensure policies always checked on XFRM-I input path Benedict Wong
2023-05-31 12:13 ` Re-adding support for nested IPsec tunnels Steffen Klassert

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.