Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: Add DisableSpeculationMitigations #1047

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KentaTada
Copy link
Contributor

@KentaTada KentaTada commented May 28, 2020

It disables speculative execution mitigations in the container.
For more information about that, please refer to:
opencontainers/runc#2430

Signed-off-by: Kenta Tada Kenta.Tada@sony.com

Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a nit, otherwise LGTM

@@ -58,6 +58,8 @@ type Process struct {
OOMScoreAdj *int `json:"oomScoreAdj,omitempty" platform:"linux"`
// SelinuxLabel specifies the selinux context that the container process is run as.
SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
// AllowSpeculation disables spectre mitigations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we just make it more generic like using speculative execution instead of spectre?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you. I changed the above and config.md and the commit message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

config.md Outdated
@@ -208,6 +208,7 @@ For Linux-based systems, the `process` object supports the following process-spe
For more information on how these two settings work together, see [the memory cgroup documentation section 10. OOM Contol][cgroup-v1-memory_2].
* **`selinuxLabel`** (string, OPTIONAL) specifies the SELinux label for the process.
For more information about SELinux, see [SELinux documentation][selinux].
* **`allowSpeculation`** (bool, OPTIONAL) setting `allowSpeculation` to true disable speculative execution mitigations to improve the performance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should name this disableSpeculationMitigations instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should name this disableSpeculationMitigations instead.

disableSpeculationMitigations is easy to understand although I wanted to use the positive boolean variable name. I don't mind whichever it is.
@giuseppe, Could you give me your opinion on the variable name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name @mrunalp suggested is clearer, since it is about allowing or disabling mitigations not the speculative execution itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll modify it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrunalp @giuseppe I changed the name.

@KentaTada KentaTada changed the title config: Add AllowSpeculation config: Add DisableSpeculationMitigations Jun 1, 2020
Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I understand adding a single boolean field is simpler, I'm not sure this is the best approach.

config.md Outdated
@@ -208,6 +208,7 @@ For Linux-based systems, the `process` object supports the following process-spe
For more information on how these two settings work together, see [the memory cgroup documentation section 10. OOM Contol][cgroup-v1-memory_2].
* **`selinuxLabel`** (string, OPTIONAL) specifies the SELinux label for the process.
For more information about SELinux, see [SELinux documentation][selinux].
* **`disableSpeculationMitigations`** (bool, OPTIONAL) setting `disableSpeculationMitigations` to true disable speculative execution mitigations to improve the performance.
Copy link
Member

@cyphar cyphar Jun 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs more explanation as an option (and should be reworded to not repeat the name of the setting), and preferably a link to the kernel documentation for speculation mitigations.

Suggested change
* **`disableSpeculationMitigations`** (bool, OPTIONAL) setting `disableSpeculationMitigations` to true disable speculative execution mitigations to improve the performance.
* **`disableSpeculationMitigations`** (bool, OPTIONAL) specifies whether CPU speculative execution mitigations should be disabled for the process. Several mitigations are auto-enabled under Linux, and can cause a noticeable performance impact (depending on your workload). Note that enabling this option may reduce the security properties of containers created with this configuration. See [the kernel documentation][speculative-control] for more information.
[speculative-control]: https://www.kernel.org/doc/html/latest/userspace-api/spec_ctrl.html

However, looking at the kernel documentation, i notice that this new configuration option doesn't allow users to specify PR_SPEC_FORCE_DISABLE -- which forces a container to have speculation mitigations enabled. There's also an argument that users should be able to specify which mitigations to disable... Maybe we should instead have a mitigations object that has more than one option:

"speculationMitigations": {
	"defaultRule": "force-enable",
	"exceptions": [
		{
			"mitigation": "store-bypass",
			"rule": "disable",
		},
	],
}

The above configuration would result in PR_SPEC_STORE_BYPASS being set to PR_SPEC_ENABLE, and PR_SPEC_INDIR_BRANCH being set to PR_SPEC_FORCE_DISABLE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs more explanation as an option (and should be reworded to not repeat the name of the setting), and preferably a link to the kernel documentation for speculation mitigations.

I completely agree with you. I should prepare for more explanation. Thanks!

Maybe we should instead have a mitigations object that has more than one option:

I agree to use object but please let me explain the background of prctl and seccomp.

The kernel automatically forces a container to have all speculation mitigations enabled when seccomp is used without SECCOMP_FILTER_FLAG_SPEC_ALLOW on x86_64.
https://github.com/torvalds/linux/blob/v5.7-rc7/arch/x86/kernel/cpu/bugs.c#L1201
It affects the result of prctl.

In addition to that, I found the kernel bug that the kernel only forced to enable Speculative Store Bypass mitigations and not to enable Indirect Branch Speculation mitigations even if seccomp was used. I may create a kernel patch after more investigation.

Anyway, I thought it was difficult for users to set up complex settings at first.
But I reconsider and it is no problem if container runtime handles it appropriately. 

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just realized we already have SECCOMP_FILTER_FLAG_SPEC_ALLOW in the seccomp flags (and I've added it): #1018

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giuseppe @cyphar

I've just realized we already have SECCOMP_FILTER_FLAG_SPEC_ALLOW in the seccomp flags (and I've added it): #1018

SECCOMP_FILTER_FLAG_SPEC_ALLOW is also needed to disable mitigations when secccomp is used as mentioned previously.
I think we will implement the container runtime using secomp with SECCOMP_FILTER_FLAG_SPEC_ALLOW + prctl like below:
https://chromium.googlesource.com/chromium/src/sandbox/+/be48c498815b50c9585332d35bb5f6f4920c41de

But

However, looking at the kernel documentation, i notice that this new configuration option doesn't allow users to specify PR_SPEC_FORCE_DISABLE -- which forces a container to have speculation mitigations enabled. There's also an argument that users should be able to specify which mitigations to disable... Maybe we should instead have a mitigations object that has more than one option:

I don't know the reason but https://www.kernel.org/doc/html/latest/userspace-api/spec_ctrl.html is different from the actual behavior.

  • When PR_SPEC_FORCE_DISABLE is set for PR_SPEC_STORE_BYPASS, a subsequent prctl(…, PR_SPEC_ENABLE) will fail. This is as same as the kernel document.
  • When PR_SPEC_FORCE_DISABLE is set for PR_SPEC_INDIRECT_BRANCH, a subsequent prctl(…, PR_SPEC_ENABLE) will not fail as below comments from kernel community. This is not as same as the kernel document.
    https://lore.kernel.org/patchwork/patch/1251849/

Actually, my below modified runc can disable IBPB/STIBP mitigation even if seccomp without SECCOMP_FILTER_FLAG_SPEC_ALLOW is enabled.
opencontainers/runc#2433

I'm sorry but please give me some time to reconsider this interface because it is complicated. And please give me feedback.
Thanks!

Copy link
Contributor Author

@KentaTada KentaTada Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI:

When PR_SPEC_FORCE_DISABLE is set for PR_SPEC_INDIRECT_BRANCH, a subsequent prctl(…, PR_SPEC_ENABLE) will not fail as below comments from kernel community. This is not as same as the kernel document.
https://lore.kernel.org/patchwork/patch/1251849/

After my patch, another person modified this issue as same as my patch.
https://lore.kernel.org/patchwork/patch/1253799/

So, the complicated specification or bug is fixed. I'll reconsider the interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyphar I apologize for the late reply. I updated to use object.
Could you review the latest commit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyphar PTAL ^^^

@KentaTada KentaTada force-pushed the allow-speculation branch 2 times, most recently from 86079d3 to eb7ab28 Compare June 1, 2020 10:33
It disables speculative execution mitigations
in the container.
For more information about that, please refer to:
opencontainers/runc#2430

Co-Authored-By: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Kenta Tada <Kenta.Tada@sony.com>
@KentaTada
Copy link
Contributor Author

@cyphar
This feature is also needed in moby/moby#42619
Could you review my update?

* `enable` - The mitigation of this particular speculation is disabled.
* `disable` - The mitigation of this particular speculation is enabled.
* `force-disable` - Same as disable, but it cannot be undone.
* `disable-noexec` - Same as disable, but the state will be cleared on execve(2).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disable-noexec is not applicable/supported for indirect-branch. Maybe we need a note here?

}

// SpecExceptions is used to specify the setting of speculative execution mitigations.
type SpecExceptions struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SpecException instead of SpecExceptions, as each defines one exception?

* `store-bypass` - Speculative Store Bypass
* `indirect-branch` - Indirect Branch Speculation in User Processes
* **`rule`** *(string, REQUIRED)* - enables or disables the specific mitigation.
* `enable` - The mitigation of this particular speculation is disabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the rules under exceptions keep the same semantics with disable, or it should reflect/align with the corresponding mitigation's?

* `disable` - The mitigation of speculations without `exceptions` is enabled.
* `force-disable` - Same as disable, but it cannot be undone.
* `disable-noexec` - Same as disable, but the state will be cleared on execve(2).
* **`exceptions`** *(array of objects, OPTIONAL)* - the configuration of specific mitigations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any possibility that we need multiple exceptions with the same mitigation type? If not, what about using dedicate structs with rules for store-bypass and indirect-branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants