netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH ipsec 0/3] Fixes for the ipsec tree
@ 2022-03-07 12:11 Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 1/3] esp: Fix possible buffer overflow in ESP transformation Steffen Klassert
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Steffen Klassert @ 2022-03-07 12:11 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert

I plan to apply the following fixes to the ipsec tree:

1) Fix possible buffer overflow in ESP output transformation.

2) Fix BEET mode for ESP inter address family tunneling on GSO.

3) Fix ESP GSO on inter address family tunnels.

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

* [PATCH ipsec 1/3] esp: Fix possible buffer overflow in ESP transformation
  2022-03-07 12:11 [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
@ 2022-03-07 12:11 ` Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 2/3] esp: Fix BEET mode inter address family tunneling on GSO Steffen Klassert
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2022-03-07 12:11 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert

The maximum message size that can be send is bigger than
the  maximum site that skb_page_frag_refill can allocate.
So it is possible to write beyond the allocated buffer.

Fix this by doing a fallback to COW in that case.

v2:

Avoid get get_order() costs as suggested by Linus Torvalds.

Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
Reported-by: valis <sec@valis.email>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/esp.h | 2 ++
 net/ipv4/esp4.c   | 5 +++++
 net/ipv6/esp6.c   | 5 +++++
 3 files changed, 12 insertions(+)

diff --git a/include/net/esp.h b/include/net/esp.h
index 9c5637d41d95..90cd02ff77ef 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -4,6 +4,8 @@
 
 #include <linux/skbuff.h>
 
+#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER)
+
 struct ip_esp_hdr;
 
 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index e1b1d080e908..70e6c87fbe3d 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -446,6 +446,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
 	struct page *page;
 	struct sk_buff *trailer;
 	int tailen = esp->tailen;
+	unsigned int allocsz;
 
 	/* this is non-NULL only with TCP/UDP Encapsulation */
 	if (x->encap) {
@@ -455,6 +456,10 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
 			return err;
 	}
 
+	allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+	if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+		goto cow;
+
 	if (!skb_cloned(skb)) {
 		if (tailen <= skb_tailroom(skb)) {
 			nfrags = 1;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 7591160edce1..b0ffbcd5432d 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -482,6 +482,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
 	struct page *page;
 	struct sk_buff *trailer;
 	int tailen = esp->tailen;
+	unsigned int allocsz;
 
 	if (x->encap) {
 		int err = esp6_output_encap(x, skb, esp);
@@ -490,6 +491,10 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
 			return err;
 	}
 
+	allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+	if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+		goto cow;
+
 	if (!skb_cloned(skb)) {
 		if (tailen <= skb_tailroom(skb)) {
 			nfrags = 1;
-- 
2.25.1


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

* [PATCH ipsec 2/3] esp: Fix BEET mode inter address family tunneling on GSO
  2022-03-07 12:11 [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 1/3] esp: Fix possible buffer overflow in ESP transformation Steffen Klassert
@ 2022-03-07 12:11 ` Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 3/3] net: Fix esp GSO on inter address family tunnels Steffen Klassert
  2022-03-08  7:00 ` [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
  3 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2022-03-07 12:11 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert

The xfrm{4,6}_beet_gso_segment() functions did not correctly set the
SKB_GSO_IPXIP4 and SKB_GSO_IPXIP6 gso types for the address family
tunneling case. Fix this by setting these gso types.

Fixes: 384a46ea7bdc7 ("esp4: add gso_segment for esp4 beet mode")
Fixes: 7f9e40eb18a99 ("esp6: add gso_segment for esp6 beet mode")
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/ipv4/esp4_offload.c | 3 +++
 net/ipv6/esp6_offload.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index d87f02a6e934..146d4d54830c 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -160,6 +160,9 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x,
 			skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
 	}
 
+	if (proto == IPPROTO_IPV6)
+		skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
+
 	__skb_pull(skb, skb_transport_offset(skb));
 	ops = rcu_dereference(inet_offloads[proto]);
 	if (likely(ops && ops->callbacks.gso_segment))
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index ba5e81cd569c..e61172d50817 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -199,6 +199,9 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
 			ipv6_skip_exthdr(skb, 0, &proto, &frag);
 	}
 
+	if (proto == IPPROTO_IPIP)
+		skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP6;
+
 	__skb_pull(skb, skb_transport_offset(skb));
 	ops = rcu_dereference(inet6_offloads[proto]);
 	if (likely(ops && ops->callbacks.gso_segment))
-- 
2.25.1


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

* [PATCH ipsec 3/3] net: Fix esp GSO on inter address family tunnels.
  2022-03-07 12:11 [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 1/3] esp: Fix possible buffer overflow in ESP transformation Steffen Klassert
  2022-03-07 12:11 ` [PATCH ipsec 2/3] esp: Fix BEET mode inter address family tunneling on GSO Steffen Klassert
