Skip to content

Commit

Permalink
Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/tip

Pull core locking updates from Thomas Gleixner.

* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  futex: Mark get_robust_list as deprecated
  futex: Do not leak robust list to unprivileged process
  • Loading branch information
torvalds committed Mar 31, 2012
2 parents 623ff77 + ec0c427 commit 3a0d184
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 46 deletions.
10 changes: 10 additions & 0 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,13 @@ When: 3.5
Why: The old kmap_atomic() with two arguments is deprecated, we only
keep it for backward compatibility for few cycles and then drop it.
Who: Cong Wang <[email protected]>

----------------------------

What: get_robust_list syscall
When: 2013
Why: There appear to be no production users of the get_robust_list syscall,
and it runs the risk of leaking address locations, allowing the bypass
of ASLR. It was only ever intended for debugging, so it should be
removed.
Who: Kees Cook <[email protected]>
38 changes: 15 additions & 23 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <linux/magic.h>
#include <linux/pid.h>
#include <linux/nsproxy.h>
#include <linux/ptrace.h>

#include <asm/futex.h>

Expand Down Expand Up @@ -2443,40 +2444,31 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
{
struct robust_list_head __user *head;
unsigned long ret;
const struct cred *cred = current_cred(), *pcred;
struct task_struct *p;

if (!futex_cmpxchg_enabled)
return -ENOSYS;

WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");

rcu_read_lock();

ret = -ESRCH;
if (!pid)
head = current->robust_list;
p = current;
else {
struct task_struct *p;

ret = -ESRCH;
rcu_read_lock();
p = find_task_by_vpid(pid);
if (!p)
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 &&
!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
goto err_unlock;
ok:
head = p->robust_list;
rcu_read_unlock();
}

ret = -EPERM;
if (!ptrace_may_access(p, PTRACE_MODE_READ))
goto err_unlock;

head = p->robust_list;
rcu_read_unlock();

if (put_user(sizeof(*head), len_ptr))
return -EFAULT;
return put_user(head, head_ptr);
Expand Down
38 changes: 15 additions & 23 deletions kernel/futex_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/compat.h>
#include <linux/nsproxy.h>
#include <linux/futex.h>
#include <linux/ptrace.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -136,40 +137,31 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
{
struct compat_robust_list_head __user *head;
unsigned long ret;
const struct cred *cred = current_cred(), *pcred;
struct task_struct *p;

if (!futex_cmpxchg_enabled)
return -ENOSYS;

WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");

rcu_read_lock();

ret = -ESRCH;
if (!pid)
head = current->compat_robust_list;
p = current;
else {
struct task_struct *p;

ret = -ESRCH;
rcu_read_lock();
p = find_task_by_vpid(pid);
if (!p)
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 &&
!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
goto err_unlock;
ok:
head = p->compat_robust_list;
rcu_read_unlock();
}

ret = -EPERM;
if (!ptrace_may_access(p, PTRACE_MODE_READ))
goto err_unlock;

head = p->compat_robust_list;
rcu_read_unlock();

if (put_user(sizeof(*head), len_ptr))
return -EFAULT;
return put_user(ptr_to_compat(head), head_ptr);
Expand Down

0 comments on commit 3a0d184

Please sign in to comment.