Blob Blame History Raw
From 106df426732fc582d1a1bcd6b823b5f16a08b933 Mon Sep 17 00:00:00 2001
From: "C. Erastus Toe" <ctoe@redhat.com>
Date: Tue, 24 May 2022 09:59:53 -0400
Subject: [KPATCH CVE-2022-27666] kpatch fixes for CVE-2022-27666
Content-type: text/plain

Kernels:
4.18.0-372.9.1.el8

Changes since last build:
arches: x86_64 ppc64le
esp4.o: changed function: esp_output_head
esp6.o: changed function: esp6_output_head
---------------------------

Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/49
Approved-by: Joe Lawrence (@joe.lawrence)
Modifications: none

commit 3217bc60aaf7f21f0704da5989de7bdd01a69742
Author: Sabrina Dubroca <sdubroca@redhat.com>
Date:   Wed May 11 11:44:45 2022 +0200

    esp: Fix possible buffer overflow in ESP transformation

    Bugzilla: https://bugzilla.redhat.com/2062114
    CVE: CVE-2022-27666
    Y-Commit: 72c973454384f9f432ca5ba5ebaa778e471050bd

    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2062115
    Tested: reproducer + basic ipsec tests
    O-CVE: CVE-2022-27666

    commit ebe48d368e97d007bfeb76fcb065d6cfc4c96645
    Author: Steffen Klassert <steffen.klassert@secunet.com>
    Date:   Mon Mar 7 13:11:39 2022 +0100

        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>

    Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com>
    Signed-off-by: Augusto Caringi <acaringi@redhat.com>

commit 3525e8a7ea460ac64682bce8889212830dfe371a
Author: Sabrina Dubroca <sdubroca@redhat.com>
Date:   Wed May 11 11:44:56 2022 +0200

    esp: limit skb_page_frag_refill use to a single page

    Bugzilla: https://bugzilla.redhat.com/2062114
    CVE: CVE-2022-27666
    Y-Commit: a1efd3ffe608ccbe9be08a691a939360f2c7c362

    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2062115
    Tested: reproducer + basic ipsec tests
    O-CVE: CVE-2022-27666

    commit 5bd8baab087dff657e05387aee802e70304cc813
    Author: Sabrina Dubroca <sd@queasysnail.net>
    Date:   Wed Apr 13 10:10:50 2022 +0200

        esp: limit skb_page_frag_refill use to a single page

        Commit ebe48d368e97 ("esp: Fix possible buffer overflow in ESP
        transformation") tried to fix skb_page_frag_refill usage in ESP by
        capping allocsize to 32k, but that doesn't completely solve the issue,
        as skb_page_frag_refill may return a single page. If that happens, we
        will write out of bounds, despite the check introduced in the previous
        patch.

        This patch forces COW in cases where we would end up calling
        skb_page_frag_refill with a size larger than a page (first in
        esp_output_head with tailen, then in esp_output_tail with
        skb->data_len).

        Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
        Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
        Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
        Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

    Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com>
    Signed-off-by: Augusto Caringi <acaringi@redhat.com>

Signed-off-by: C. Erastus Toe <ctoe@redhat.com>
---
 net/ipv4/esp4.c | 4 ++++
 net/ipv6/esp6.c | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index e86d59f9a6ea..af0eaa4e6c2b 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -453,6 +453,10 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
 			return err;
 	}
 
+	if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
+	    ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
+		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 5e19455e14f3..2ff1a109f464 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -500,6 +500,10 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
 			return err;
 	}
 
+	if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
+	    ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
+		goto cow;
+
 	if (!skb_cloned(skb)) {
 		if (tailen <= skb_tailroom(skb)) {
 			nfrags = 1;
-- 
2.26.3