@ 2022-03-07 12:11 ` Steffen Klassert
  2022-03-08  7:00 ` [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
  3 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2022-03-07 12:11 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert

The esp tunnel GSO handlers use skb_mac_gso_segment to
push the inner packet to the segmentation handlers.
However, skb_mac_gso_segment takes the Ethernet Protocol
ID from 'skb->protocol' which is wrong for inter address
family tunnels. We fix this by introducing a new
skb_eth_gso_segment function.

This function can be used if it is necessary to pass the
Ethernet Protocol ID directly to the segmentation handler.
First users of this function will be the esp4 and esp6
tunnel segmentation handlers.

Fixes: c35fe4106b92 ("xfrm: Add mode handlers for IPsec on layer 2")
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/linux/netdevice.h |  2 ++
 net/core/gro.c            | 25 +++++++++++++++++++++++++
 net/ipv4/esp4_offload.c   |  3 +--
 net/ipv6/esp6_offload.c   |  3 +--
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e490b84732d1..b1e59ccbb8e7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4602,6 +4602,8 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
 
 struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 				  netdev_features_t features, bool tx_path);
+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
+				    netdev_features_t features, __be16 type);
 struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
 				    netdev_features_t features);
 
diff --git a/net/core/gro.c b/net/core/gro.c
index a11b286d1495..b7d2b0dc59a2 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -92,6 +92,31 @@ void dev_remove_offload(struct packet_offload *po)
 }
 EXPORT_SYMBOL(dev_remove_offload);
 
+/**
+ *	skb_eth_gso_segment - segmentation handler for ethernet protocols.
+ *	@skb: buffer to segment
+ *	@features: features for the output path (see dev->features)
+ *	@type: Ethernet Protocol ID
+ */
+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
+				    netdev_features_t features, __be16 type)
+{
+	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+	struct packet_offload *ptype;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(ptype, &offload_base, list) {
+		if (ptype->type == type && ptype->callbacks.gso_segment) {
+			segs = ptype->callbacks.gso_segment(skb, features);
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return segs;
+}
+EXPORT_SYMBOL(skb_eth_gso_segment);
+
 /**
  *	skb_mac_gso_segment - mac layer segmentation handler.
  *	@skb: buffer to segment
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index 146d4d54830c..935026f4c807 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -110,8 +110,7 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
 						struct sk_buff *skb,
 						netdev_features_t features)
 {
-	__skb_push(skb, skb->mac_len);
-	return skb_mac_gso_segment(skb, features);
+	return skb_eth_gso_segment(skb, features, htons(ETH_P_IP));
 }
 
 static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index e61172d50817..3a293838a91d 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -145,8 +145,7 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
 						struct sk_buff *skb,
 						netdev_features_t features)
 {
-	__skb_push(skb, skb->mac_len);
-	return skb_mac_gso_segment(skb, features);
+	return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6));
 }
 
 static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
-- 
2.25.1


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

* Re: [PATCH ipsec 0/3] Fixes for the ipsec tree
  2022-03-07 12:11 [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
                   ` (2 preceding siblings ...)
  2022-03-07 12:11 ` [PATCH ipsec 3/3] net: Fix esp GSO on inter address family tunnels Steffen Klassert
@ 2022-03-08  7:00 ` Steffen Klassert
  3 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2022-03-08  7:00 UTC (permalink / raw)
  To: netdev

On Mon, Mar 07, 2022 at 01:11:38PM +0100, Steffen Klassert wrote:
> I plan to apply the following fixes to the ipsec tree:
> 
> 1) Fix possible buffer overflow in ESP output transformation.
> 
> 2) Fix BEET mode for ESP inter address family tunneling on GSO.
> 
> 3) Fix ESP GSO on inter address family tunnels.

This is now applied to thwe ipsec tree.

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

end of thread, other threads:[~2022-03-08  7:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-07 12:11 [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert
2022-03-07 12:11 ` [PATCH ipsec 1/3] esp: Fix possible buffer overflow in ESP transformation Steffen Klassert
2022-03-07 12:11 ` [PATCH ipsec 2/3] esp: Fix BEET mode inter address family tunneling on GSO Steffen Klassert
2022-03-07 12:11 ` [PATCH ipsec 3/3] net: Fix esp GSO on inter address family tunnels Steffen Klassert
2022-03-08  7:00 ` [PATCH ipsec 0/3] Fixes for the ipsec tree Steffen Klassert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).