public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* Cherry-pick request to fix CVE-2022-0886 in v5.10 and v5.4
@ 2022-03-22  1:49 Vaibhav Rustagi
  2022-03-22  8:02 ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Vaibhav Rustagi @ 2022-03-22  1:49 UTC (permalink / raw)
  To: Greg KH; +Cc: # 3.4.x, steffen.klassert

[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

Hi Greg,

To fix CVE-2022-0886 in v5.10 and v5.4, we need to cherry-pick the
commit "esp: Fix possible buffer overflow in ESP transformation"
(ebe48d368e97d007bfeb76fcb065d6cfc4c96645). The commit didn't apply
cleanly in v5.10 and v5.4 and therefore, patches for both the kernel
versions are attached.

In order to backport the original commit, following changes are done:

 - v5.10:
    - "SKB_FRAG_PAGE_ORDER" declaration is moved from
"net/core/sock.c" to "include/net/sock.c"

 - v5.4:
    - "SKB_FRAG_PAGE_ORDER" declaration is moved from
"net/core/sock.c" to "include/net/sock.c"
    - Ignore changes introduced due to `xfrm: add support for UDPv6
encapsulation of ESP` in esp6_output_head()

Can you help in cherry-picking the commit to above stable branches?

Thanks,
Vaibhav

[-- Attachment #2: 5-4-esp-Fix-possible-buffer-overflow-in-ESP-transformati.patch --]
[-- Type: application/octet-stream, Size: 3788 bytes --]

From 33c40493a6b79866065afe041818e424f8bbf264 Mon Sep 17 00:00:00 2001
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Mon, 7 Mar 2022 13:11:39 +0100
Subject: [PATCH] esp: Fix possible buffer overflow in ESP transformation

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.

For having the patch build on v5.4, following changes are done:
 - `SKB_FRAG_PAGE_ORDER` declaration is moved from net/core/sock.c to include/net/sock.c.
 - Remove changes introduced due to `xfrm: add support for UDPv6 encapsulation of ESP` in esp6_output_head

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>
Signed-off-by: Vaibhav Rustagi <vaibhavrustagi@google.com>
---
 include/net/esp.h  | 2 ++
 include/net/sock.h | 3 +++
 net/core/sock.c    | 2 --
 net/ipv4/esp4.c    | 5 +++++
 net/ipv6/esp6.c    | 5 +++++
 5 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/include/net/esp.h b/include/net/esp.h
index 117652eb6ea3..465e38890ee9 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/include/net/sock.h b/include/net/sock.h
index 079b5f6f13d8..7f213cfcb3cc 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2583,6 +2583,9 @@ extern int sysctl_optmem_max;
 extern __u32 sysctl_wmem_default;
 extern __u32 sysctl_rmem_default;
 
+
+/* On 32bit arches, an skb frag is limited to 2^15 */
+#define SKB_FRAG_PAGE_ORDER	get_order(32768)
 DECLARE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
 
 static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
diff --git a/net/core/sock.c b/net/core/sock.c
index 57b7a10703c3..c84f68bff7f5 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2355,8 +2355,6 @@ static void sk_leave_memory_pressure(struct sock *sk)
 	}
 }
 
-/* On 32bit arches, an skb frag is limited to 2^15 */
-#define SKB_FRAG_PAGE_ORDER	get_order(32768)
 DEFINE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
 
 /**
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 00210e55b4cd..ef20f550d2f8 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -277,6 +277,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 UDP Encapsulation */
 	if (x->encap) {
@@ -286,6 +287,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 7a739f16d82b..79f117e33b80 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -230,6 +230,11 @@ 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;
+
+	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)) {
-- 
2.35.1.894.gb6a874cedc-goog


[-- Attachment #3: 5-10-esp-Fix-possible-buffer-overflow-in-ESP-transformati.patch --]
[-- Type: application/octet-stream, Size: 3806 bytes --]

From 862d44d130e14ba26ab69f28d3153b788f5b6f67 Mon Sep 17 00:00:00 2001
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Mon, 7 Mar 2022 13:11:39 +0100
Subject: [PATCH] esp: Fix possible buffer overflow in ESP transformation

[ Upstream commit ebe48d368e97d007bfeb76fcb065d6cfc4c96645 ]

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.

For having the patch build on v5.10, `SKB_FRAG_PAGE_ORDER` declaration
is moved from net/core/sock.c to include/net/sock.c.

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>
Signed-off-by: Vaibhav Rustagi <vaibhavrustagi@google.com>
---
 include/net/esp.h  | 2 ++
 include/net/sock.h | 1 +
 net/core/sock.c    | 1 -
 net/ipv4/esp4.c    | 5 +++++
 net/ipv6/esp6.c    | 5 +++++
 5 files changed, 13 insertions(+), 1 deletion(-)

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/include/net/sock.h b/include/net/sock.h
index bb40d4de545c..9426af15b1b8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2670,6 +2670,7 @@ extern int sysctl_optmem_max;
 extern __u32 sysctl_wmem_default;
 extern __u32 sysctl_rmem_default;
 
+#define SKB_FRAG_PAGE_ORDER     get_order(32768)
 DECLARE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
 
 static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
diff --git a/net/core/sock.c b/net/core/sock.c
index 6d9af4ef93d7..bee3c320dbfe 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2445,7 +2445,6 @@ static void sk_leave_memory_pressure(struct sock *sk)
 	}
 }
 
-#define SKB_FRAG_PAGE_ORDER	get_order(32768)
 DEFINE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
 
 /**
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 4b834bbf95e0..9aae82145bc1 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -448,6 +448,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) {
@@ -457,6 +458,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 fc8acb15dcfb..a28301a4cc8f 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -483,6 +483,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);
@@ -491,6 +492,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.35.1.894.gb6a874cedc-goog


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

end of thread, other threads:[~2022-03-24 14:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-22  1:49 Cherry-pick request to fix CVE-2022-0886 in v5.10 and v5.4 Vaibhav Rustagi
2022-03-22  8:02 ` Greg KH
2022-03-22 16:53   ` Vaibhav Rustagi
2022-03-22 20:42     ` Vaibhav Rustagi
2022-03-24 14:22       ` Greg KH
2022-03-23  7:01     ` Greg KH
2022-03-23 16:14       ` Vaibhav Rustagi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox