The patch below does not apply to the 5.10-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ebe48d368e97d007bfeb76fcb065d6cfc4c96645 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.
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
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;
From: Steffen Klassert steffen.klassert@secunet.com
Plese apply this on 5.10.y stable as well as it fixes the following syzbot issues:
LINK: https://syzkaller.appspot.com/bug?id=517fa734b92b7db404c409b924cf5c997640e32... LINK: https://syzkaller.appspot.com/bug?id=57375340ab81a369df5da5eb16cfcd4aef9dfb9...
Here is a working patch. ---8<---
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.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible") Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible") Reported-by: valis sec@valis.email Reported-by: syzbot+93ab2623dcb5c73eda9f@syzkaller.appspotmail.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org --- include/net/esp.h | 2 ++ include/net/sock.h | 1 + net/ipv4/esp4.c | 5 +++++ net/ipv6/esp6.c | 5 +++++ 4 files changed, 13 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/include/net/sock.h b/include/net/sock.h index d50823df426c..865e0ff20a81 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2688,6 +2688,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/ipv4/esp4.c b/net/ipv4/esp4.c index 61dfb64e7256..b23b2bedca7a 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 cb708fbb1c17..ffcc30484c8d 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;
On Thu, Mar 17, 2022 at 09:41:59AM -0700, Tadeusz Struk wrote:
From: Steffen Klassert steffen.klassert@secunet.com
Plese apply this on 5.10.y stable as well as it fixes the following syzbot issues:
LINK: https://syzkaller.appspot.com/bug?id=517fa734b92b7db404c409b924cf5c997640e32... LINK: https://syzkaller.appspot.com/bug?id=57375340ab81a369df5da5eb16cfcd4aef9dfb9...
Here is a working patch. ---8<---
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.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible") Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible") Reported-by: valis sec@valis.email Reported-by: syzbot+93ab2623dcb5c73eda9f@syzkaller.appspotmail.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org
include/net/esp.h | 2 ++ include/net/sock.h | 1 + net/ipv4/esp4.c | 5 +++++ net/ipv6/esp6.c | 5 +++++ 4 files changed, 13 insertions(+)
What is the git commit id of this commit in Linus's tree?
thanks,
greg k-h
On 3/17/22 09:56, Greg KH wrote:
On Thu, Mar 17, 2022 at 09:41:59AM -0700, Tadeusz Struk wrote:
From: Steffen Klassert steffen.klassert@secunet.com
Plese apply this on 5.10.y stable as well as it fixes the following syzbot issues:
LINK: https://syzkaller.appspot.com/bug?id=517fa734b92b7db404c409b924cf5c997640e32... LINK: https://syzkaller.appspot.com/bug?id=57375340ab81a369df5da5eb16cfcd4aef9dfb9...
Here is a working patch. ---8<---
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.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible") Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible") Reported-by: valis sec@valis.email Reported-by: syzbot+93ab2623dcb5c73eda9f@syzkaller.appspotmail.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org
include/net/esp.h | 2 ++ include/net/sock.h | 1 + net/ipv4/esp4.c | 5 +++++ net/ipv6/esp6.c | 5 +++++ 4 files changed, 13 insertions(+)
What is the git commit id of this commit in Linus's tree?
It's this one:
ebe48d368e97 ("esp: Fix possible buffer overflow in ESP transformation")
Sorry I forgot to include it in the backport.
On Thu, Mar 17, 2022 at 10:09:52AM -0700, Tadeusz Struk wrote:
On 3/17/22 09:56, Greg KH wrote:
On Thu, Mar 17, 2022 at 09:41:59AM -0700, Tadeusz Struk wrote:
From: Steffen Klassert steffen.klassert@secunet.com
Plese apply this on 5.10.y stable as well as it fixes the following syzbot issues:
LINK: https://syzkaller.appspot.com/bug?id=517fa734b92b7db404c409b924cf5c997640e32... LINK: https://syzkaller.appspot.com/bug?id=57375340ab81a369df5da5eb16cfcd4aef9dfb9...
Here is a working patch. ---8<---
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.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible") Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible") Reported-by: valis sec@valis.email Reported-by: syzbot+93ab2623dcb5c73eda9f@syzkaller.appspotmail.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org
include/net/esp.h | 2 ++ include/net/sock.h | 1 + net/ipv4/esp4.c | 5 +++++ net/ipv6/esp6.c | 5 +++++ 4 files changed, 13 insertions(+)
What is the git commit id of this commit in Linus's tree?
It's this one:
ebe48d368e97 ("esp: Fix possible buffer overflow in ESP transformation")
Sorry I forgot to include it in the backport.
Now queued up, thanks.
gre gk-h
linux-stable-mirror@lists.linaro.org