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

riscv64imac: allow shadow call stack sanitizer #129316

Merged
merged 1 commit into from
Aug 29, 2024

Conversation

dingxiangfei2009
Copy link
Contributor

cc @Darksonn for shadow call stack sanitizer support on RV64IMAC and RV64GC

@rustbot
Copy link
Collaborator

rustbot commented Aug 20, 2024

r? @nnethercote

rustbot has assigned @nnethercote.
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. labels Aug 20, 2024
@Darksonn
Copy link
Contributor

Some context: on aarch64 there is a requirement to pass the -Zfixed-x18, but there is no such flag on riscv. You just need to make sure the build is linked to a runtime with Shadow Call Stack instrumentation support.

See #128348 for the equivalent aarch64 change.

@ilovepi
Copy link
Contributor

ilovepi commented Aug 20, 2024

For SCS RISC-V needs gp/X3 to not be used for gp-relaxation. Not sure if rustc has a nob for that, but it may make sense to issue a warning if SCS and gp-relaxation are used together. I don't recall if we do that in clang, but you're going to have a bad time if you mix them. We're supposed to use the ELF attributes to make sure you don't mix them improperly and fail the link, but that work has been blocked on linker support across toolchains. Butgp/X3 is always reserved, so you're right that the equivalent check isn't needed.

@Darksonn
Copy link
Contributor

I don't believe rustc has a nob for that. I've only ever seen it on linkers. It doesn't sound like there's anything we can do about it right now?

@ilovepi
Copy link
Contributor

ilovepi commented Aug 20, 2024

I don't believe rustc has a nob for that. I've only ever seen it on linkers. It doesn't sound like there's anything we can do about it right now?

