prctl: Add speculation control prctls
Add two new prctls to control aspects of speculation related vulnerabilites and their mitigations to provide finer grained control over performance impacting mitigations. PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature which is selected with arg2 of prctl(2). The return value uses bit 0-2 with the following meaning: Bit Define Description 0 PR_SPEC_PRCTL Mitigation can be controlled per task by PR_SET_SPECULATION_CTRL 1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is disabled 2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is enabled If all bits are 0 the CPU is not affected by the speculation misfeature. If PR_SPEC_PRCTL is set, then the per task control of the mitigation is available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation misfeature will fail. PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which is selected by arg2 of prctl(2) per task. arg3 is used to hand in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE. The common return values are: EINVAL prctl is not implemented by the architecture or the unused prctl() arguments are not 0 ENODEV arg2 is selecting a not supported speculation misfeature PR_SET_SPECULATION_CTRL has these additional return values: ERANGE arg3 is incorrect, i.e. it's not either PR_SPEC_ENABLE or PR_SPEC_DISABLE ENXIO prctl control of the selected speculation misfeature is disabled The first supported controlable speculation misfeature is PR_SPEC_STORE_BYPASS. Add the define so this can be shared between architectures. Based on an initial patch from Tim Chen and mostly rewritten. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
parent
28a2775217
commit
b617cfc858
|
@ -19,6 +19,7 @@ place where this information is gathered.
|
||||||
no_new_privs
|
no_new_privs
|
||||||
seccomp_filter
|
seccomp_filter
|
||||||
unshare
|
unshare
|
||||||
|
spec_ctrl
|
||||||
|
|
||||||
.. only:: subproject and html
|
.. only:: subproject and html
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
===================
|
||||||
|
Speculation Control
|
||||||
|
===================
|
||||||
|
|
||||||
|
Quite some CPUs have speculation related misfeatures which are in fact
|
||||||
|
vulnerabilites causing data leaks in various forms even accross privilege
|
||||||
|
domains.
|
||||||
|
|
||||||
|
The kernel provides mitigation for such vulnerabilities in various
|
||||||
|
forms. Some of these mitigations are compile time configurable and some on
|
||||||
|
the kernel command line.
|
||||||
|
|
||||||
|
There is also a class of mitigations which are very expensive, but they can
|
||||||
|
be restricted to a certain set of processes or tasks in controlled
|
||||||
|
environments. The mechanism to control these mitigations is via
|
||||||
|
:manpage:`prctl(2)`.
|
||||||
|
|
||||||
|
There are two prctl options which are related to this:
|
||||||
|
|
||||||
|
* PR_GET_SPECULATION_CTRL
|
||||||
|
|
||||||
|
* PR_SET_SPECULATION_CTRL
|
||||||
|
|
||||||
|
PR_GET_SPECULATION_CTRL
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
|
||||||
|
which is selected with arg2 of prctl(2). The return value uses bits 0-2 with
|
||||||
|
the following meaning:
|
||||||
|
|
||||||
|
==== ================ ===================================================
|
||||||
|
Bit Define Description
|
||||||
|
==== ================ ===================================================
|
||||||
|
0 PR_SPEC_PRCTL Mitigation can be controlled per task by
|
||||||
|
PR_SET_SPECULATION_CTRL
|
||||||
|
1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
|
||||||
|
disabled
|
||||||
|
2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
|
||||||
|
enabled
|
||||||
|
==== ================ ===================================================
|
||||||
|
|
||||||
|
If all bits are 0 the CPU is not affected by the speculation misfeature.
|
||||||
|
|
||||||
|
If PR_SPEC_PRCTL is set, then the per task control of the mitigation is
|
||||||
|
available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation
|
||||||
|
misfeature will fail.
|
||||||
|
|
||||||
|
PR_SET_SPECULATION_CTRL
|
||||||
|
-----------------------
|
||||||
|
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
|
||||||
|
is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
|
||||||
|
in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE.
|
||||||
|
|
||||||
|
Common error codes
|
||||||
|
------------------
|
||||||
|
======= =================================================================
|
||||||
|
Value Meaning
|
||||||
|
======= =================================================================
|
||||||
|
EINVAL The prctl is not implemented by the architecture or unused
|
||||||
|
prctl(2) arguments are not 0
|
||||||
|
|
||||||
|
ENODEV arg2 is selecting a not supported speculation misfeature
|
||||||
|
======= =================================================================
|
||||||
|
|
||||||
|
PR_SET_SPECULATION_CTRL error codes
|
||||||
|
-----------------------------------
|
||||||
|
======= =================================================================
|
||||||
|
Value Meaning
|
||||||
|
======= =================================================================
|
||||||
|
0 Success
|
||||||
|
|
||||||
|
ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
|
||||||
|
PR_SPEC_DISABLE
|
||||||
|
|
||||||
|
ENXIO Control of the selected speculation misfeature is not possible.
|
||||||
|
See PR_GET_SPECULATION_CTRL.
|
||||||
|
======= =================================================================
|
||||||
|
|
||||||
|
Speculation misfeature controls
|
||||||
|
-------------------------------
|
||||||
|
- PR_SPEC_STORE_BYPASS: Speculative Store Bypass
|
||||||
|
|
||||||
|
Invocations:
|
||||||
|
* prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
|
||||||
|
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
|
||||||
|
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
|
|
@ -55,4 +55,9 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
|
||||||
\
|
\
|
||||||
(typeof(_i)) (_i & _mask); \
|
(typeof(_i)) (_i & _mask); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* Speculation control prctl */
|
||||||
|
int arch_prctl_spec_ctrl_get(unsigned long which);
|
||||||
|
int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
|
||||||
|
|
||||||
#endif /* _LINUX_NOSPEC_H */
|
#endif /* _LINUX_NOSPEC_H */
|
||||||
|
|
|
@ -207,4 +207,15 @@ struct prctl_mm_map {
|
||||||
# define PR_SVE_VL_LEN_MASK 0xffff
|
# define PR_SVE_VL_LEN_MASK 0xffff
|
||||||
# define PR_SVE_VL_INHERIT (1 << 17) /* inherit across exec */
|
# define PR_SVE_VL_INHERIT (1 << 17) /* inherit across exec */
|
||||||
|
|
||||||
|
/* Per task speculation control */
|
||||||
|
#define PR_GET_SPECULATION_CTRL 52
|
||||||
|
#define PR_SET_SPECULATION_CTRL 53
|
||||||
|
/* Speculation control variants */
|
||||||
|
# define PR_SPEC_STORE_BYPASS 0
|
||||||
|
/* Return and control values for PR_SET/GET_SPECULATION_CTRL */
|
||||||
|
# define PR_SPEC_NOT_AFFECTED 0
|
||||||
|
# define PR_SPEC_PRCTL (1UL << 0)
|
||||||
|
# define PR_SPEC_ENABLE (1UL << 1)
|
||||||
|
# define PR_SPEC_DISABLE (1UL << 2)
|
||||||
|
|
||||||
#endif /* _LINUX_PRCTL_H */
|
#endif /* _LINUX_PRCTL_H */
|
||||||
|
|
22
kernel/sys.c
22
kernel/sys.c
|
@ -61,6 +61,8 @@
|
||||||
#include <linux/uidgid.h>
|
#include <linux/uidgid.h>
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
|
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
#include <linux/kmsg_dump.h>
|
#include <linux/kmsg_dump.h>
|
||||||
/* Move somewhere else to avoid recompiling? */
|
/* Move somewhere else to avoid recompiling? */
|
||||||
#include <generated/utsrelease.h>
|
#include <generated/utsrelease.h>
|
||||||
|
@ -2242,6 +2244,16 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __weak arch_prctl_spec_ctrl_get(unsigned long which)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
||||||
unsigned long, arg4, unsigned long, arg5)
|
unsigned long, arg4, unsigned long, arg5)
|
||||||
{
|
{
|
||||||
|
@ -2450,6 +2462,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
||||||
case PR_SVE_GET_VL:
|
case PR_SVE_GET_VL:
|
||||||
error = SVE_GET_VL();
|
error = SVE_GET_VL();
|
||||||
break;
|
break;
|
||||||
|
case PR_GET_SPECULATION_CTRL:
|
||||||
|
if (arg3 || arg4 || arg5)
|
||||||
|
return -EINVAL;
|
||||||
|
error = arch_prctl_spec_ctrl_get(arg2);
|
||||||
|
break;
|
||||||
|
case PR_SET_SPECULATION_CTRL:
|
||||||
|
if (arg4 || arg5)
|
||||||
|
return -EINVAL;
|
||||||
|
error = arch_prctl_spec_ctrl_set(arg2, arg3);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue