@@ -76,6 +76,75 @@ to introduce the mitigations to the entire program.
76
76
[ `-Z stack-protector` ] : https://github.com/rust-lang/rust/issues/114903
77
77
[ 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
78
78
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
+
79
148
# Guide-level explanation
80
149
[ guide-level-explanation ] : #guide-level-explanation
81
150
@@ -109,23 +178,23 @@ When compiling a crate, if the current crate has a mitigation with enforcement
109
178
turned on, and one of the dependencies does not have that mitigation turned
110
179
on (whether enforcing or not), a compilation error results.
111
180
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.
114
183
115
184
The error happens independent of the target crate type (you get an error
116
185
if you are building an rlib, not just the final executable).
117
186
118
187
For example, with ` -C stack-protector ` , the compatibility table will be
119
188
as follows:
120
189
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 |
129
198
130
199
If a program has multiple flags of the same kind, the last flag wins, so e.g.
131
200
` -C stack-protector=strong-noenforce -C stack-protector=strong ` is the same as
0 commit comments