]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Fix use after free during shutdown
authorPekka Enberg <penberg@kernel.org>
Tue, 3 Jan 2012 17:20:23 +0000 (19:20 +0200)
committerPekka Enberg <penberg@kernel.org>
Tue, 3 Jan 2012 17:21:32 +0000 (19:21 +0200)
Valgrind reports the following use after free error, when shutting down a
guest:

  [penberg@tux kvm]$ valgrind ./vm run

  [ snipĀ ]

  Mounting...
  Starting '/bin/sh'...
  sh-4.2# exit

  [ snipĀ ]

  ==4726== Thread 11:
  ==4726== Invalid read of size 8
  ==4726==    at 0x407818: kvm__continue (kvm.c:518)
  ==4726==    by 0x3DE683534F: ??? (in /lib64/libc-2.14.so)
  ==4726==    by 0x3DE68D8AF6: ioctl (in /lib64/libc-2.14.so)
  ==4726==    by 0x406C95: kvm_cpu__run (kvm-cpu.c:35)
  ==4726==    by 0x406D95: kvm_cpu__start (kvm-cpu.c:109)
  ==4726==    by 0x4046D5: kvm_cpu_thread (builtin-run.c:603)
  ==4726==    by 0x3DE7007B30: start_thread (in /lib64/libpthread-2.14.so)
  ==4726==    by 0x3DE68DFD2C: clone (in /lib64/libc-2.14.so)
  ==4726==  Address 0x4c2e040 is 0 bytes inside a block of size 936 free'd
  ==4726==    at 0x4A055FE: free (vg_replace_malloc.c:366)
  ==4726==    by 0x4046E7: kvm_cpu_thread (builtin-run.c:606)
  ==4726==    by 0x3DE7007B30: start_thread (in /lib64/libpthread-2.14.so)
  ==4726==    by 0x3DE68DFD2C: clone (in /lib64/libc-2.14.so)
  ==4726==
  ==4726== Thread 1:
  ==4726== Invalid read of size 1
  ==4726==    at 0x4057BC: kvm_cmd_run (builtin-run.c:1182)
  ==4726==    by 0x40D46D: handle_command (kvm-cmd.c:84)
  ==4726==    by 0x3DE682139C: (below main) (in /lib64/libc-2.14.so)
  ==4726==  Address 0x4e36f58 is 920 bytes inside a block of size 936 free'd
  ==4726==    at 0x4A055FE: free (vg_replace_malloc.c:366)
  ==4726==    by 0x4046E7: kvm_cpu_thread (builtin-run.c:606)
  ==4726==    by 0x3DE7007B30: start_thread (in /lib64/libpthread-2.14.so)
  ==4726==    by 0x3DE68DFD2C: clone (in /lib64/libc-2.14.so)

This patch fixes the problem by moving the kvm_cpu__delete() call from
kvm_cpu_thread() to kvm_cmd_run() after we've made sure the VCPU thread is
stopped.

Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/builtin-run.c

index 27daf0fea8586ec34a12f70126381e0ba70386ab..adfbbbf6ea4e74bec823d3f3e53ea3e84b1a245f 100644 (file)
@@ -603,8 +603,6 @@ static void *kvm_cpu_thread(void *arg)
        if (kvm_cpu__start(current_kvm_cpu))
                goto panic_kvm;
 
-       kvm_cpu__delete(current_kvm_cpu);
-
        return (void *) (intptr_t) 0;
 
 panic_kvm:
@@ -620,8 +618,6 @@ panic_kvm:
        kvm_cpu__show_code(current_kvm_cpu);
        kvm_cpu__show_page_tables(current_kvm_cpu);
 
-       kvm_cpu__delete(current_kvm_cpu);
-
        return (void *) (intptr_t) 1;
 }
 
@@ -1178,11 +1174,14 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
        if (pthread_join(kvm_cpus[0]->thread, &ret) != 0)
                exit_code = 1;
 
+       kvm_cpu__delete(kvm_cpus[0]);
+
        for (i = 1; i < nrcpus; i++) {
                if (kvm_cpus[i]->is_running) {
                        pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT);
                        if (pthread_join(kvm_cpus[i]->thread, &ret) != 0)
                                die("pthread_join");
+                       kvm_cpu__delete(kvm_cpus[i]);
                }
                if (ret != NULL)
                        exit_code = 1;