Blame SOURCES/CVE-2021-37576.patch

2228a1
From 742fee241938f6089d67c4e779ba0d608a9d88e3 Mon Sep 17 00:00:00 2001
2228a1
From: Joe Lawrence <joe.lawrence@redhat.com>
2228a1
Date: Mon, 30 Aug 2021 16:54:36 -0400
2228a1
Subject: [KPATCH CVE-2021-37576] powerpc: kpatch fixes for CVE-2021-37576
2228a1
2228a1
Kernels:
2228a1
4.18.0-305.el8
2228a1
4.18.0-305.3.1.el8_4
2228a1
4.18.0-305.7.1.el8_4
2228a1
4.18.0-305.10.2.el8_4
2228a1
4.18.0-305.12.1.el8_4
2228a1
2228a1
arches: ppc64le
2228a1
Changes since last build:
2228a1
[ppc64le]:
2228a1
book3s_rtas.o: changed function: kvmppc_rtas_hcall
2228a1
2228a1
---------------------------
2228a1
2228a1
Kernels:
2228a1
4.18.0-305.el8
2228a1
4.18.0-305.3.1.el8_4
2228a1
4.18.0-305.7.1.el8_4
2228a1
4.18.0-305.10.2.el8_4
2228a1
4.18.0-305.12.1.el8_4
2228a1
2228a1
Modifications: none
2228a1
Approved-by: Yannick Cote (@ycote1)
2228a1
Approved-by: Artem Savkov (@artem.savkov)
2228a1
KPATCH-MR: https://gitlab.com/kpatch-dev/rhel-8/-/merge_requests/2
2228a1
2228a1
KT0 test PASS: https://beaker.engineering.redhat.com/jobs/5756102
2228a1
for kpatch-patch-4_18_0-305-1-5.el8 scratch build:
2228a1
https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=39394966
2228a1
2228a1
commit 82faab596fc8f92648f20e2fbc4211557b115c13
2228a1
Author: Jon Maloy <jmaloy@redhat.com>
2228a1
Date:   Thu Aug 12 19:22:51 2021 -0400
2228a1
2228a1
    KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow
2228a1
2228a1
    Bugzilla: https://bugzilla.redhat.com/1988225
2228a1
    Upstream Status: Merged
2228a1
    Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=38936146
2228a1
    CVE: CVE-2021-37576
2228a1
2228a1
    commit f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a
2228a1
    Author: Nicholas Piggin <npiggin@gmail.com>
2228a1
    Date:   Tue Jul 20 20:43:09 2021 +1000
2228a1
2228a1
        KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow
2228a1
2228a1
        The kvmppc_rtas_hcall() sets the host rtas_args.rets pointer based on
2228a1
        the rtas_args.nargs that was provided by the guest. That guest nargs
2228a1
        value is not range checked, so the guest can cause the host rets pointer
2228a1
        to be pointed outside the args array. The individual rtas function
2228a1
        handlers check the nargs and nrets values to ensure they are correct,
2228a1
        but if they are not, the handlers store a -3 (0xfffffffd) failure
2228a1
        indication in rets[0] which corrupts host memory.
2228a1
2228a1
        Fix this by testing up front whether the guest supplied nargs and nret
2228a1
        would exceed the array size, and fail the hcall directly without storing
2228a1
        a failure indication to rets[0].
2228a1
2228a1
        Also expand on a comment about why we kill the guest and try not to
2228a1
        return errors directly if we have a valid rets[0] pointer.
2228a1
2228a1
        Fixes: 8e591cb72047 ("KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls")
2228a1
        Cc: stable@vger.kernel.org # v3.10+
2228a1
        Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2228a1
        Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
2228a1
        Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2228a1
2228a1
    Signed-off-by: Jon Maloy <jmaloy@redhat.com>
2228a1
2228a1
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2228a1
---
2228a1
 arch/powerpc/kvm/book3s_rtas.c | 25 ++++++++++++++++++++++---
2228a1
 1 file changed, 22 insertions(+), 3 deletions(-)
2228a1
2228a1
diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c
2228a1
index ceccacbf028e..52095f765e32 100644
2228a1
--- a/arch/powerpc/kvm/book3s_rtas.c
2228a1
+++ b/arch/powerpc/kvm/book3s_rtas.c
2228a1
@@ -245,6 +245,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
2228a1
 	 * value so we can restore it on the way out.
2228a1
 	 */
2228a1
 	orig_rets = args.rets;
2228a1
+	if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) {
2228a1
+		/*
2228a1
+		 * Don't overflow our args array: ensure there is room for
2228a1
+		 * at least rets[0] (even if the call specifies 0 nret).
2228a1
+		 *
2228a1
+		 * Each handler must then check for the correct nargs and nret
2228a1
+		 * values, but they may always return failure in rets[0].
2228a1
+		 */
2228a1
+		rc = -EINVAL;
2228a1
+		goto fail;
2228a1
+	}
2228a1
 	args.rets = &args.args[be32_to_cpu(args.nargs)];
2228a1
 
2228a1
 	mutex_lock(&vcpu->kvm->arch.rtas_token_lock);
2228a1
@@ -272,9 +283,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
2228a1
 fail:
2228a1
 	/*
2228a1
 	 * We only get here if the guest has called RTAS with a bogus
2228a1
-	 * args pointer. That means we can't get to the args, and so we
2228a1
-	 * can't fail the RTAS call. So fail right out to userspace,
2228a1
-	 * which should kill the guest.
2228a1
+	 * args pointer or nargs/nret values that would overflow the
2228a1
+	 * array. That means we can't get to the args, and so we can't
2228a1
+	 * fail the RTAS call. So fail right out to userspace, which
2228a1
+	 * should kill the guest.
2228a1
+	 *
2228a1
+	 * SLOF should actually pass the hcall return value from the
2228a1
+	 * rtas handler call in r3, so enter_rtas could be modified to
2228a1
+	 * return a failure indication in r3 and we could return such
2228a1
+	 * errors to the guest rather than failing to host userspace.
2228a1
+	 * However old guests that don't test for failure could then
2228a1
+	 * continue silently after errors, so for now we won't do this.
2228a1
 	 */
2228a1
 	return rc;
2228a1
 }
2228a1
-- 
2228a1
2.31.1
2228a1
2228a1