]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.17/futex-futex_find_get_task-remove-credentails-check.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.17 / futex-futex_find_get_task-remove-credentails-check.patch
CommitLineData
66966263
GKH
1From 7a0ea09ad5352efce8fe79ed853150449903b9f5 Mon Sep 17 00:00:00 2001
2From: Michal Hocko <mhocko@suse.cz>
3Date: Wed, 30 Jun 2010 09:51:19 +0200
4Subject: futex: futex_find_get_task remove credentails check
5
6From: Michal Hocko <mhocko@suse.cz>
7
8commit 7a0ea09ad5352efce8fe79ed853150449903b9f5 upstream.
9
10futex_find_get_task is currently used (through lookup_pi_state) from two
11contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
12looks it needs the credentials check, though. Different (e)uids
13shouldn't matter at all because the only thing that is important for
14shared futex is the accessibility of the shared memory.
15
16The credentail check results in glibc assert failure or process hang (if
17glibc is compiled without assert support) for shared robust pthread
18mutex with priority inheritance if a process tries to lock already held
19lock owned by a process with a different euid:
20
21pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
22
23The problem is that futex_lock_pi_atomic which is called when we try to
24lock already held lock checks the current holder (tid is stored in the
25futex value) to get the PI state. It uses lookup_pi_state which in turn
26gets task struct from futex_find_get_task. ESRCH is returned either
27when the task is not found or if credentials check fails.
28
29futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
30however, doesn't expect that robust lock returns with ESRCH because it
31should get either success or owner died.
32
33Signed-off-by: Michal Hocko <mhocko@suse.cz>
34Acked-by: Darren Hart <dvhltc@us.ibm.com>
35Cc: Ingo Molnar <mingo@elte.hu>
36Cc: Thomas Gleixner <tglx@linutronix.de>
37Cc: Nick Piggin <npiggin@suse.de>
38Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
39Cc: Peter Zijlstra <peterz@infradead.org>
40Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
41Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
42
43---
44 kernel/futex.c | 17 ++++-------------
45 1 file changed, 4 insertions(+), 13 deletions(-)
46
47--- a/kernel/futex.c
48+++ b/kernel/futex.c
49@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_p
50 static struct task_struct * futex_find_get_task(pid_t pid)
51 {
52 struct task_struct *p;
53- const struct cred *cred = current_cred(), *pcred;
54
55 rcu_read_lock();
56 p = find_task_by_vpid(pid);
57- if (!p) {
58- p = ERR_PTR(-ESRCH);
59- } else {
60- pcred = __task_cred(p);
61- if (cred->euid != pcred->euid &&
62- cred->euid != pcred->uid)
63- p = ERR_PTR(-ESRCH);
64- else
65- get_task_struct(p);
66- }
67+ if (p)
68+ get_task_struct(p);
69
70 rcu_read_unlock();
71
72@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_h
73 if (!pid)
74 return -ESRCH;
75 p = futex_find_get_task(pid);
76- if (IS_ERR(p))
77- return PTR_ERR(p);
78+ if (!p)
79+ return -ESRCH;
80
81 /*
82 * We need to look at the task state flags to figure out,