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
|
Why: The old kmap_atomic() with two arguments is deprecated, we only
|
||||||
keep it for backward compatibility for few cycles and then drop it.
|
keep it for backward compatibility for few cycles and then drop it.
|
||||||
Who: Cong Wang <amwang@redhat.com>
|
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/magic.h>
|
||||||
#include <linux/pid.h>
|
#include <linux/pid.h>
|
||||||
#include <linux/nsproxy.h>
|
#include <linux/nsproxy.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
|
||||||
#include <asm/futex.h>
|
#include <asm/futex.h>
|
||||||
|
|
||||||
|
@ -2443,40 +2444,31 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
|
||||||
{
|
{
|
||||||
struct robust_list_head __user *head;
|
struct robust_list_head __user *head;
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
const struct cred *cred = current_cred(), *pcred;
|
struct task_struct *p;
|
||||||
|
|
||||||
if (!futex_cmpxchg_enabled)
|
if (!futex_cmpxchg_enabled)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
if (!pid)
|
WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");
|
||||||
head = current->robust_list;
|
|
||||||
else {
|
|
||||||
struct task_struct *p;
|
|
||||||
|
|
||||||
ret = -ESRCH;
|
rcu_read_lock();
|
||||||
rcu_read_lock();
|
|
||||||
|
ret = -ESRCH;
|
||||||
|
if (!pid)
|
||||||
|
p = current;
|
||||||
|
else {
|
||||||
p = find_task_by_vpid(pid);
|
p = find_task_by_vpid(pid);
|
||||||
if (!p)
|
if (!p)
|
||||||
goto err_unlock;
|
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))
|
if (put_user(sizeof(*head), len_ptr))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return put_user(head, head_ptr);
|
return put_user(head, head_ptr);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/nsproxy.h>
|
#include <linux/nsproxy.h>
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
|
||||||
#include <asm/uaccess.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;
|
struct compat_robust_list_head __user *head;
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
const struct cred *cred = current_cred(), *pcred;
|
struct task_struct *p;
|
||||||
|
|
||||||
if (!futex_cmpxchg_enabled)
|
if (!futex_cmpxchg_enabled)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
if (!pid)
|
WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");
|
||||||
head = current->compat_robust_list;
|
|
||||||
else {
|
|
||||||
struct task_struct *p;
|
|
||||||
|
|
||||||
ret = -ESRCH;
|
rcu_read_lock();
|
||||||
rcu_read_lock();
|
|
||||||
|
ret = -ESRCH;
|
||||||
|
if (!pid)
|
||||||
|
p = current;
|
||||||
|
else {
|
||||||
p = find_task_by_vpid(pid);
|
p = find_task_by_vpid(pid);
|
||||||
if (!p)
|
if (!p)
|
||||||
goto err_unlock;
|
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))
|
if (put_user(sizeof(*head), len_ptr))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return put_user(ptr_to_compat(head), head_ptr);
|
return put_user(ptr_to_compat(head), head_ptr);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче