Core locking updates for 3.4
Linus,
please pull the latest core-locking-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-locking-for-linus
Thanks,
tglx
------------------>
Kees Cook (2):
futex: Do not leak robust list to unprivileged process
futex: Mark get_robust_list as deprecated
Documentation/feature-removal-schedule.txt | 10 +++++++ kernel/futex.c | 38 +++++++++++----------------- kernel/futex_compat.c | 38 +++++++++++----------------- 3 files changed, 40 insertions(+), 46 deletions(-)
Documentation/feature-removal-schedule.txt +10 -0
@@ -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]>
kernel/futex.c +15 -23
@@ -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 ; +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);
kernel/futex_compat.c +15 -23
@@ -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 ; +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);