Commit 33cd29bc authored by Kees Cook's avatar Kees Cook Committed by Juerg Haefliger

UBUNTU: SAUCE: nospec: Allow getting/setting on non-current task

CVE-2018-3639 (x86)

Adjust arch_prctl_get/set_spec_ctrl() to operate on tasks other than
current.

This is needed both for /proc/$pid/status queries and for seccomp (since
thread-syncing can trigger seccomp in non-current threads).
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarTyler Hicks <tyhicks@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
[juergh: Context adjustments.]
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
parent 45993eab
......@@ -555,31 +555,35 @@ static void ssb_select_mitigation()
#undef pr_fmt
static int ssb_prctl_set(unsigned long ctrl)
static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
{
bool rds = !!test_tsk_thread_flag(current, TIF_RDS);
bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
return -ENXIO;
if (ctrl == PR_SPEC_ENABLE)
clear_tsk_thread_flag(current, TIF_RDS);
clear_tsk_thread_flag(task, TIF_RDS);
else
set_tsk_thread_flag(current, TIF_RDS);
set_tsk_thread_flag(task, TIF_RDS);
if (rds != !!test_tsk_thread_flag(current, TIF_RDS))
/*
* If being set on non-current task, delay setting the CPU
* mitigation until it is next scheduled.
*/
if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
speculative_store_bypass_update();
return 0;
}
static int ssb_prctl_get(void)
static int ssb_prctl_get(struct task_struct *task)
{
switch (ssb_mode) {
case SPEC_STORE_BYPASS_DISABLE:
return PR_SPEC_DISABLE;
case SPEC_STORE_BYPASS_PRCTL:
if (test_tsk_thread_flag(current, TIF_RDS))
if (test_tsk_thread_flag(task, TIF_RDS))
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
default:
......@@ -589,24 +593,25 @@ static int ssb_prctl_get(void)
}
}
int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
unsigned long ctrl)
{
if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
return -ERANGE;
switch (which) {
case PR_SPEC_STORE_BYPASS:
return ssb_prctl_set(ctrl);
return ssb_prctl_set(task, ctrl);
default:
return -ENODEV;
}
}
int arch_prctl_spec_ctrl_get(unsigned long which)
int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
{
switch (which) {
case PR_SPEC_STORE_BYPASS:
return ssb_prctl_get();
return ssb_prctl_get(task);
default:
return -ENODEV;
}
......
......@@ -7,8 +7,11 @@
#define _LINUX_NOSPEC_H
#include <asm/barrier.h>
struct task_struct;
/* Speculation control prctl */
int arch_prctl_spec_ctrl_get(unsigned long which);
int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which);
int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
unsigned long ctrl);
#endif /* _LINUX_NOSPEC_H */
......@@ -2089,12 +2089,13 @@ static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
}
#endif
int __weak arch_prctl_spec_ctrl_get(unsigned long which)
int __weak arch_prctl_spec_ctrl_get(struct task_struct *t, unsigned long which)
{
return -EINVAL;
}
int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which,
unsigned long ctrl)
{
return -EINVAL;
}
......@@ -2296,12 +2297,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
case PR_GET_SPECULATION_CTRL:
if (arg3 || arg4 || arg5)
return -EINVAL;
error = arch_prctl_spec_ctrl_get(arg2);
error = arch_prctl_spec_ctrl_get(me, arg2);
break;
case PR_SET_SPECULATION_CTRL:
if (arg4 || arg5)
return -EINVAL;
error = arch_prctl_spec_ctrl_set(arg2, arg3);
error = arch_prctl_spec_ctrl_set(me, arg2, arg3);
break;
default:
error = -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment