[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] CVE-2012-0028: Move "exit_robust_list" into mm_release(); nullify lists after cleanup



# HG changeset patch
# User Laszlo Ersek <lersek@xxxxxxxxxx>
# Date 1326102624 -3600
# Node ID b4e1b9ff189f3b04475a1d0118932316abf26e19
# Parent  821a5b2a10c86f18fbce0907af0db6905b9d540a
CVE-2012-0028: Move "exit_robust_list" into mm_release(); nullify lists after 
cleanup

This is a backport of upstream commits 8141c7f3 & fc6b177d:

    We don't want to get rid of the futexes just at exit() time, we want
    to drop them when doing an execve() too, since that gets rid of the
    previous VM image too.

    Doing it at mm_release() time means that we automatically always do it
    when we disassociate a VM map from the task.

    The robust list pointers of user space held futexes are kept intact
    over an exec() call. When the exec'ed task exits exit_robust_list() is
    called with the stale pointer. The risk of corruption is minimal, but
    still it is incorrect to keep the pointers valid. Actually glibc
    should uninstall the robust list before calling exec() but we have to
    deal with it anyway.

    Nullify the pointers after [compat_]exit_robust_list() has been
    called.

In Xen HVM guests on IA64, the stale robust_list pointer, inherited over
execve(), caused a fault that was spuriously resolved to a legacy MMIO
request with wrong size, forcing the qemu-dm process to exit.

322a2c10 is not squashed in this patch because the Priority Inheritance
state cleanup (exit_pi_state_list()) seems to be restricted to kernel
space.

Signed-off-by: Laszlo Ersek <lersek@xxxxxxxxxx>
Committed-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r 821a5b2a10c8 -r b4e1b9ff189f kernel/exit.c
--- a/kernel/exit.c     Thu Jan 05 10:21:22 2012 +0100
+++ b/kernel/exit.c     Mon Jan 09 10:50:24 2012 +0100
@@ -34,7 +34,6 @@
 #include <linux/cn_proc.h>
 #include <linux/mutex.h>
 #include <linux/futex.h>
-#include <linux/compat.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/audit.h> /* for audit_free() */
 #include <linux/resource.h>
@@ -898,12 +897,6 @@
                exit_itimers(tsk->signal);
        }
        acct_collect(code, group_dead);
-       if (unlikely(tsk->robust_list))
-               exit_robust_list(tsk);
-#if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
-       if (unlikely(tsk->compat_robust_list))
-               compat_exit_robust_list(tsk);
-#endif
        if (unlikely(tsk->audit_context))
                audit_free(tsk);
        taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
diff -r 821a5b2a10c8 -r b4e1b9ff189f kernel/fork.c
--- a/kernel/fork.c     Thu Jan 05 10:21:22 2012 +0100
+++ b/kernel/fork.c     Mon Jan 09 10:50:24 2012 +0100
@@ -35,6 +35,7 @@
 #include <linux/syscalls.h>
 #include <linux/jiffies.h>
 #include <linux/futex.h>
+#include <linux/compat.h>
 #include <linux/rcupdate.h>
 #include <linux/ptrace.h>
 #include <linux/mount.h>
@@ -434,6 +435,20 @@
 {
        struct completion *vfork_done = tsk->vfork_done;
 
+       /* Get rid of any futexes when releasing the mm */
+#ifdef CONFIG_FUTEX
+       if (unlikely(tsk->robust_list)) {
+               exit_robust_list(tsk);
+               tsk->robust_list = NULL;
+       }
+#ifdef CONFIG_COMPAT
+       if (unlikely(tsk->compat_robust_list)) {
+               compat_exit_robust_list(tsk);
+               tsk->compat_robust_list = NULL;
+       }
+#endif
+#endif
+
        /* Get rid of any cached register state */
        deactivate_mm(tsk, mm);
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.