Skip to content

Commit badc6b0

Browse files
author
Ariel Ben-Yehuda
committed
address review comments
1 parent 1305c42 commit badc6b0

File tree

1 file changed

+79
-10
lines changed

1 file changed

+79
-10
lines changed

text/3855-mitigation-enforcement.md

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,75 @@ to introduce the mitigations to the entire program.
7676
[`-Z stack-protector`]: https://github.com/rust-lang/rust/issues/114903
7777
[example by Alice Ryhl]: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Target.20modifiers.20and.20-Cunsafe-allow-abi-mismatch/near/483871803
7878

79+
## Supported mitigations
80+
81+
The following mitigations could find this feature interesting
82+
83+
### Already Stable
84+
85+
1. `-C control-flow-guard`
86+
This is a "CFI-type" mitigation on Windows, and therefore having it enabled
87+
only partially makes it far less protective.
88+
89+
However, it is already stable, and we would need a `-C control-flow-guard-enforce`
90+
or `-C deny-partial-mitigations=control-flow-guard` (or bikeshed) to make
91+
it enforcing.
92+
2. `-C relocation-model`
93+
If position-dependent code is compiled into a binary, then ASLR will
94+
not be able to be enabled.
95+
96+
This is less of a problem in Rust than in C, since position-independent
97+
code is a rarely-changed default in Rust, and it can easily be checked
98+
via [`hardening-check(1)`] or similar tools since it's easily visible
99+
in the ELF header.
100+
101+
However, we might still want to introduce a `-C enforce-position-independent` or
102+
`-C deny-partial-mitigations=position-independent`.
103+
104+
As far as I can tell, there is no way to disable `relro` via stable Rust
105+
compilation flags.
106+
107+
### Currently Unstable (as of rustc 1.89)
108+
109+
This RFC is not the place to make a decision of exactly which unstable mitigations
110+
should have enforcement enabled - that should take place as a part of their
111+
stabilization.
112+
113+
However, it would be good to see that enforcement fits well with sanitizers.
114+
115+
1. [`-Z branch-protection`]/[`-Z cf-protection`] - control flow
116+
protection in ARM or Intel, respectively. Would probably want this.
117+
It uses [`.note.gnu.property`](#notegnuproperty-1) which makes it active only
118+
if every object in the address space uses it, which makes it easy to detect via a
119+
[`hardening-check(1)`]-style tool, but since it is not the default, this
120+
would make it easier to make sure it is enabled.
121+
2. `-Z ehcont-guard` - I couldn't find documentation of that (Windows) feature,
122+
but it looks relevant.
123+
2. [`-Z indirect-branch-cs-prefix`] - a part of retpoline (Spectre)
124+
mitigation on x86.
125+
3. [`-Z no-jump-tables`] - CFI-type mitigation?
126+
soon to be stabilized as [`-C jump-tables`]. Do we want to hold that
127+
stabilization as well?
128+
3. [`-Z retpoline`] and `-Z retpoline-external-thunk` - Spectre-type mitigation
129+
4. [`-Z sanitizer`]-based mitigations. A fairly large use case.
130+
As far as I can tell, enforcement makes sense for
131+
`-Zsanitizer=cfi, -Zsanitizer=memtag, -Zsanitizer=shadow-call-stack`
132+
and does not make sense for
133+
`-Zsanitizer=address, -Zsanitizer=dataflow, -Zsanitizer=hwaddress, -Zsanitizer=leak, -Zsanitizer=memory, -Zsanitizer=thread`
134+
4. [`-Z stack-protector`] - stack smashing protection, local-type mitigation
135+
5. [`-Z ub-checks`]: as far as I can tell, it is not intended as a mitigation,
136+
but since it prevents some UB, it might be thought of as one
137+
138+
[`-Z branch-protection`]: https://github.com/rust-lang/rust/issues/113369
139+
[`-Z cf-protection`]: https://github.com/rust-lang/rust/issues/93754
140+
[`-Z indirect-branch-cs-prefix`]: https://github.com/rust-lang/rust/issues/116852
141+
[`-Z no-jump-tables`]: https://github.com/rust-lang/rust/issues/116592
142+
[`-C jump-tables`]: https://github.com/rust-lang/rust/pull/145974
143+
[`-Z retpoline`]: https://github.com/rust-lang/rust/issues/116852
144+
[`-Z sanitizer`]: https://github.com/rust-lang/rust/issues/89653
145+
[`-Z stack-protector`]: https://github.com/rust-lang/rust/issues/114903
146+
[`-Z ub-checks`]: https://github.com/rust-lang/rust/issues/123499
147+
79148
# Guide-level explanation
80149
[guide-level-explanation]: #guide-level-explanation
81150

@@ -109,23 +178,23 @@ When compiling a crate, if the current crate has a mitigation with enforcement
109178
turned on, and one of the dependencies does not have that mitigation turned
110179
on (whether enforcing or not), a compilation error results.
111180

112-
If a mitigation has multiple "levels", a lower level at a child crate is compatible
113-
with a higher level at a base crate.
181+
If a mitigation has multiple "levels", a lower level at a dependent
182+
crate is compatible with a higher level at a base crate.
114183

115184
The error happens independent of the target crate type (you get an error
116185
if you are building an rlib, not just the final executable).
117186

118187
For example, with `-C stack-protector`, the compatibility table will be
119188
as follows:
120189

121-
| Base\Child | none | none-noenforce | strong | strong-noenforce | all | all-noenforce |
122-
| ---------------- | ---- | -------------- | ------ | -------------------- | ----- | -------------------- |
123-
| none | OK | OK | error | OK - child noenforce | error | OK - child noenforce |
124-
| none-noenforce | OK | OK | error | OK - child noenforce | error | OK - child noenforce |
125-
| strong | OK | OK | OK | OK | error | OK - child noenforce |
126-
| strong-noenforce | OK | OK | OK | OK | error | OK - child noenforce |
127-
| all | OK | OK | OK | OK | OK | OK |
128-
| all-noenforce | OK | OK | OK | OK | OK | OK |
190+
| Base\Dependent | none | none-noenforce | strong | strong-noenforce | all | all-noenforce |
191+
| ---------------- | ---- | -------------- | ------ | ------------------------ | ----- | -------------------- |
192+
| none | OK | OK | error | OK - dependent noenforce | error | OK - dependent noenforce |
193+
| none-noenforce | OK | OK | error | OK - dependent noenforce | error | OK - dependent noenforce |
194+
| strong | OK | OK | OK | OK | error | OK - dependent noenforce |
195+
| strong-noenforce | OK | OK | OK | OK | error | OK - dependent noenforce |
196+
| all | OK | OK | OK | OK | OK | OK |
197+
| all-noenforce | OK | OK | OK | OK | OK | OK |
129198

130199
If a program has multiple flags of the same kind, the last flag wins, so e.g.
131200
`-C stack-protector=strong-noenforce -C stack-protector=strong` is the same as

0 commit comments

Comments
 (0)