Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.33-rc6-git6 /kernel/futex.c

Filename:/kernel/futex.c
Lines Added:27
Lines Deleted:3
Also changed in: (Previous) 2.6.33-rc6-git5  2.6.33-rc6  2.6.33-rc5  2.6.33-rc4-git7  2.6.33-rc4-git6  2.6.33-rc4-git5 
(Following) 2.6.33-rc7  2.6.33-rc8  2.6.33 

Location
[  2.6.33-rc6-git6
  [  kernel
     o  futex.c

Patch

diff --git a/kernel/futex.c b/kernel/futex.c
index d9b3a22..e7a35f1 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -530,8 +530,25 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
             return -EINVAL;
 
          WARN_ON(!atomic_read(&pi_state->refcount));
-         WARN_ON(pid && pi_state->owner &&
-            pi_state->owner->pid != pid);
+
+         /*
+          * When pi_state->owner is NULL then the owner died
+          * and another waiter is on the fly. pi_state->owner
+          * is fixed up by the task which acquires
+          * pi_state->rt_mutex.
+          *
+          * We do not check for pid == 0 which can happen when
+          * the owner died and robust_list_exit() cleared the
+          * TID.
+          */
+         if (pid && pi_state->owner) {
+            /*
+             * Bail out if user space manipulated the
+             * futex value.
+             */
+            if (pid != task_pid_vnr(pi_state->owner))
+               return -EINVAL;
+         }
 
          atomic_inc(&pi_state->refcount);
          *ps = pi_state;
@@ -758,6 +775,13 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
    if (!pi_state)
       return -EINVAL;
 
+   /*
+    * If current does not own the pi_state then the futex is
+    * inconsistent and user space fiddled with the futex value.
+    */
+   if (pi_state->owner != current)
+      return -EINVAL;
+
    raw_spin_lock(&pi_state->pi_mutex.wait_lock);
    new_owner = rt_mutex_next_owner(&pi_state->pi_mutex);
 
@@ -1971,7 +1995,7 @@ retry_private:
    /* Unqueue and drop the lock */
    unqueue_me_pi(&q);
 
-   goto out;
+   goto out_put_key;
 
 out_unlock_put_key:
    queue_unlock(&q, hb);


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.