summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin M. Forbes <jforbes@fedoraproject.org>2018-10-03 07:55:07 -0500
committerJustin M. Forbes <jforbes@fedoraproject.org>2018-10-03 07:55:07 -0500
commitd115630b5280fce16946a2ce2c0f6f97b049b28a (patch)
tree2e44caf6aa7845e0601b86c1222c36ffc508d3fc
parent772dbde03433f2dfe434bd92a5040dafeb0be632 (diff)
downloadkernel-d115630b5280fce16946a2ce2c0f6f97b049b28a.tar.gz
kernel-d115630b5280fce16946a2ce2c0f6f97b049b28a.tar.xz
kernel-d115630b5280fce16946a2ce2c0f6f97b049b28a.zip
Fix arm64 kvm priv escalation (rhbz 1635475 1635476)
-rw-r--r--arm64_kvm_security.patch155
-rw-r--r--kernel.spec6
2 files changed, 161 insertions, 0 deletions
diff --git a/arm64_kvm_security.patch b/arm64_kvm_security.patch
new file mode 100644
index 000000000..71490d969
--- /dev/null
+++ b/arm64_kvm_security.patch
@@ -0,0 +1,155 @@
+From d26c25a9d19b5976b319af528886f89cf455692d Mon Sep 17 00:00:00 2001
+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
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit d26c25a9d19b5976b319af528886f89cf455692d upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kvm/guest.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+--- a/arch/arm64/kvm/guest.c
++++ b/arch/arm64/kvm/guest.c
+@@ -57,6 +57,45 @@ static u64 core_reg_offset_from_id(u64 i
+ 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
+ (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
+ (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;
+
+From 2a3f93459d689d990b3ecfbe782fec89b97d3279 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Thu, 27 Sep 2018 16:53:22 +0100
+Subject: arm64: KVM: Sanitize PSTATE.M when being set from userspace
+
+From: Marc Zyngier <marc.zyngier@arm.com>
+
+commit 2a3f93459d689d990b3ecfbe782fec89b97d3279 upstream.
+
+Not all execution modes are valid for a guest, and some of them
+depend on what the HW actually supports. Let's verify that what
+userspace provides is compatible with both the VM settings and
+the HW capabilities.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 0d854a60b1d7 ("arm64: KVM: enable initialization of a 32bit vcpu")
+Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
+Reviewed-by: Mark Rutland <mark.rutland@arm.com>
+Reviewed-by: Dave Martin <Dave.Martin@arm.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kvm/guest.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/guest.c
++++ b/arch/arm64/kvm/guest.c
+@@ -152,17 +152,25 @@ static int set_core_reg(struct kvm_vcpu
+ }
+
+ if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
+- u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
++ u64 mode = (*(u64 *)valp) & COMPAT_PSR_MODE_MASK;
+ switch (mode) {
+ case COMPAT_PSR_MODE_USR:
++ if (!system_supports_32bit_el0())
++ return -EINVAL;
++ break;
+ case COMPAT_PSR_MODE_FIQ:
+ case COMPAT_PSR_MODE_IRQ:
+ case COMPAT_PSR_MODE_SVC:
+ case COMPAT_PSR_MODE_ABT:
+ case COMPAT_PSR_MODE_UND:
++ if (!vcpu_el1_is_32bit(vcpu))
++ return -EINVAL;
++ break;
+ case PSR_MODE_EL0t:
+ case PSR_MODE_EL1t:
+ case PSR_MODE_EL1h:
++ if (vcpu_el1_is_32bit(vcpu))
++ return -EINVAL;
+ break;
+ default:
+ err = -EINVAL;
diff --git a/kernel.spec b/kernel.spec
index 33db02530..fc08a1514 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -674,6 +674,9 @@ Patch536: powerpc-ipv6.patch
# rhbz 1634250
Patch537: HID-intel-ish-hid-Enable-Sunrise-Point-H-ish-driver.patch
+# rhbz 1635475 1635476
+Patch538: arm64_kvm_security.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1933,6 +1936,9 @@ fi
#
#
%changelog
+* Wed Oct 03 2018 Justin M. Forbes <jforbes@fedoraproject.org>
+- Fix arm64 kvm priv escalation (rhbz 1635475 1635476)
+
* Mon Oct 01 2018 Laura Abbott <labbott@redhat.com>
- Disable CONFIG_CRYPTO_DEV_SP_PSP (rhbz 1608242)