Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[pandora-kernel.git] / kernel / futex.c
index bda4157..fe28dc2 100644 (file)
@@ -782,8 +782,8 @@ static void __unqueue_futex(struct futex_q *q)
 {
        struct futex_hash_bucket *hb;
 
-       if (WARN_ON(!q->lock_ptr || !spin_is_locked(q->lock_ptr)
-                       || plist_node_empty(&q->list)))
+       if (WARN_ON_SMP(!q->lock_ptr || !spin_is_locked(q->lock_ptr))
+           || WARN_ON(plist_node_empty(&q->list)))
                return;
 
        hb = container_of(q->lock_ptr, struct futex_hash_bucket, lock);
@@ -1886,7 +1886,7 @@ retry:
        restart->futex.val = val;
        restart->futex.time = abs_time->tv64;
        restart->futex.bitset = bitset;
-       restart->futex.flags = flags;
+       restart->futex.flags = flags | FLAGS_HAS_TIMEOUT;
 
        ret = -ERESTART_RESTARTBLOCK;
 
@@ -2418,10 +2418,19 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
                        goto err_unlock;
                ret = -EPERM;
                pcred = __task_cred(p);
+               /* If victim is in different user_ns, then uids are not
+                  comparable, so we must have CAP_SYS_PTRACE */
+               if (cred->user->user_ns != pcred->user->user_ns) {
+                       if (!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
+                               goto err_unlock;
+                       goto ok;
+               }
+               /* If victim is in same user_ns, then uids are comparable */
                if (cred->euid != pcred->euid &&
                    cred->euid != pcred->uid &&
-                   !capable(CAP_SYS_PTRACE))
+                   !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
                        goto err_unlock;
+ok:
                head = p->robust_list;
                rcu_read_unlock();
        }