* [PATCH] futex: futex_find_get_task remove credentails check
@ 2010-07-08 12:51 Michal Hocko
2010-07-08 13:22 ` Ingo Molnar
2010-07-28 23:57 ` [stable] " Greg KH
0 siblings, 2 replies; 11+ messages in thread
From: Michal Hocko @ 2010-07-08 12:51 UTC (permalink / raw)
To: stable; +Cc: Thomas Gleixner, Ingo Molnar, Darren Hart, LKML
Hi stable team,
could you consider including the following patch (Linus tree commit:
7a0ea09ad5352efce8fe79ed853150449903b9f5).
The original discussion which led to this commit can be found at
http://lkml.org/lkml/2010/6/23/52.
In short:
The original pi locking implementation (since it got to the kernel)
contains a credential check (in futex_find_get_task) if we want to
create a PI state for already held lock. This test fails if the lock
owner has a different (e)uid than the process for which we want to
create the state.
The lock operation then fails with ESRCH which is the error code
which is returned if the process holding a lock doesn't exist.
The userspace (glibc) doesn't expect this behavior for shared robust PI
futexes and fails with an assert or hang the task in the end-less loop.
The test case is attached in the referenced thread.
The credential test, which is removed by this patch, doesn't look
correct and it limits the functionality without any good reason. There
are no security consequences as well because the only thing that should
matter in the shared futex-es is accessibility to the shared memory.
The patch applies as is on top of Vanilla 2.6.32, but let me know if you
want to base it on top of the any of the stable trees.
---
>From 7a0ea09ad5352efce8fe79ed853150449903b9f5 Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.cz>
Date: Wed, 30 Jun 2010 09:51:19 +0200
Subject: [PATCH] futex: futex_find_get_task remove credentails check
futex_find_get_task is currently used (through lookup_pi_state) from two
contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
looks it needs the credentials check, though. Different (e)uids
shouldn't matter at all because the only thing that is important for
shared futex is the accessibility of the shared memory.
The credentail check results in glibc assert failure or process hang (if
glibc is compiled without assert support) for shared robust pthread
mutex with priority inheritance if a process tries to lock already held
lock owned by a process with a different euid:
pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
The problem is that futex_lock_pi_atomic which is called when we try to
lock already held lock checks the current holder (tid is stored in the
futex value) to get the PI state. It uses lookup_pi_state which in turn
gets task struct from futex_find_get_task. ESRCH is returned either
when the task is not found or if credentials check fails.
futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
however, doesn't expect that robust lock returns with ESRCH because it
should get either success or owner died.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Darren Hart <dvhltc@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
kernel/futex.c | 17 ++++-------------
1 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/kernel/futex.c b/kernel/futex.c
index e7a35f1..6a3a5fa 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
static struct task_struct * futex_find_get_task(pid_t pid)
{
struct task_struct *p;
- const struct cred *cred = current_cred(), *pcred;
rcu_read_lock();
p = find_task_by_vpid(pid);
- if (!p) {
- p = ERR_PTR(-ESRCH);
- } else {
- pcred = __task_cred(p);
- if (cred->euid != pcred->euid &&
- cred->euid != pcred->uid)
- p = ERR_PTR(-ESRCH);
- else
- get_task_struct(p);
- }
+ if (p)
+ get_task_struct(p);
rcu_read_unlock();
@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
if (!pid)
return -ESRCH;
p = futex_find_get_task(pid);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (!p)
+ return -ESRCH;
/*
* We need to look at the task state flags to figure out,
--
1.7.1
--
Michal Hocko
L3 team
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 12:51 [PATCH] futex: futex_find_get_task remove credentails check Michal Hocko
@ 2010-07-08 13:22 ` Ingo Molnar
2010-07-12 10:20 ` Thomas Gleixner
2010-07-28 23:57 ` [stable] " Greg KH
1 sibling, 1 reply; 11+ messages in thread
From: Ingo Molnar @ 2010-07-08 13:22 UTC (permalink / raw)
To: Michal Hocko; +Cc: stable, Thomas Gleixner, Darren Hart, LKML
* Michal Hocko <mhocko@suse.cz> wrote:
> Hi stable team,
> could you consider including the following patch (Linus tree commit:
> 7a0ea09ad5352efce8fe79ed853150449903b9f5).
Ack.
Ingo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 13:22 ` Ingo Molnar
@ 2010-07-12 10:20 ` Thomas Gleixner
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Gleixner @ 2010-07-12 10:20 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Michal Hocko, stable, Darren Hart, LKML
On Thu, 8 Jul 2010, Ingo Molnar wrote:
>
> * Michal Hocko <mhocko@suse.cz> wrote:
>
> > Hi stable team,
> > could you consider including the following patch (Linus tree commit:
> > 7a0ea09ad5352efce8fe79ed853150449903b9f5).
>
> Ack.
Ack
tglx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [stable] [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 12:51 [PATCH] futex: futex_find_get_task remove credentails check Michal Hocko
2010-07-08 13:22 ` Ingo Molnar
@ 2010-07-28 23:57 ` Greg KH
1 sibling, 0 replies; 11+ messages in thread
From: Greg KH @ 2010-07-28 23:57 UTC (permalink / raw)
To: Michal Hocko; +Cc: stable, Thomas Gleixner, Darren Hart, Ingo Molnar, LKML
On Thu, Jul 08, 2010 at 02:51:04PM +0200, Michal Hocko wrote:
> Hi stable team,
> could you consider including the following patch (Linus tree commit:
> 7a0ea09ad5352efce8fe79ed853150449903b9f5).
Now queued up.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 9:43 ` Peter Zijlstra
@ 2010-07-08 9:50 ` Michal Hocko
0 siblings, 0 replies; 11+ messages in thread
From: Michal Hocko @ 2010-07-08 9:50 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Darren Hart
On Thu 08-07-10 11:43:53, Peter Zijlstra wrote:
> On Thu, 2010-07-08 at 11:39 +0200, Michal Hocko wrote:
> > OK, so do you need an ACK from Thomas, or can you grab the patch and
> > push it through one of your trees?
> >
> Have a look at Linus' tree.
Ahh, you mean 7a0ea09ad5352efce8fe79ed853150449903b9f5. I didn't get any
email about the committing.
Thanks!
--
Michal Hocko
L3 team
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 9:39 ` Michal Hocko
@ 2010-07-08 9:43 ` Peter Zijlstra
2010-07-08 9:50 ` Michal Hocko
0 siblings, 1 reply; 11+ messages in thread
From: Peter Zijlstra @ 2010-07-08 9:43 UTC (permalink / raw)
To: Michal Hocko
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Darren Hart
On Thu, 2010-07-08 at 11:39 +0200, Michal Hocko wrote:
> OK, so do you need an ACK from Thomas, or can you grab the patch and
> push it through one of your trees?
>
Have a look at Linus' tree.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 9:32 ` Ingo Molnar
@ 2010-07-08 9:39 ` Michal Hocko
2010-07-08 9:43 ` Peter Zijlstra
0 siblings, 1 reply; 11+ messages in thread
From: Michal Hocko @ 2010-07-08 9:39 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Peter Zijlstra, Darren Hart
On Thu 08-07-10 11:32:41, Ingo Molnar wrote:
>
> * Michal Hocko <mhocko@suse.cz> wrote:
>
> > On Wed 30-06-10 09:43:27, Darren Hart wrote:
> > > On 06/30/2010 02:55 AM, Michal Hocko wrote:
> > > >On Wed 30-06-10 09:01:15, Michal Hocko wrote:
> > > >>On Tue 29-06-10 09:41:02, Linus Torvalds wrote:
> > > >>>On Tue, Jun 29, 2010 at 1:42 AM, Michal Hocko<mhocko@suse.cz> wrote:
> > > >>>>
> > > >>>>futex_find_get_task is currently used (through lookup_pi_state) from two
> > > >>>>contexts, futex_requeue and futex_lock_pi_atomic. While credentials check
> > > >>>>makes sense in the first code path, the second one is more problematic
> > > >>>>because this check requires that the PI lock holder (pid parameter) has
> > > >>>>the same uid and euid as the process's euid which is trying to lock the
> > > >>>>same futex (current).
> > > >>>
> > > >>>So exactly why does it make sense to check the credentials in the
> > > >>>first code path then?
> > > >>
> > > >>I though that requeue needs this for security reasons (don't let requeue
> > > >>process for other user), but when I thought about that again you are
> > > >>right and the only what matters should be accessibility of the shared
> > > >>memory.
> > > >
> > > >And here is the patch which does the thing.
> > > >
> > > >--
> > > >
> > > > From 082c5ad2c482a8e78b61b17e213e750b006176aa Mon Sep 17 00:00:00 2001
> > > >From: Michal Hocko<mhocko@suse.cz>
> > > >Date: Wed, 30 Jun 2010 09:51:19 +0200
> > > >Subject: [PATCH] futex: futex_find_get_task remove credentails check
> > > >
> > > >futex_find_get_task is currently used (through lookup_pi_state) from two
> > > >contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
> > > >looks it needs the credentials check, though. Different (e)uids
> > > >shouldn't matter at all because the only thing that is important for
> > > >shared futex is the accessibility of the shared memory.
> > > >
> > > >The credentail check results in glibc assert failure or process hang (if
> > > >glibc is compiled without assert support) for shared robust pthread
> > > >mutex with priority inheritance if a process tries to lock already held
> > > >lock owned by a process with a different euid:
> > > >
> > > >pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
> > > >
> > > >The problem is that futex_lock_pi_atomic which is called when we try to
> > > >lock already held lock checks the current holder (tid is stored in the
> > > >futex value) to get the PI state. It uses lookup_pi_state which in turn
> > > >gets task struct from futex_find_get_task. ESRCH is returned either when
> > > >the task is not found or if credentials check fails.
> > > >futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
> > > >however, doesn't expect that robust lock returns with ESRCH because it
> > > >should get either success or owner died.
> > > >
> > > >Signed-off-by: Michal Hocko<mhocko@suse.cz>
> > >
> > > Without hearing back from Ingo on the original intent of the
> > > credentials check, this looks right to me.
> >
> > Could you comment on that Ingo, please?
>
> I think that's more of a question to Thomas :-)
>
> My memories are hazy and nothing springs out as some credible original intent.
> So please assume it doesnt exist :-)
OK, so do you need an ACK from Thomas, or can you grab the patch and
push it through one of your trees?
>
> Ingo
--
Michal Hocko
L3 team
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-07-08 9:28 ` Michal Hocko
@ 2010-07-08 9:32 ` Ingo Molnar
2010-07-08 9:39 ` Michal Hocko
0 siblings, 1 reply; 11+ messages in thread
From: Ingo Molnar @ 2010-07-08 9:32 UTC (permalink / raw)
To: Michal Hocko
Cc: Linus Torvalds, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Peter Zijlstra, Darren Hart
* Michal Hocko <mhocko@suse.cz> wrote:
> On Wed 30-06-10 09:43:27, Darren Hart wrote:
> > On 06/30/2010 02:55 AM, Michal Hocko wrote:
> > >On Wed 30-06-10 09:01:15, Michal Hocko wrote:
> > >>On Tue 29-06-10 09:41:02, Linus Torvalds wrote:
> > >>>On Tue, Jun 29, 2010 at 1:42 AM, Michal Hocko<mhocko@suse.cz> wrote:
> > >>>>
> > >>>>futex_find_get_task is currently used (through lookup_pi_state) from two
> > >>>>contexts, futex_requeue and futex_lock_pi_atomic. While credentials check
> > >>>>makes sense in the first code path, the second one is more problematic
> > >>>>because this check requires that the PI lock holder (pid parameter) has
> > >>>>the same uid and euid as the process's euid which is trying to lock the
> > >>>>same futex (current).
> > >>>
> > >>>So exactly why does it make sense to check the credentials in the
> > >>>first code path then?
> > >>
> > >>I though that requeue needs this for security reasons (don't let requeue
> > >>process for other user), but when I thought about that again you are
> > >>right and the only what matters should be accessibility of the shared
> > >>memory.
> > >
> > >And here is the patch which does the thing.
> > >
> > >--
> > >
> > > From 082c5ad2c482a8e78b61b17e213e750b006176aa Mon Sep 17 00:00:00 2001
> > >From: Michal Hocko<mhocko@suse.cz>
> > >Date: Wed, 30 Jun 2010 09:51:19 +0200
> > >Subject: [PATCH] futex: futex_find_get_task remove credentails check
> > >
> > >futex_find_get_task is currently used (through lookup_pi_state) from two
> > >contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
> > >looks it needs the credentials check, though. Different (e)uids
> > >shouldn't matter at all because the only thing that is important for
> > >shared futex is the accessibility of the shared memory.
> > >
> > >The credentail check results in glibc assert failure or process hang (if
> > >glibc is compiled without assert support) for shared robust pthread
> > >mutex with priority inheritance if a process tries to lock already held
> > >lock owned by a process with a different euid:
> > >
> > >pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
> > >
> > >The problem is that futex_lock_pi_atomic which is called when we try to
> > >lock already held lock checks the current holder (tid is stored in the
> > >futex value) to get the PI state. It uses lookup_pi_state which in turn
> > >gets task struct from futex_find_get_task. ESRCH is returned either when
> > >the task is not found or if credentials check fails.
> > >futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
> > >however, doesn't expect that robust lock returns with ESRCH because it
> > >should get either success or owner died.
> > >
> > >Signed-off-by: Michal Hocko<mhocko@suse.cz>
> >
> > Without hearing back from Ingo on the original intent of the
> > credentials check, this looks right to me.
>
> Could you comment on that Ingo, please?
I think that's more of a question to Thomas :-)
My memories are hazy and nothing springs out as some credible original intent.
So please assume it doesnt exist :-)
Ingo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-06-30 16:43 ` Darren Hart
@ 2010-07-08 9:28 ` Michal Hocko
2010-07-08 9:32 ` Ingo Molnar
0 siblings, 1 reply; 11+ messages in thread
From: Michal Hocko @ 2010-07-08 9:28 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Ingo Molnar, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Peter Zijlstra, Darren Hart
On Wed 30-06-10 09:43:27, Darren Hart wrote:
> On 06/30/2010 02:55 AM, Michal Hocko wrote:
> >On Wed 30-06-10 09:01:15, Michal Hocko wrote:
> >>On Tue 29-06-10 09:41:02, Linus Torvalds wrote:
> >>>On Tue, Jun 29, 2010 at 1:42 AM, Michal Hocko<mhocko@suse.cz> wrote:
> >>>>
> >>>>futex_find_get_task is currently used (through lookup_pi_state) from two
> >>>>contexts, futex_requeue and futex_lock_pi_atomic. While credentials check
> >>>>makes sense in the first code path, the second one is more problematic
> >>>>because this check requires that the PI lock holder (pid parameter) has
> >>>>the same uid and euid as the process's euid which is trying to lock the
> >>>>same futex (current).
> >>>
> >>>So exactly why does it make sense to check the credentials in the
> >>>first code path then?
> >>
> >>I though that requeue needs this for security reasons (don't let requeue
> >>process for other user), but when I thought about that again you are
> >>right and the only what matters should be accessibility of the shared
> >>memory.
> >
> >And here is the patch which does the thing.
> >
> >--
> >
> > From 082c5ad2c482a8e78b61b17e213e750b006176aa Mon Sep 17 00:00:00 2001
> >From: Michal Hocko<mhocko@suse.cz>
> >Date: Wed, 30 Jun 2010 09:51:19 +0200
> >Subject: [PATCH] futex: futex_find_get_task remove credentails check
> >
> >futex_find_get_task is currently used (through lookup_pi_state) from two
> >contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
> >looks it needs the credentials check, though. Different (e)uids
> >shouldn't matter at all because the only thing that is important for
> >shared futex is the accessibility of the shared memory.
> >
> >The credentail check results in glibc assert failure or process hang (if
> >glibc is compiled without assert support) for shared robust pthread
> >mutex with priority inheritance if a process tries to lock already held
> >lock owned by a process with a different euid:
> >
> >pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
> >
> >The problem is that futex_lock_pi_atomic which is called when we try to
> >lock already held lock checks the current holder (tid is stored in the
> >futex value) to get the PI state. It uses lookup_pi_state which in turn
> >gets task struct from futex_find_get_task. ESRCH is returned either when
> >the task is not found or if credentials check fails.
> >futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
> >however, doesn't expect that robust lock returns with ESRCH because it
> >should get either success or owner died.
> >
> >Signed-off-by: Michal Hocko<mhocko@suse.cz>
>
> Without hearing back from Ingo on the original intent of the
> credentials check, this looks right to me.
Could you comment on that Ingo, please?
>
> Acked-by: Darren Hart <dvhltc@us.ibm.com>
>
>
> >---
> > kernel/futex.c | 17 ++++-------------
> > 1 files changed, 4 insertions(+), 13 deletions(-)
> >
> >diff --git a/kernel/futex.c b/kernel/futex.c
> >index e7a35f1..6a3a5fa 100644
> >--- a/kernel/futex.c
> >+++ b/kernel/futex.c
> >@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
> > static struct task_struct * futex_find_get_task(pid_t pid)
> > {
> > struct task_struct *p;
> >- const struct cred *cred = current_cred(), *pcred;
> >
> > rcu_read_lock();
> > p = find_task_by_vpid(pid);
> >- if (!p) {
> >- p = ERR_PTR(-ESRCH);
> >- } else {
> >- pcred = __task_cred(p);
> >- if (cred->euid != pcred->euid&&
> >- cred->euid != pcred->uid)
> >- p = ERR_PTR(-ESRCH);
> >- else
> >- get_task_struct(p);
> >- }
> >+ if (p)
> >+ get_task_struct(p);
> >
> > rcu_read_unlock();
> >
> >@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
> > if (!pid)
> > return -ESRCH;
> > p = futex_find_get_task(pid);
> >- if (IS_ERR(p))
> >- return PTR_ERR(p);
> >+ if (!p)
> >+ return -ESRCH;
> >
> > /*
> > * We need to look at the task state flags to figure out,
>
>
> --
> Darren Hart
> IBM Linux Technology Center
> Real-Time Linux Team
--
Michal Hocko
L3 team
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] futex: futex_find_get_task remove credentails check
2010-06-30 9:55 ` [PATCH] futex: futex_find_get_task remove credentails check Michal Hocko
@ 2010-06-30 16:43 ` Darren Hart
2010-07-08 9:28 ` Michal Hocko
0 siblings, 1 reply; 11+ messages in thread
From: Darren Hart @ 2010-06-30 16:43 UTC (permalink / raw)
To: Michal Hocko
Cc: Linus Torvalds, Ingo Molnar, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Peter Zijlstra
On 06/30/2010 02:55 AM, Michal Hocko wrote:
> On Wed 30-06-10 09:01:15, Michal Hocko wrote:
>> On Tue 29-06-10 09:41:02, Linus Torvalds wrote:
>>> On Tue, Jun 29, 2010 at 1:42 AM, Michal Hocko<mhocko@suse.cz> wrote:
>>>>
>>>> futex_find_get_task is currently used (through lookup_pi_state) from two
>>>> contexts, futex_requeue and futex_lock_pi_atomic. While credentials check
>>>> makes sense in the first code path, the second one is more problematic
>>>> because this check requires that the PI lock holder (pid parameter) has
>>>> the same uid and euid as the process's euid which is trying to lock the
>>>> same futex (current).
>>>
>>> So exactly why does it make sense to check the credentials in the
>>> first code path then?
>>
>> I though that requeue needs this for security reasons (don't let requeue
>> process for other user), but when I thought about that again you are
>> right and the only what matters should be accessibility of the shared
>> memory.
>
> And here is the patch which does the thing.
>
> --
>
> From 082c5ad2c482a8e78b61b17e213e750b006176aa Mon Sep 17 00:00:00 2001
> From: Michal Hocko<mhocko@suse.cz>
> Date: Wed, 30 Jun 2010 09:51:19 +0200
> Subject: [PATCH] futex: futex_find_get_task remove credentails check
>
> futex_find_get_task is currently used (through lookup_pi_state) from two
> contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
> looks it needs the credentials check, though. Different (e)uids
> shouldn't matter at all because the only thing that is important for
> shared futex is the accessibility of the shared memory.
>
> The credentail check results in glibc assert failure or process hang (if
> glibc is compiled without assert support) for shared robust pthread
> mutex with priority inheritance if a process tries to lock already held
> lock owned by a process with a different euid:
>
> pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
>
> The problem is that futex_lock_pi_atomic which is called when we try to
> lock already held lock checks the current holder (tid is stored in the
> futex value) to get the PI state. It uses lookup_pi_state which in turn
> gets task struct from futex_find_get_task. ESRCH is returned either when
> the task is not found or if credentials check fails.
> futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
> however, doesn't expect that robust lock returns with ESRCH because it
> should get either success or owner died.
>
> Signed-off-by: Michal Hocko<mhocko@suse.cz>
Without hearing back from Ingo on the original intent of the credentials
check, this looks right to me.
Acked-by: Darren Hart <dvhltc@us.ibm.com>
> ---
> kernel/futex.c | 17 ++++-------------
> 1 files changed, 4 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/futex.c b/kernel/futex.c
> index e7a35f1..6a3a5fa 100644
> --- a/kernel/futex.c
> +++ b/kernel/futex.c
> @@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
> static struct task_struct * futex_find_get_task(pid_t pid)
> {
> struct task_struct *p;
> - const struct cred *cred = current_cred(), *pcred;
>
> rcu_read_lock();
> p = find_task_by_vpid(pid);
> - if (!p) {
> - p = ERR_PTR(-ESRCH);
> - } else {
> - pcred = __task_cred(p);
> - if (cred->euid != pcred->euid&&
> - cred->euid != pcred->uid)
> - p = ERR_PTR(-ESRCH);
> - else
> - get_task_struct(p);
> - }
> + if (p)
> + get_task_struct(p);
>
> rcu_read_unlock();
>
> @@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
> if (!pid)
> return -ESRCH;
> p = futex_find_get_task(pid);
> - if (IS_ERR(p))
> - return PTR_ERR(p);
> + if (!p)
> + return -ESRCH;
>
> /*
> * We need to look at the task state flags to figure out,
--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] futex: futex_find_get_task remove credentails check
2010-06-30 7:01 ` Michal Hocko
@ 2010-06-30 9:55 ` Michal Hocko
2010-06-30 16:43 ` Darren Hart
0 siblings, 1 reply; 11+ messages in thread
From: Michal Hocko @ 2010-06-30 9:55 UTC (permalink / raw)
To: Linus Torvalds
Cc: Ingo Molnar, Darren Hart, Thomas Gleixner, LKML, Nick Piggin,
Alexey Kuznetsov, Peter Zijlstra
On Wed 30-06-10 09:01:15, Michal Hocko wrote:
> On Tue 29-06-10 09:41:02, Linus Torvalds wrote:
> > On Tue, Jun 29, 2010 at 1:42 AM, Michal Hocko <mhocko@suse.cz> wrote:
> > >
> > > futex_find_get_task is currently used (through lookup_pi_state) from two
> > > contexts, futex_requeue and futex_lock_pi_atomic. While credentials check
> > > makes sense in the first code path, the second one is more problematic
> > > because this check requires that the PI lock holder (pid parameter) has
> > > the same uid and euid as the process's euid which is trying to lock the
> > > same futex (current).
> >
> > So exactly why does it make sense to check the credentials in the
> > first code path then?
>
> I though that requeue needs this for security reasons (don't let requeue
> process for other user), but when I thought about that again you are
> right and the only what matters should be accessibility of the shared
> memory.
And here is the patch which does the thing.
--
>From 082c5ad2c482a8e78b61b17e213e750b006176aa Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.cz>
Date: Wed, 30 Jun 2010 09:51:19 +0200
Subject: [PATCH] futex: futex_find_get_task remove credentails check
futex_find_get_task is currently used (through lookup_pi_state) from two
contexts, futex_requeue and futex_lock_pi_atomic. None of the paths
looks it needs the credentials check, though. Different (e)uids
shouldn't matter at all because the only thing that is important for
shared futex is the accessibility of the shared memory.
The credentail check results in glibc assert failure or process hang (if
glibc is compiled without assert support) for shared robust pthread
mutex with priority inheritance if a process tries to lock already held
lock owned by a process with a different euid:
pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
The problem is that futex_lock_pi_atomic which is called when we try to
lock already held lock checks the current holder (tid is stored in the
futex value) to get the PI state. It uses lookup_pi_state which in turn
gets task struct from futex_find_get_task. ESRCH is returned either when
the task is not found or if credentials check fails.
futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code,
however, doesn't expect that robust lock returns with ESRCH because it
should get either success or owner died.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
---
kernel/futex.c | 17 ++++-------------
1 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/kernel/futex.c b/kernel/futex.c
index e7a35f1..6a3a5fa 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
static struct task_struct * futex_find_get_task(pid_t pid)
{
struct task_struct *p;
- const struct cred *cred = current_cred(), *pcred;
rcu_read_lock();
p = find_task_by_vpid(pid);
- if (!p) {
- p = ERR_PTR(-ESRCH);
- } else {
- pcred = __task_cred(p);
- if (cred->euid != pcred->euid &&
- cred->euid != pcred->uid)
- p = ERR_PTR(-ESRCH);
- else
- get_task_struct(p);
- }
+ if (p)
+ get_task_struct(p);
rcu_read_unlock();
@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
if (!pid)
return -ESRCH;
p = futex_find_get_task(pid);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (!p)
+ return -ESRCH;
/*
* We need to look at the task state flags to figure out,
--
1.7.1
--
Michal Hocko
L3 team
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-07-29 0:16 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-08 12:51 [PATCH] futex: futex_find_get_task remove credentails check Michal Hocko
2010-07-08 13:22 ` Ingo Molnar
2010-07-12 10:20 ` Thomas Gleixner
2010-07-28 23:57 ` [stable] " Greg KH
-- strict thread matches above, loose matches on Subject: below --
2010-06-25 17:53 futex: race in lock and unlock&exit for robust futex with PI? Darren Hart
2010-06-25 23:35 ` Darren Hart
2010-06-28 14:42 ` Michal Hocko
2010-06-28 15:32 ` Michal Hocko
2010-06-28 15:58 ` Michal Hocko
2010-06-28 16:39 ` Michal Hocko
2010-06-28 16:49 ` Peter Zijlstra
2010-06-29 8:42 ` [PATCH] futex: futex_find_get_task make credentials check conditional Michal Hocko
2010-06-29 16:41 ` Linus Torvalds
2010-06-30 7:01 ` Michal Hocko
2010-06-30 9:55 ` [PATCH] futex: futex_find_get_task remove credentails check Michal Hocko
2010-06-30 16:43 ` Darren Hart
2010-07-08 9:28 ` Michal Hocko
2010-07-08 9:32 ` Ingo Molnar
2010-07-08 9:39 ` Michal Hocko
2010-07-08 9:43 ` Peter Zijlstra
2010-07-08 9:50 ` Michal Hocko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome