Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/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
This commit is contained in:
Коммит
3a0d184943
|
@ -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 <amwang@redhat.com>
|
||||
|
||||
----------------------------
|
||||
|
||||
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 <keescook@chromium.org>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include <linux/magic.h>
|
||||
#include <linux/pid.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
#include <asm/futex.h>
|
||||
|
||||
|
@ -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;
|
||||
|
||||
if (!pid)
|
||||
head = current->robust_list;
|
||||
else {
|
||||
struct task_struct *p;
|
||||
WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");
|
||||
|
||||
ret = -ESRCH;
|
||||
rcu_read_lock();
|
||||
rcu_read_lock();
|
||||
|
||||
ret = -ESRCH;
|
||||
if (!pid)
|
||||
p = current;
|
||||
else {
|
||||
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);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/compat.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <linux/futex.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
@ -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;
|
||||
|
||||
if (!pid)
|
||||
head = current->compat_robust_list;
|
||||
else {
|
||||
struct task_struct *p;
|
||||
WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");
|
||||
|
||||
ret = -ESRCH;
|
||||
rcu_read_lock();
|
||||
rcu_read_lock();
|
||||
|
||||
ret = -ESRCH;
|
||||
if (!pid)
|
||||
p = current;
|
||||
else {
|
||||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче