|
|
8045f6 |
From 9ab861c9a630d07a8ac0240f81dd0067b6c57963 Mon Sep 17 00:00:00 2001
|
|
|
8045f6 |
From: Joel Savitz <jsavitz@redhat.com>
|
|
|
8045f6 |
Date: Mon, 20 Sep 2021 13:49:09 -0400
|
|
|
8045f6 |
Subject: [KPATCH CVE-2021-37576] KVM: PPC: kpatch fixes for CVE-2021-37576
|
|
|
8045f6 |
|
|
|
8045f6 |
Kernels:
|
|
|
8045f6 |
3.10.0-1160.el7
|
|
|
8045f6 |
3.10.0-1160.2.1.el7
|
|
|
8045f6 |
3.10.0-1160.2.2.el7
|
|
|
8045f6 |
3.10.0-1160.6.1.el7
|
|
|
8045f6 |
3.10.0-1160.11.1.el7
|
|
|
8045f6 |
3.10.0-1160.15.2.el7
|
|
|
8045f6 |
3.10.0-1160.21.1.el7
|
|
|
8045f6 |
3.10.0-1160.24.1.el7
|
|
|
8045f6 |
3.10.0-1160.25.1.el7
|
|
|
8045f6 |
3.10.0-1160.31.1.el7
|
|
|
8045f6 |
3.10.0-1160.36.2.el7
|
|
|
8045f6 |
3.10.0-1160.41.1.el7
|
|
|
8045f6 |
3.10.0-1160.42.2.el7
|
|
|
8045f6 |
|
|
|
8045f6 |
Changes since last build:
|
|
|
8045f6 |
arches: ppc64le
|
|
|
8045f6 |
book3s_rtas.o: changed function: kvmppc_rtas_hcall
|
|
|
8045f6 |
---------------------------
|
|
|
8045f6 |
|
|
|
8045f6 |
Kernels:
|
|
|
8045f6 |
3.10.0-1160.2.1.el7
|
|
|
8045f6 |
3.10.0-1160.2.2.el7
|
|
|
8045f6 |
3.10.0-1160.6.1.el7
|
|
|
8045f6 |
3.10.0-1160.11.1.el7
|
|
|
8045f6 |
3.10.0-1160.15.2.el7
|
|
|
8045f6 |
3.10.0-1160.21.1.el7
|
|
|
8045f6 |
3.10.0-1160.24.1.el7
|
|
|
8045f6 |
3.10.0-1160.25.1.el7
|
|
|
8045f6 |
3.10.0-1160.31.1.el7
|
|
|
8045f6 |
3.10.0-1160.36.2.el7
|
|
|
8045f6 |
3.10.0-1160.41.1.el7
|
|
|
8045f6 |
3.10.0-1160.42.2.el7
|
|
|
8045f6 |
|
|
|
8045f6 |
Modifications: None
|
|
|
8045f6 |
Kpatch-MR: https://gitlab.com/kpatch-dev/rhel-7/-/merge_requests/8
|
|
|
8045f6 |
Approved-by: Artem Savkov (@artem.savkov)
|
|
|
8045f6 |
Approved-by: Joe Lawrence (@joe.lawrence)
|
|
|
8045f6 |
Approved-by: Yannick Cote (@ycote1)
|
|
|
8045f6 |
|
|
|
8045f6 |
Z-MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-7/-/merge_requests/274
|
|
|
8045f6 |
|
|
|
8045f6 |
No reproducer available, tested via manual install and:
|
|
|
8045f6 |
KT0 test PASS (ppc64le only): https://beaker.engineering.redhat.com/jobs/5809981
|
|
|
8045f6 |
|
|
|
8045f6 |
for scratch build: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=39840849
|
|
|
8045f6 |
|
|
|
8045f6 |
commit e1b729d6d332cc22fe641edc723324222096bf29
|
|
|
8045f6 |
Author: Jon Maloy <jmaloy@redhat.com>
|
|
|
8045f6 |
Date: Thu Aug 12 19:22:51 2021 -0400
|
|
|
8045f6 |
|
|
|
8045f6 |
KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow
|
|
|
8045f6 |
|
|
|
8045f6 |
Bugzilla: https://bugzilla.redhat.com/1988218
|
|
|
8045f6 |
Upstream Status: Merged
|
|
|
8045f6 |
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=39246436
|
|
|
8045f6 |
CVE: CVE-2021-37576
|
|
|
8045f6 |
|
|
|
8045f6 |
commit f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a
|
|
|
8045f6 |
Author: Nicholas Piggin <npiggin@gmail.com>
|
|
|
8045f6 |
Date: Tue Jul 20 20:43:09 2021 +1000
|
|
|
8045f6 |
|
|
|
8045f6 |
KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow
|
|
|
8045f6 |
|
|
|
8045f6 |
The kvmppc_rtas_hcall() sets the host rtas_args.rets pointer based on
|
|
|
8045f6 |
the rtas_args.nargs that was provided by the guest. That guest nargs
|
|
|
8045f6 |
value is not range checked, so the guest can cause the host rets pointer
|
|
|
8045f6 |
to be pointed outside the args array. The individual rtas function
|
|
|
8045f6 |
handlers check the nargs and nrets values to ensure they are correct,
|
|
|
8045f6 |
but if they are not, the handlers store a -3 (0xfffffffd) failure
|
|
|
8045f6 |
indication in rets[0] which corrupts host memory.
|
|
|
8045f6 |
|
|
|
8045f6 |
Fix this by testing up front whether the guest supplied nargs and nret
|
|
|
8045f6 |
would exceed the array size, and fail the hcall directly without storing
|
|
|
8045f6 |
a failure indication to rets[0].
|
|
|
8045f6 |
|
|
|
8045f6 |
Also expand on a comment about why we kill the guest and try not to
|
|
|
8045f6 |
return errors directly if we have a valid rets[0] pointer.
|
|
|
8045f6 |
|
|
|
8045f6 |
Fixes: 8e591cb72047 ("KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls")
|
|
|
8045f6 |
Cc: stable@vger.kernel.org # v3.10+
|
|
|
8045f6 |
Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
|
|
|
8045f6 |
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
|
|
|
8045f6 |
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
|
|
|
8045f6 |
|
|
|
8045f6 |
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
|
|
8045f6 |
|
|
|
8045f6 |
Signed-off-by: Joel Savitz <jsavitz@redhat.com>
|
|
|
8045f6 |
---
|
|
|
8045f6 |
arch/powerpc/kvm/book3s_rtas.c | 25 ++++++++++++++++++++++---
|
|
|
8045f6 |
1 file changed, 22 insertions(+), 3 deletions(-)
|
|
|
8045f6 |
|
|
|
8045f6 |
diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c
|
|
|
8045f6 |
index ef27fbd5d9c5..d896c6854abc 100644
|
|
|
8045f6 |
--- a/arch/powerpc/kvm/book3s_rtas.c
|
|
|
8045f6 |
+++ b/arch/powerpc/kvm/book3s_rtas.c
|
|
|
8045f6 |
@@ -230,6 +230,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
|
|
|
8045f6 |
* value so we can restore it on the way out.
|
|
|
8045f6 |
*/
|
|
|
8045f6 |
orig_rets = args.rets;
|
|
|
8045f6 |
+ if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) {
|
|
|
8045f6 |
+ /*
|
|
|
8045f6 |
+ * Don't overflow our args array: ensure there is room for
|
|
|
8045f6 |
+ * at least rets[0] (even if the call specifies 0 nret).
|
|
|
8045f6 |
+ *
|
|
|
8045f6 |
+ * Each handler must then check for the correct nargs and nret
|
|
|
8045f6 |
+ * values, but they may always return failure in rets[0].
|
|
|
8045f6 |
+ */
|
|
|
8045f6 |
+ rc = -EINVAL;
|
|
|
8045f6 |
+ goto fail;
|
|
|
8045f6 |
+ }
|
|
|
8045f6 |
args.rets = &args.args[be32_to_cpu(args.nargs)];
|
|
|
8045f6 |
|
|
|
8045f6 |
mutex_lock(&vcpu->kvm->lock);
|
|
|
8045f6 |
@@ -257,9 +268,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
|
|
|
8045f6 |
fail:
|
|
|
8045f6 |
/*
|
|
|
8045f6 |
* We only get here if the guest has called RTAS with a bogus
|
|
|
8045f6 |
- * args pointer. That means we can't get to the args, and so we
|
|
|
8045f6 |
- * can't fail the RTAS call. So fail right out to userspace,
|
|
|
8045f6 |
- * which should kill the guest.
|
|
|
8045f6 |
+ * args pointer or nargs/nret values that would overflow the
|
|
|
8045f6 |
+ * array. That means we can't get to the args, and so we can't
|
|
|
8045f6 |
+ * fail the RTAS call. So fail right out to userspace, which
|
|
|
8045f6 |
+ * should kill the guest.
|
|
|
8045f6 |
+ *
|
|
|
8045f6 |
+ * SLOF should actually pass the hcall return value from the
|
|
|
8045f6 |
+ * rtas handler call in r3, so enter_rtas could be modified to
|
|
|
8045f6 |
+ * return a failure indication in r3 and we could return such
|
|
|
8045f6 |
+ * errors to the guest rather than failing to host userspace.
|
|
|
8045f6 |
+ * However old guests that don't test for failure could then
|
|
|
8045f6 |
+ * continue silently after errors, so for now we won't do this.
|
|
|
8045f6 |
*/
|
|
|
8045f6 |
return rc;
|
|
|
8045f6 |
}
|
|
|
8045f6 |
--
|
|
|
8045f6 |
2.26.3
|
|
|
8045f6 |
|
|
|
8045f6 |
|