Yeah, I'm not all that surprised. But it does probably make sense to warn i they're used together to compile the same crate/module/TU. Not a problem this patch needs to solve today (I don't even think we do that in clang), but its probably nicer to do if we know its incompatible with another option.

@nnethercote
Copy link
Contributor

I don't know anything about this stuff. I do see that #128348 added two tests and added text to several .md files -- should this PR do the same?

@tmandry reviewed the other one, so I will forward the review to him:
r? tmandry

@rustbot rustbot assigned tmandry and unassigned nnethercote Aug 21, 2024
@ilovepi
Copy link
Contributor

ilovepi commented Aug 21, 2024

Actualy, I'd suggest rewriting the bulk of the shadow stack documentation to more closely align w/ what's in LLVM: https://clang.llvm.org/docs/ShadowCallStack.html#id6. Before we added RISC-V support, our docs were also very Aarch64 centric, and it seems like the Rust versions were closely following the old version. I'd also suggest that at least some of the descriptions in the fixed-x18.md be moved to a shadwow-call-stack.md file, and discuss the overall picture of SCS, rather than the vagaries of the Aarch64 ABI. Those details have a place, but have equivalents in other architectures, like RISC-V, so I think it would be best to organize them accordingly. I'm happy to help w/ that, but I'm not sure I'll have time for a PR before next week.

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Aug 22, 2024

No worries @ilovepi I can help with moving the documentation. I will put it up later and see if we have time next week to walk it through. 👍

There is a sanitizer.md under unstable-book, where other sanitizers are documented. I feel that the discussion on the overall picture of SCS is better suited over there and the section needs some expansion and especially editing. Would that sounds reasonable?

@Darksonn
Copy link
Contributor

Let's mention the target in src/doc/unstable-book/src/compiler-flags/sanitizer.md so we don't make #121966 worse. As for otherwise improving the documentation, I think it is a good idea, but I don't think it needs to block this PR.

I would be happy to commit to making sure that updating the documentation happens, but I won't have time this week or next week.

Would that work for you?

@ilovepi
Copy link
Contributor

ilovepi commented Aug 22, 2024

Agreed that the extra documentation shouldn’t be a blocker on this.

@dingxiangfei2009 @Darksonn Thanks for taking the lead on those updates 😄. Let me know if you’d like feedback, as I’m happy to help.

@rustbot rustbot added the PG-exploit-mitigations Project group: Exploit mitigations label Aug 23, 2024
@dingxiangfei2009 dingxiangfei2009 marked this pull request as ready for review August 23, 2024 18:32
@rustbot
Copy link
Collaborator

rustbot commented Aug 23, 2024

Some changes occurred in src/doc/unstable-book/src/compiler-flags/sanitizer.md

cc @rust-lang/project-exploit-mitigations, @rcvalle

These commits modify compiler targets.
(See the Target Tier Policy.)

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Aug 23, 2024

I need a bit more time to write a test. Let us move ahead and tweak the wording first.

@Darksonn
Copy link
Contributor

For the test it looks like you could just copy tests/codegen/sanitizer/aarch64-shadow-call-stack-with-fixed-x18.rs and adjust the target name. Or even rename the test to not be aarch64 specific and add it inside the file.

@rustbot
Copy link
Collaborator

rustbot commented Aug 26, 2024

Some changes occurred in tests/codegen/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

@dingxiangfei2009
Copy link
Contributor Author

@rustbot ready

  • A FileCheck test is added. I have also independently verified the generated library artifacts locally and and it looks properly instrumented. If a further testing on the efficacy of the instrumentation, I have something offline but I need a bit time to figure out how to make it play with compiletest.
  • Documentation is live but I would need to tweak the wording. Suggestions are very much welcome!

Comment on lines 779 to 782
To that end, implementation of this sanitizer requires reservation of one of the registers on the target platform.
Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section.
See the [Clang ShadowCallStack documentation][clang-scs] for more details.
Copy link
Contributor

Choose a reason for hiding this comment

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

The current phrasing makes it sound like you could reserve any register and tell the compiler. Maybe something that's a mix of the old and new version would make that less ambiguous?

Suggested change
To that end, implementation of this sanitizer requires reservation of one of the registers on the target platform.
Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section.
See the [Clang ShadowCallStack documentation][clang-scs] for more details.
The ShadowCallStack (SCS) requires that the platform reserves a register that could be used for the SCS. Aarch64 and RISC-V both have a platform register defined in their ABIs, which can optionally be reserved for this purpose (X18 and X3/GP respectively). Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section.
See the [Clang ShadowCallStack documentation][clang-scs] for more details.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied. The wording about the register reservation was indeed a bit ambiguous.

The following targets support ShadowCallStack.

* `riscv64imac-unknown-none-elf`
* `riscv64gc-unknown-none-elf`
Copy link
Contributor

Choose a reason for hiding this comment

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

you could include Fuchsia here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

Comment on lines 787 to 792
ShadowCallStack requires on this platform ABI reservation of the register `x18` as the instrumentation makes use of this register.
When `x18` is not reserved on the target AArch64 platform and is availabe as a scratch register, enabling ShadowCallStack leds to undefined behaviour.
In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
ShadowCallStack requires on this platform ABI reservation of the register `x18` as the instrumentation makes use of this register.
When `x18` is not reserved on the target AArch64 platform and is availabe as a scratch register, enabling ShadowCallStack leds to undefined behaviour.
In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value.
ShadowCallStack requires the use of the ABI defined platform register, `x18`, which is required for code generation purposes.
When `x18` is not reserved, and is instead used as a scratch register, enabling ShadowCallStack would lead to undefined behavior, due to corruption of the return addresses on the SCS or through clobbering the SCS register.
In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value.

WDYT of this phrasing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied with additional explanation on the source of UB.

#[lang = "sized"]
trait Sized {}

// CHECK: ; Function Attrs:{{.*}}shadowcallstack
Copy link
Contributor

Choose a reason for hiding this comment

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

You probably want a check line for the definition of foo and the attribute #0 to match up w/ the check below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added. Now the test is matching foo with #0 attribute.

@dingxiangfei2009
Copy link
Contributor Author

@rustbot ready

  • The documentation has received improvement on wording.
  • FileCheck is updated to match the instrumented function with its attribute node.

@nnethercote
Copy link
Contributor

@ilovepi: if you are satisfied with the latest version, then I am happy to r+ it.

@ilovepi
Copy link
Contributor

ilovepi commented Aug 29, 2024

LGTM. Depending on how complete you want the target info, Fuchsia also supports scs on Aarch64. Not a blocker in my opinion so feel free to land as is.

@nnethercote
Copy link
Contributor

LGTM. Depending on how complete you want the target info, Fuchsia also supports scs on Aarch64. Not a blocker in my opinion so feel free to land as is.

@dingxiangfei2009: I will delegate-approve this so you can make that change if you like, and then approve this yourself.

@bors delegate=dingxiangfei2009

@bors
Copy link
Contributor

bors commented Aug 29, 2024

✌️ @dingxiangfei2009, you can now approve this pull request!

If @nnethercote told you to "r=me" after making some further change, please make that change, then do @bors r=@nnethercote

@dingxiangfei2009
Copy link
Contributor Author

@ilovepi I added the AArch64 Fuchsia and went through the docs again. 🚀

@bors r=@nnethercote

@bors
Copy link
Contributor

bors commented Aug 29, 2024

📌 Commit 9c29b33 has been approved by nnethercote

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 29, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 29, 2024
…llaumeGomez

Rollup of 7 pull requests

Successful merges:

 - rust-lang#123940 (debug-fmt-detail option)
 - rust-lang#128166 (Improved `checked_isqrt` and `isqrt` methods)
 - rust-lang#128970 (Add `-Zlint-llvm-ir`)
 - rust-lang#129316 (riscv64imac: allow shadow call stack sanitizer)
 - rust-lang#129690 (Add `needs-unwind` compiletest directive to `libtest-thread-limit` and replace some `Path` with `path` in `run-make`)
 - rust-lang#129732 (Add `unreachable_pub`, round 3)
 - rust-lang#129743 (Fix rustdoc clippy lints)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 29, 2024
…llaumeGomez

Rollup of 7 pull requests

Successful merges:

 - rust-lang#123940 (debug-fmt-detail option)
 - rust-lang#128166 (Improved `checked_isqrt` and `isqrt` methods)
 - rust-lang#128970 (Add `-Zlint-llvm-ir`)
 - rust-lang#129316 (riscv64imac: allow shadow call stack sanitizer)
 - rust-lang#129690 (Add `needs-unwind` compiletest directive to `libtest-thread-limit` and replace some `Path` with `path` in `run-make`)
 - rust-lang#129732 (Add `unreachable_pub`, round 3)
 - rust-lang#129743 (Fix rustdoc clippy lints)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit a65404a into rust-lang:master Aug 29, 2024
6 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 29, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 29, 2024
Rollup merge of rust-lang#129316 - dingxiangfei2009:riscv64-imac-scs, r=nnethercote

riscv64imac: allow shadow call stack sanitizer

cc `@Darksonn` for shadow call stack sanitizer support on RV64IMAC and RV64GC
@dingxiangfei2009 dingxiangfei2009 deleted the riscv64-imac-scs branch August 31, 2024 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants