-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
x86-64: Enable Intel CET #2992
x86-64: Enable Intel CET #2992
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I'd never heard of Intel CET, but it looks harmless enough...
Could you take a minute to describe what benefit this inclusion provides?
Note, GCC says:
[...] the recommended use of the [
__has_include
] operator is as follows:#if defined __has_include # if __has_include (<stdatomic.h>) # include <stdatomic.h> # endif #endif
The first
#if
test succeeds only when the operator is supported by the version of GCC (or another compiler) being used. Only when that test succeeds is it valid to use__has_include
as a preprocessor operator. As a result, combining the two tests into a single expression as shown below would only be valid with a compiler that supports the operator but not with others that don’t.#if defined __has_include && __has_include ("header.h") /* not portable */ … #endif
Please rewrite the test to match that style.
fbf54c5
to
ba5a7c9
Compare
Done.
Done. |
ba5a7c9
to
cd7620a
Compare
Thanks for applying the patch so quickly! I've tried to do some reading to understand what CET does. If I understand correctly, it impacts (all?) control flow instructions, in different ways. It looks like no modification of the source is required for However, it sounds to me like (some?) It looks like those are the only things tracked by CET? So it sounds to me like our current source is compatible with CET as-is. The criteria I'm trying to evaluate overall here are:
So it seems like this is close to good to go. Please correct me if I'm misunderstanding or missing anything. And if you're able to help us make sure we have good test coverage for this, that would also be great! |
Correct.
Correct.
On Linux/x86, you can use
There is no performance impact.
Let me try. |
See: #2994 |
Intel Control-flow Enforcement Technology (CET): https://en.wikipedia.org/wiki/Control-flow_integrity#Intel_Control-flow_Enforcement_Technology requires that on Linux, all linker input files are marked as CET enabled in .note.gnu.property section. For high-level language source codes, .note.gnu.property section is added by compiler with the -fcf-protection option. For assembly sources, include <cet.h> to add .note.gnu.property section.
cd7620a
to
51ab182
Compare
Ok, so the only remaining topic was to see if I could get a CET-violating instruction to trigger a fault. I tried the following patch on top of this PR: --- a/lib/decompress/huf_decompress_amd64.S
+++ b/lib/decompress/huf_decompress_amd64.S
@@ -303,7 +303,8 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
movq 16(%rsp), %ip3
/* Re-compute olimit */
- jmp .L_4X1_compute_olimit
+ lea .L_4X1_compute_olimit(%rip), %rax
+ jmp *%rax
#undef GET_NEXT_DELT
#undef DECODE_FROM_DELT
@@ -535,7 +536,8 @@ HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
cmp %op3, 48(%rsp)
ja .L_4X2_loop_body
- jmp .L_4X2_compute_olimit
+ lea .L_4X2_compute_olimit(%rip), %rax
+ jmp *%rax
#undef DECODE
#undef RELOAD_BITS I built this with:
As I understand it, this should trigger a fault when run under CET. But no such error occurs when I run it. Googling shows that hardware CET support is only present starting in Tiger Lake chips. And my workstation is a Haswell... I'm assuming that GitHub's virtual environments don't support CET either. Is there any way we can simulate running under CET to validate that our binary works? Maybe under QEMU or something? |
You need to run it under a CET enabled kernel on TGL to see the CP fault. https://github.com/hjl-tools/linux/tree/hjl/cet%2Flinux-5.15.y
|
Short of going out and buying one, it looks like I don't have access to a Tiger Lake or Alder Lake system. Certainly we don't have continuous testing infrastructure on such a platform. I'm not really sure how best to proceed. On the one hand, I have high confidence that this patch is correct at present. And on that basis I'm inclined to merge it. But I'm uncomfortable enabling a feature whose purpose is to blow up on users' machines under conditions that are (absent CET) otherwise valid, when we have no way to test that our code does not meet those conditions. It's not totally unthinkable that some day in the future someone will want to ship an indirect jump, and we will have forgotten that this is a thing. Do you have any suggestions? |
Please try Intel SDE on Linux: https://www.intel.com/content/www/us/en/developer/articles/tool/software-development-emulator.html You can pass "-tgl -cet" to SDE to test CET. |
@hjl-tools, ah this looks exactly like what I'm looking for. I can't seem to get it to work though. I verified (I'm pretty sure) that my built binary has CET enabled:
But when I invoke
I can verify that the indirect jump I inserted above is being executed:
What am I doing wrong? |
Aha! I figured it out. This document describes that
Excellent! I will look into turning this into a test we can run continuously. And then this likely clears us to merge this PR. |
@hjl-tools, I'm trying to come up with a test we can run continuously in GitHub and once again I'm seeing behavior I don't understand. When I invoke zstd through SDE, it seems like SDE is doing nothing and zstd is being run directly: https://github.com/felixhandte/zstd/runs/479429041 I would have expected:
Do you have any insight into what's going wrong? |
How can I reproduce it? |
You can grab my attempt here:
You can then open a PR with that code against a zstd repo (mine, for example) to run the actions. |
I reproduced it. I reported it to our SDE developers. |
Please check felixhandte#7 |
@hjl-tools, that worked! Excellent! |
Intel Control-flow Enforcement Technology (CET):
https://en.wikipedia.org/wiki/Control-flow_integrity#Intel_Control-flow_Enforcement_Technology
requires that on Linux, all linker input files are marked as CET enabled
in .note.gnu.property section. For high-level language source codes,
.note.gnu.property section is added by compiler with the -fcf-protection
option. For assembly sources, include <cet.h> to add .note.gnu.property
section.