From 8458b5cdccec7b56055c81454a0b633b3761dea3 Mon Sep 17 00:00:00 2001 From: Kenta Tada Date: Tue, 26 May 2020 11:17:26 +0900 Subject: [PATCH] Add --allow-speculation option to disable IBPB/STIBP mitigation This flag disables IBPB/STIBP mitigation for container. It is needed to improve the performance of bytecode interpreters when users do not need IBPB/STIBP mitigation. Signed-off-by: Kenta Tada --- create.go | 4 ++++ libcontainer/configs/config.go | 3 +++ libcontainer/init_linux.go | 1 + libcontainer/specconv/spec_linux.go | 18 ++++++++++-------- libcontainer/standard_init_linux.go | 5 +++++ run.go | 4 ++++ utils_linux.go | 1 + 7 files changed, 28 insertions(+), 8 deletions(-) diff --git a/create.go b/create.go index 5f3ac60958e..9e570b81e4b 100644 --- a/create.go +++ b/create.go @@ -50,6 +50,10 @@ command(s) that get executed on start, edit the args parameter of the spec. See Name: "preserve-fds", Usage: "Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)", }, + cli.BoolFlag{ + Name: "allow-speculation", + Usage: "disable spectre mitigations", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go index 8c19c4a1958..b913b11e9e7 100644 --- a/libcontainer/configs/config.go +++ b/libcontainer/configs/config.go @@ -85,6 +85,9 @@ type Config struct { // This is a common option when the container is running in ramdisk NoPivotRoot bool `json:"no_pivot_root"` + // AllowSpeculation will disable IBPB/STIBP mitigation. + AllowSpeculation bool `json:"allow_speculation"` + // ParentDeathSignal specifies the signal that is sent to the container's process in the case // that the parent process dies. ParentDeathSignal int `json:"parent_death_signal"` diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 2c304001ad7..d5448ee3212 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -55,6 +55,7 @@ type initConfig struct { ProcessLabel string `json:"process_label"` AppArmorProfile string `json:"apparmor_profile"` NoNewPrivileges bool `json:"no_new_privileges"` + AllowSpeculation bool `json:"allow_speculation"` User string `json:"user"` AdditionalGroups []string `json:"additional_groups"` Config *configs.Config `json:"config"` diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go index 2ad1651f393..8d9f782faca 100644 --- a/libcontainer/specconv/spec_linux.go +++ b/libcontainer/specconv/spec_linux.go @@ -197,6 +197,7 @@ type CreateOpts struct { UseSystemdCgroup bool NoPivotRoot bool NoNewKeyring bool + AllowSpeculation bool Spec *specs.Spec RootlessEUID bool RootlessCgroups bool @@ -227,14 +228,15 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) { labels = append(labels, fmt.Sprintf("%s=%s", k, v)) } config := &configs.Config{ - Rootfs: rootfsPath, - NoPivotRoot: opts.NoPivotRoot, - Readonlyfs: spec.Root.Readonly, - Hostname: spec.Hostname, - Labels: append(labels, fmt.Sprintf("bundle=%s", cwd)), - NoNewKeyring: opts.NoNewKeyring, - RootlessEUID: opts.RootlessEUID, - RootlessCgroups: opts.RootlessCgroups, + Rootfs: rootfsPath, + NoPivotRoot: opts.NoPivotRoot, + AllowSpeculation: opts.AllowSpeculation, + Readonlyfs: spec.Root.Readonly, + Hostname: spec.Hostname, + Labels: append(labels, fmt.Sprintf("bundle=%s", cwd)), + NoNewKeyring: opts.NoNewKeyring, + RootlessEUID: opts.RootlessEUID, + RootlessCgroups: opts.RootlessCgroups, } exists := false diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index f5be67c01b7..3df6af8b9e3 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -207,6 +207,11 @@ func (l *linuxStandardInit) Init() error { return newSystemErrorWithCause(err, "init seccomp") } } + if l.config.Config.AllowSpeculation { + if err := unix.Prctl(unix.PR_SET_SPECULATION_CTRL, unix.PR_SPEC_INDIRECT_BRANCH, unix.PR_SPEC_ENABLE, 0, 0); err != nil { + return errors.Wrap(err, "disable IBPB/STIBP mitigation") + } + } if err := unix.Exec(name, l.config.Args[0:], os.Environ()); err != nil { return newSystemErrorWithCause(err, "exec user process") } diff --git a/run.go b/run.go index f8d6317844d..e3e749e4613 100644 --- a/run.go +++ b/run.go @@ -61,6 +61,10 @@ command(s) that get executed on start, edit the args parameter of the spec. See Name: "preserve-fds", Usage: "Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)", }, + cli.BoolFlag{ + Name: "allow-speculation", + Usage: "disable spectre mitigations", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { diff --git a/utils_linux.go b/utils_linux.go index a9587f7d3bc..a0415dd3f93 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -236,6 +236,7 @@ func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcont UseSystemdCgroup: context.GlobalBool("systemd-cgroup"), NoPivotRoot: context.Bool("no-pivot"), NoNewKeyring: context.Bool("no-new-keyring"), + AllowSpeculation: context.Bool("allow-speculation"), Spec: spec, RootlessEUID: os.Geteuid() != 0, RootlessCgroups: rootlessCg,