git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
netns xfrm: fix "ip xfrm state|policy count" misreport
[safe/jmp/linux-2.6]
/
kernel
/
futex_compat.c
diff --git
a/kernel/futex_compat.c
b/kernel/futex_compat.c
index
cc098e1
..
2357165
100644
(file)
--- a/
kernel/futex_compat.c
+++ b/
kernel/futex_compat.c
@@
-30,6
+30,15
@@
fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
return 0;
}
return 0;
}
+static void __user *futex_uaddr(struct robust_list __user *entry,
+ compat_long_t futex_offset)
+{
+ compat_uptr_t base = ptr_to_compat(entry);
+ void __user *uaddr = compat_ptr(base + futex_offset);
+
+ return uaddr;
+}
+
/*
* Walk curr->robust_list (very carefully, it's a userspace list!)
* and mark any locks found there dead, and notify any waiters.
/*
* Walk curr->robust_list (very carefully, it's a userspace list!)
* and mark any locks found there dead, and notify any waiters.
@@
-45,6
+54,9
@@
void compat_exit_robust_list(struct task_struct *curr)
compat_long_t futex_offset;
int rc;
compat_long_t futex_offset;
int rc;
+ if (!futex_cmpxchg_enabled)
+ return;
+
/*
* Fetch the list head (which was registered earlier, via
* sys_set_robust_list()):
/*
* Fetch the list head (which was registered earlier, via
* sys_set_robust_list()):
@@
-76,11
+88,12
@@
void compat_exit_robust_list(struct task_struct *curr)
* A pending lock might already be on the list, so
* dont process it twice:
*/
* A pending lock might already be on the list, so
* dont process it twice:
*/
- if (entry != pending)
- if (handle_futex_death((void __user *)entry + futex_offset,
- curr, pi))
- return;
+ if (entry != pending) {
+ void __user *uaddr = futex_uaddr(entry, futex_offset);
+ if (handle_futex_death(uaddr, curr, pi))
+ return;
+ }
if (rc)
return;
uentry = next_uentry;
if (rc)
return;
uentry = next_uentry;
@@
-94,15
+107,20
@@
void compat_exit_robust_list(struct task_struct *curr)
cond_resched();
}
cond_resched();
}
- if (pending)
- handle_futex_death((void __user *)pending + futex_offset,
- curr, pip);
+ if (pending) {
+ void __user *uaddr = futex_uaddr(pending, futex_offset);
+
+ handle_futex_death(uaddr, curr, pip);
+ }
}
asmlinkage long
compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
compat_size_t len)
{
}
asmlinkage long
compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
compat_size_t len)
{
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
+
if (unlikely(len != sizeof(*head)))
return -EINVAL;
if (unlikely(len != sizeof(*head)))
return -EINVAL;
@@
-117,6
+135,10
@@
compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
{
struct compat_robust_list_head __user *head;
unsigned long ret;
{
struct compat_robust_list_head __user *head;
unsigned long ret;
+ const struct cred *cred = current_cred(), *pcred;
+
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
if (!pid)
head = current->compat_robust_list;
if (!pid)
head = current->compat_robust_list;
@@
-125,13
+147,14
@@
compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
ret = -ESRCH;
read_lock(&tasklist_lock);
ret = -ESRCH;
read_lock(&tasklist_lock);
- p = find_task_by_pid_ns(pid,
- current->nsproxy->pid_ns);
+ p = find_task_by_vpid(pid);
if (!p)
goto err_unlock;
ret = -EPERM;
if (!p)
goto err_unlock;
ret = -EPERM;
- if ((current->euid != p->euid) && (current->euid != p->uid) &&
- !capable(CAP_SYS_PTRACE))
+ pcred = __task_cred(p);
+ if (cred->euid != pcred->euid &&
+ cred->euid != pcred->uid &&
+ !capable(CAP_SYS_PTRACE))
goto err_unlock;
head = p->compat_robust_list;
read_unlock(&tasklist_lock);
goto err_unlock;
head = p->compat_robust_list;
read_unlock(&tasklist_lock);
@@
-156,7
+179,9
@@
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
int val2 = 0;
int cmd = op & FUTEX_CMD_MASK;
int val2 = 0;
int cmd = op & FUTEX_CMD_MASK;
- if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) {
+ if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
+ cmd == FUTEX_WAIT_BITSET ||
+ cmd == FUTEX_WAIT_REQUEUE_PI)) {
if (get_compat_timespec(&ts, utime))
return -EFAULT;
if (!timespec_valid(&ts))
if (get_compat_timespec(&ts, utime))
return -EFAULT;
if (!timespec_valid(&ts))
@@
-164,10
+189,11
@@
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
t = timespec_to_ktime(ts);
if (cmd == FUTEX_WAIT)
t = timespec_to_ktime(ts);
if (cmd == FUTEX_WAIT)
- t = ktime_add(ktime_get(), t);
+ t = ktime_add
_safe
(ktime_get(), t);
tp = &t;
}
tp = &t;
}
- if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
+ cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
val2 = (int) (unsigned long) utime;
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
val2 = (int) (unsigned long) utime;
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);