futex: Fix the write access fault problem for real
commit434f5f9696e76352c4e23b3fa99881e87149da66
authorThomas Gleixner <tglx@linutronix.de>
Thu, 2 Jul 2009 16:59:39 +0000 (2 18:59 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 20 Jul 2009 03:38:50 +0000 (19 20:38 -0700)
tree2f4ea2fa63164994ac269c84f6477f1d7bdbc947
parent934ad5062c7ae18dde894f828037cd04daae5a63
futex: Fix the write access fault problem for real

commit d0725992c8a6fb63a16bc9e8b2a50094cc4db3cd and aa715284b4d28cabde6c25c568d769a6be712bc8 upstream

commit 64d1304a64 (futex: setup writeable mapping for futex ops which
modify user space data) did address only half of the problem of write
access faults.

The patch was made on two wrong assumptions:

1) access_ok(VERIFY_WRITE,...) would actually check write access.

   On x86 it does _NOT_. It's a pure address range check.

2) a RW mapped region can not go away under us.

   That's wrong as well. Nobody can prevent another thread to call
   mprotect(PROT_READ) on that region where the futex resides. If that
   call hits between the get_user_pages_fast() verification and the
   actual write access in the atomic region we are toast again.

The solution is to not rely on access_ok and get_user() for any write
access related fault on private and shared futexes. Instead we need to
fault it in with verification of write access.

There is no generic non destructive write mechanism which would fault
the user page in trough a #PF, but as we already know that we will
fault we can as well call get_user_pages() directly and avoid the #PF
overhead.

If get_user_pages() returns -EFAULT we know that we can not fix it
anymore and need to bail out to user space.

Remove a bunch of confusing comments on this issue as well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
kernel/futex.c