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

x86_64: Add CET instructions and check in CI #761

Merged
merged 3 commits into from
Feb 8, 2025
Merged

Conversation

mkannwischer
Copy link
Contributor

@mkannwischer mkannwischer commented Feb 8, 2025

Modern x86_64 support hardware features through the CET instructions to protect
against return-oriented programming (ROP) attacks. Those protections can be
enabled through -fcf-protection=.
For this to work, all compilation units (including assembly) need to support
CET.

This commit adds support and contains two main changes:

  1. Each assembly file needs to set the the appropriate note.gnu.property
    section to signal that it does support CET. We achieve this by including cet.h
    in all assembly files which sets the required properties.
    Note that this applies also to empty compilation units (e.g., the aarch64
    assembly files when compiling for x86_64).

  2. Each label that can potentially be a target of an indirect branch needs
    to start with en endbr64 instruction, otherwise the branch faults.
    Our assembly does not use indirect branches and, hence, any internal branching
    is unaffected by this.
    However, the global symbols may potentially be targets of indirect branches
    (they don't seem to be though). To address this, we add endb64 to every global
    symbol by using the _CET_ENDBR macro provided by cet.h. Note that this is
    only adding the instruction in case CET is enabled.
    We introduce a new macro MLK_ASM_FN_SYMBOL that adds this automatically for
    X86 systems. This way our assembly simplification scripts are unaffected as
    the endbr64 instructions are out of scope.

Resolves #762

@mkannwischer mkannwischer force-pushed the cf-protections branch 9 times, most recently from 0c95f79 to cb3a0f9 Compare February 8, 2025 04:04
@mkannwischer mkannwischer force-pushed the cf-protections branch 6 times, most recently from 0b87872 to 851964b Compare February 8, 2025 08:23
@mkannwischer mkannwischer marked this pull request as ready for review February 8, 2025 08:23
mlkem/sys.h Outdated Show resolved Hide resolved
Copy link
Contributor

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

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

I would prefer not to dummy-define CET_xxx but use a MLK wrapper. Otherwise we risk breaking this with the undef section in the monobuild

Modern x86_64 support hardware features through the CET instructions to protect
against return-oriented programming (ROP) attacks. Those protections can be
enabled through -fcf-protection=.
For this to work, all compilation units (including assembly) need to support
CET.

This commit adds support and contains two main changes:

1) Each assembly file needs to set the the appropriate note.gnu.property
 section to signal that it does support CET. We achieve this by including cet.h
 in all assembly files which sets the required properties.
 Note that this applies also to empty compilation units (e.g., the aarch64
 assembly files when compiling for x86_64).

2) Each label that can potentially be a target of an indirect branch needs
 to start with en endbr64 instruction, otherwise the branch faults.
 Our assembly does not use indirect branches and, hence, any internal branching
 is unaffected by this.
 However, the global symbols may potentially be targets of indirect branches
 (they don't seem to be though). To address this, we add endb64 to every global
 symbol by using the _CET_ENDBR macro provided by cet.h. Note that this is
 only adding the instruction in case CET is enabled.
 We introduce a new macro MLK_ASM_FN_SYMBOL that adds this automatically for
 X86 systems. This way our assembly simplification scripts are unaffected as
 the endbr64 instructions are out of scope.

Signed-off-by: Matthias J. Kannwischer <[email protected]>

.
Signed-off-by: Matthias J. Kannwischer <[email protected]>
This commit adds a workflow that checks if we properly support CET by compiling
with -fcf-protection=full.

This primarily checks that all assembly compilation units set the required
note.gnu.property section signaling CET support (this can be achieved by
setting -Wl,-z,cet-report=error).

This does _not_ make sure all global symbols have the required endbr64
instructions. Our binaries do not use indirect branches anywhere, so if
those instructions would be missing, there would not be any fault.

Signed-off-by: Matthias J. Kannwischer <[email protected]>
Copy link
Contributor

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

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

Thank you @mkannwischer !

@hanno-becker hanno-becker merged commit 8e77f81 into main Feb 8, 2025
176 checks passed
@hanno-becker hanno-becker deleted the cf-protections branch February 8, 2025 09:45
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.

Support Intel's Control-Flow Protections (CET)
2 participants