Skip to content

Commit

Permalink
prctl: Add speculation control prctls
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Ingo Molnar <[email protected]>
Reviewed-by: Konrad Rzeszutek Wilk <[email protected]>
  • Loading branch information
KAGA-KOKO committed May 3, 2018
1 parent 28a2775 commit b617cfc
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
1 change: 1 addition & 0 deletions Documentation/userspace-api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ place where this information is gathered.
no_new_privs
seccomp_filter
unshare
spec_ctrl

.. only:: subproject and html

Expand Down
86 changes: 86 additions & 0 deletions Documentation/userspace-api/spec_ctrl.rst
Original file line number Diff line number Diff line change
@@ -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);
5 changes: 5 additions & 0 deletions include/linux/nospec.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
\
(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 */
11 changes: 11 additions & 0 deletions include/uapi/linux/prctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,15 @@ struct prctl_mm_map {
# define PR_SVE_VL_LEN_MASK 0xffff
# 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 */
22 changes: 22 additions & 0 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
#include <linux/uidgid.h>
#include <linux/cred.h>

#include <linux/nospec.h>

#include <linux/kmsg_dump.h>
/* Move somewhere else to avoid recompiling? */
#include <generated/utsrelease.h>
Expand Down Expand Up @@ -2242,6 +2244,16 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data)
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,
unsigned long, arg4, unsigned long, arg5)
{
Expand Down Expand Up @@ -2450,6 +2462,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
case PR_SVE_GET_VL:
error = SVE_GET_VL();
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:
error = -EINVAL;
break;
Expand Down

0 comments on commit b617cfc

Please sign in to comment.