71 lines
2.3 KiB
Diff
71 lines
2.3 KiB
Diff
From 7ab02af428c2d312c0cf8fb0b01cc1eb21131a3d Mon Sep 17 00:00:00 2001
|
|
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Date: Tue, 2 Feb 2010 12:37:44 -0800
|
|
Subject: [PATCH] Fix 'flush_old_exec()/setup_new_exec()' split
|
|
|
|
Commit 221af7f87b9 ("Split 'flush_old_exec' into two functions") split
|
|
the function at the point of no return - ie right where there were no
|
|
more error cases to check. That made sense from a technical standpoint,
|
|
but when we then also combined it with the actual personality setting
|
|
going in between flush_old_exec() and setup_new_exec(), it needs to be a
|
|
bit more careful.
|
|
|
|
In particular, we need to make sure that we really flush the old
|
|
personality bits in the 'flush' stage, rather than later in the 'setup'
|
|
stage, since otherwise we might be flushing the _new_ personality state
|
|
that we're just setting up.
|
|
|
|
So this moves the flags and personality flushing (and 'flush_thread()',
|
|
which is the arch-specific function that generally resets lazy FP state
|
|
etc) of the old process into flush_old_exec(), so that it doesn't affect
|
|
any state that execve() is setting up for the new process environment.
|
|
|
|
This was reported by Michal Simek as breaking his Microblaze qemu
|
|
environment.
|
|
|
|
Reported-and-tested-by: Michal Simek <michal.simek@petalogix.com>
|
|
Cc: Peter Anvin <hpa@zytor.com>
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
---
|
|
fs/exec.c | 10 +++++-----
|
|
1 files changed, 5 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/fs/exec.c b/fs/exec.c
|
|
index 675c3f4..0790a10 100644
|
|
--- a/fs/exec.c
|
|
+++ b/fs/exec.c
|
|
@@ -961,6 +961,11 @@ int flush_old_exec(struct linux_binprm * bprm)
|
|
goto out;
|
|
|
|
bprm->mm = NULL; /* We're using it now */
|
|
+
|
|
+ current->flags &= ~PF_RANDOMIZE;
|
|
+ flush_thread();
|
|
+ current->personality &= ~bprm->per_clear;
|
|
+
|
|
return 0;
|
|
|
|
out:
|
|
@@ -997,9 +1002,6 @@ void setup_new_exec(struct linux_binprm * bprm)
|
|
tcomm[i] = '\0';
|
|
set_task_comm(current, tcomm);
|
|
|
|
- current->flags &= ~PF_RANDOMIZE;
|
|
- flush_thread();
|
|
-
|
|
/* Set the new mm task size. We have to do that late because it may
|
|
* depend on TIF_32BIT which is only updated in flush_thread() on
|
|
* some architectures like powerpc
|
|
@@ -1015,8 +1017,6 @@ void setup_new_exec(struct linux_binprm * bprm)
|
|
set_dumpable(current->mm, suid_dumpable);
|
|
}
|
|
|
|
- current->personality &= ~bprm->per_clear;
|
|
-
|
|
/*
|
|
* Flush performance counters when crossing a
|
|
* security domain:
|
|
--
|
|
1.6.6
|
|
|