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

retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features #135927

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

Conversation

azhogin
Copy link
Contributor

@azhogin azhogin commented Jan 23, 2025

-Zretpoline and -Zretpoline-external-thunk flags are target modifiers (tracked to be equal in linked crates).

  • Enables target features for -Zretpoline-external-thunk:
    +retpoline-external-thunk, +retpoline-indirect-branches, +retpoline-indirect-calls.
  • Enables target features for -Zretpoline:
    +retpoline-indirect-branches, +retpoline-indirect-calls.

It corresponds to clang -mretpoline & -mretpoline-external-thunk flags.

Also this PR forbids to specify those target features manually (warning).

@rustbot
Copy link
Collaborator

rustbot commented Jan 23, 2025

r? @compiler-errors

rustbot has assigned @compiler-errors.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jan 23, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jan 23, 2025

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Member

r? compiler

@bors
Copy link
Collaborator

bors commented Jan 26, 2025

☔ The latest upstream changes (presumably #136085) made this pull request unmergeable. Please resolve the merge conflicts.

@azhogin azhogin marked this pull request as draft January 30, 2025 08:48
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@chenyukang
Copy link
Member

r? compiler

@rustbot rustbot assigned fee1-dead and unassigned chenyukang Feb 5, 2025
@rust-log-analyzer

This comment has been minimized.

@fee1-dead
Copy link
Member

r? compiler

@rustbot rustbot assigned lcnr and unassigned fee1-dead Feb 8, 2025
@lcnr
Copy link
Contributor

lcnr commented Feb 9, 2025

r? @davidtwco maybe 😅

@Darksonn
Copy link
Contributor

I don't think retpoline actually changes the ABI, so it might not need to be a target modifier. On the other hand, as an exploit mitigation, we do still want to avoid cases where you don't enable the mitigation in every compilation unit.

cc @andyhhp do I understand things correctly?

@azhogin
Copy link
Contributor Author

azhogin commented Feb 13, 2025

I don't think retpoline actually changes the ABI, so it might not need to be a target modifier. On the other hand, as an exploit mitigation, we do still want to avoid cases where you don't enable the mitigation in every compilation unit.

I read your post in #116852:

I've investigated this issue in more details. It turns out that the retpoline mitigations do not affect ABI and can be mixed.

Mixing them gives up their advantage, though. Linking together two compilation units that disagree on whether to apply the mitigation may make both vulnerable to what they attempt to mitigate.

That's why I thought it should be a target modifier.

@andyhhp
Copy link

andyhhp commented Feb 14, 2025

I don't think retpoline actually changes the ABI, so it might not need to be a target modifier. On the other hand, as an exploit mitigation, we do still want to avoid cases where you don't enable the mitigation in every compilation unit.

cc @andyhhp do I understand things correctly?

It's important to distinguish the general indirect-thunk transform from retpoline which is one specific transform (and is not effective on any Intel CPUs since Skylake).

retpoline is the specifically transform of an indirect call/jmp instruction into a call; int3; rewrite-ra; ret ROP gadget with the same net effect, but causes prediction to come from the RSB rather than the BTB.

The need to rewrite the return address on the stack necessitates the use of a GPR, and this is observable call/jmp-ee but any non-parameter register will do, so it doesn't impact the main function call ABI.

Even within retpoline itself, there are variations; inline retpolines are an option, but tend to be heavy on the code bloat side, which is why out-of-line retpolines in common sections are often preferred.

The alternatives to repoline are lfence;jmp (used on some Atom processors where retpoline isn't safe. Previously recommended by AMD but later rescinded), and re-inlining the original indirect branch (when hardware is believed safe, which is a contentious point because it can be made safe on AMD, but only "pretty safe" Intel.)

As to separate complication units, you can mix and match, but if any one piece of your whole process isn't taking safety precautions, then you've lost.

@azhogin
Copy link
Contributor Author

azhogin commented Feb 25, 2025

It's important to distinguish the general indirect-thunk transform from retpoline which is one specific transform (and is not effective on any Intel CPUs since Skylake).

Could you, please, recommend the right way to represent this flag according with +retpoline-external-thunk, +retpoline-indirect-branches, +retpoline-indirect-calls target features?

Should it be -Zx86-retpoline=[fixed_variant_of_features1|fixed_variant_of_features2|...] as in harden-sls (#136597)?
Or simple features list like -Zx86-retpoline=external-thunk,indirect-calls?

@Darksonn
Copy link
Contributor

I would think that the best choice would be to use the same name as clang, which is -mretpoline-external-thunk. So that would be -Zretpoline-external-thunk.

@ojeda
Copy link
Contributor

ojeda commented Mar 13, 2025

Yeah, personally, I prefer when compiler drivers agree. rustc tends to diverge a fair amount, but at least if "uncommon" flags have the same names it would help a bit.

@azhogin azhogin force-pushed the azhogin/retpoline branch from 386c90e to 597eb26 Compare March 25, 2025 15:09
@azhogin
Copy link
Contributor Author

azhogin commented Mar 25, 2025

  • -Zretpoline-external-thunk flag enables:
    +retpoline-external-thunk, +retpoline-indirect-branches, +retpoline-indirect-calls.

  • -Zretpoline flag enables:
    +retpoline-indirect-branches, +retpoline-indirect-calls

-Zretpoline-external-thunk also turns on -Zretpoline.

Looks like it corresponds to clang flags.

@azhogin azhogin changed the title x86-retpoline flag (target modifier) to enable retpoline-related target features retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features Mar 25, 2025
@azhogin azhogin marked this pull request as ready for review March 26, 2025 06:48
@rustbot
Copy link
Collaborator

rustbot commented Mar 26, 2025

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

}
}

/// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`.
/// (It might still be nightly-only even if this returns `true`, so make sure to also check
/// `requires_nightly`.)
pub fn toggle_allowed(&self) -> Result<(), &'static str> {
Copy link
Member

Choose a reason for hiding this comment

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

this API seems confusing, at the very least change the doc comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.