[arm64] KVM: Tighten guest core register access from userspace (CVE-2018-18021)

This commit is contained in:
Salvatore Bonaccorso 2018-10-07 08:29:33 +02:00
parent 10190f3972
commit 20bad055e2
3 changed files with 105 additions and 0 deletions

5
debian/changelog vendored
View File

@ -1,7 +1,12 @@
linux (4.18.10-2) UNRELEASED; urgency=medium
[ Ben Hutchings ]
* [rt][arm64,armhf] Fix build failure after rebasing onto 4.18.10
[ Salvatore Bonaccorso ]
* [arm64] KVM: Tighten guest core register access from userspace
(CVE-2018-18021)
-- Ben Hutchings <ben@decadent.org.uk> Fri, 05 Oct 2018 18:09:26 +0100
linux (4.18.10-1) unstable; urgency=medium

View File

@ -0,0 +1,99 @@
From: Dave Martin <Dave.Martin@arm.com>
Date: Thu, 27 Sep 2018 16:53:21 +0100
Subject: arm64: KVM: Tighten guest core register access from userspace
Origin: https://git.kernel.org/linus/d26c25a9d19b5976b319af528886f89cf455692d
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-18021
We currently allow userspace to access the core register file
in about any possible way, including straddling multiple
registers and doing unaligned accesses.
This is not the expected use of the ABI, and nobody is actually
using it that way. Let's tighten it by explicitly checking
the size and alignment for each field of the register file.
Cc: <stable@vger.kernel.org>
Fixes: 2f4a07c5f9fe ("arm64: KVM: guest one-reg interface")
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
[maz: rewrote Dave's initial patch to be more easily backported]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kvm/guest.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 07256b08226c..3088463bafc1 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -57,6 +57,45 @@ static u64 core_reg_offset_from_id(u64 id)
return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
}
+static int validate_core_offset(const struct kvm_one_reg *reg)
+{
+ u64 off = core_reg_offset_from_id(reg->id);
+ int size;
+
+ switch (off) {
+ case KVM_REG_ARM_CORE_REG(regs.regs[0]) ...
+ KVM_REG_ARM_CORE_REG(regs.regs[30]):
+ case KVM_REG_ARM_CORE_REG(regs.sp):
+ case KVM_REG_ARM_CORE_REG(regs.pc):
+ case KVM_REG_ARM_CORE_REG(regs.pstate):
+ case KVM_REG_ARM_CORE_REG(sp_el1):
+ case KVM_REG_ARM_CORE_REG(elr_el1):
+ case KVM_REG_ARM_CORE_REG(spsr[0]) ...
+ KVM_REG_ARM_CORE_REG(spsr[KVM_NR_SPSR - 1]):
+ size = sizeof(__u64);
+ break;
+
+ case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ...
+ KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]):
+ size = sizeof(__uint128_t);
+ break;
+
+ case KVM_REG_ARM_CORE_REG(fp_regs.fpsr):
+ case KVM_REG_ARM_CORE_REG(fp_regs.fpcr):
+ size = sizeof(__u32);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (KVM_REG_SIZE(reg->id) == size &&
+ IS_ALIGNED(off, size / sizeof(__u32)))
+ return 0;
+
+ return -EINVAL;
+}
+
static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
{
/*
@@ -76,6 +115,9 @@ static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
(off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
return -ENOENT;
+ if (validate_core_offset(reg))
+ return -EINVAL;
+
if (copy_to_user(uaddr, ((u32 *)regs) + off, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -98,6 +140,9 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
(off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
return -ENOENT;
+ if (validate_core_offset(reg))
+ return -EINVAL;
+
if (KVM_REG_SIZE(reg->id) > sizeof(tmp))
return -EINVAL;
--
2.11.0

View File

@ -145,6 +145,7 @@ bugfix/all/Revert-net-increase-fragment-memory-usage-limits.patch
bugfix/all/floppy-Do-not-copy-a-kernel-pointer-to-user-memory-i.patch
bugfix/all/scsi-target-iscsi-Use-hex2bin-instead-of-a-re-implem.patch
bugfix/all/scsi-target-iscsi-Use-bin2hex-instead-of-a-re-implem.patch
bugfix/arm64/arm64-kvm-tighten-guest-core-register-access-from-us.patch
# Fix exported symbol versions
bugfix/all/module-disable-matching-missing-version-crc.patch