Commit-ID: fc6b177dee33365ccb29fe6d2092223cf8d679f9
Gitweb: http://git.kernel.org/tip/fc6b177dee33365ccb29fe6d2092223cf8d679f9
Author: Peter Zijlstra <[email protected]>
AuthorDate: Mon, 5 Oct 2009 18:17:32 +0200
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 6 Oct 2009 17:00:01 +0200
futex: Nullify robust lists after cleanup
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.
Reported-by: Anirban Sinha <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
LKML-Reference: <new-submission>
Cc: [email protected]
---
kernel/fork.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index bfee931..88ef51c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -543,11 +543,15 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
/* Get rid of any futexes when releasing the mm */
#ifdef CONFIG_FUTEX
- if (unlikely(tsk->robust_list))
+ if (unlikely(tsk->robust_list)) {
exit_robust_list(tsk);
+ tsk->robust_list = NULL;
+ }
#ifdef CONFIG_COMPAT
- if (unlikely(tsk->compat_robust_list))
+ if (unlikely(tsk->compat_robust_list)) {
compat_exit_robust_list(tsk);
+ tsk->compat_robust_list = NULL;
+ }
#endif
#endif
Once upon a time, like on 09-10-06 8:03 AM, tip-bot for Peter Zijlstra wrote:
> futex: Nullify robust lists after cleanup
>
> 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.
>
> Reported-by: Anirban Sinha <[email protected]>
> Signed-off-by: Peter Zijlstra <[email protected]>
> Signed-off-by: Thomas Gleixner <[email protected]>
> LKML-Reference: <new-submission>
> Cc: [email protected]
Excellent! I very much like the solution because:
(a) it reiterates the fact that an execve() call is indeed logically the
'death' of a process.
'(b) cleans up state that should not logically propagate across an execve() call.
(c) Does not introduce new EWOULDBLOCK semantics that can potentially break user
land.
(d) Restores the 'robust' behavior of futexes by waking up other processes
waiting on it on an exec() call.
(e) handles potentially broken/buggy applications gracefully.
(f) as far as I can see, the world would be better and no worse with this patch :)
I'll let you guys know if something else strikes my eyes as being odd in the
course of my digging through the code.
Ani