]> git.lizzy.rs Git - rust.git/blob - src/doc/rustc/src/exploit-mitigations.md
Auto merge of #105919 - uweigand:s390x-stack-overflow, r=Nilstrieb
[rust.git] / src / doc / rustc / src / exploit-mitigations.md
1 # Exploit Mitigations
2
3 This chapter documents the exploit mitigations supported by the Rust
4 compiler, and is by no means an extensive survey of the Rust programming
5 language’s security features.
6
7 This chapter is for software engineers working with the Rust programming
8 language, and assumes prior knowledge of the Rust programming language and
9 its toolchain.
10
11
12 ## Introduction
13
14 The Rust programming language provides memory[1] and thread[2] safety
15 guarantees via its ownership[3], references and borrowing[4], and slice
16 types[5] features. However, Unsafe Rust[6] introduces unsafe blocks, unsafe
17 functions and methods, unsafe traits, and new types that are not subject to
18 the borrowing rules.
19
20 Parts of the Rust standard library are implemented as safe abstractions over
21 unsafe code (and historically have been vulnerable to memory corruption[7]).
22 Furthermore, the Rust code and documentation encourage creating safe
23 abstractions over unsafe code. This can cause a false sense of security if
24 unsafe code is not properly reviewed and tested.
25
26 Unsafe Rust introduces features that do not provide the same memory and
27 thread safety guarantees. This causes programs or libraries to be
28 susceptible to memory corruption (CWE-119)[8] and concurrency issues
29 (CWE-557)[9]. Modern C and C++ compilers provide exploit mitigations to
30 increase the difficulty to exploit vulnerabilities resulting from these
31 issues. Therefore, the Rust compiler must also support these exploit
32 mitigations in order to mitigate vulnerabilities resulting from the use of
33 Unsafe Rust. This chapter documents these exploit mitigations and how they
34 apply to Rust.
35
36 This chapter does not discuss the effectiveness of these exploit mitigations
37 as they vary greatly depending on several factors besides their design and
38 implementation, but rather describe what they do, so their effectiveness can
39 be understood within a given context.
40
41
42 ## Exploit mitigations
43
44 This section documents the exploit mitigations applicable to the Rust
45 compiler when building programs for the Linux operating system on the AMD64
46 architecture and equivalent.<sup id="fnref:1" role="doc-noteref"><a
47 href="#fn:1" class="footnote">1</a></sup>
48
49 The Rust Programming Language currently has no specification. The Rust
50 compiler (i.e., rustc) is the language reference implementation. All
51 references to “the Rust compiler” in this chapter refer to the language
52 reference implementation.
53
54 Table I \
55 Summary of exploit mitigations supported by the Rust compiler when building
56 programs for the Linux operating system on the AMD64 architecture and
57 equivalent.
58 <table class="table">
59   <tr>
60    <td><strong>Exploit mitigation</strong>
61    </td>
62    <td><strong>Supported and enabled by default</strong>
63    </td>
64    <td><strong>Since</strong>
65    </td>
66   </tr>
67   <tr>
68    <td>Position-independent executable
69    </td>
70    <td>Yes
71    </td>
72    <td>0.12.0 (2014-10-09)
73    </td>
74   </tr>
75   <tr>
76    <td>Integer overflow checks
77    </td>
78    <td>Yes (enabled when debug assertions are enabled, and disabled when debug assertions are disabled)
79    </td>
80    <td>1.1.0 (2015-06-25)
81    </td>
82   </tr>
83   <tr>
84    <td>Non-executable memory regions
85    </td>
86    <td>Yes
87    </td>
88    <td>1.8.0 (2016-04-14)
89    </td>
90   </tr>
91   <tr>
92    <td>Stack clashing protection
93    </td>
94    <td>Yes
95    </td>
96    <td>1.20.0 (2017-08-31)
97    </td>
98   </tr>
99   <tr>
100    <td>Read-only relocations and immediate binding
101    </td>
102    <td>Yes
103    </td>
104    <td>1.21.0 (2017-10-12)
105    </td>
106   </tr>
107   <tr>
108    <td>Heap corruption protection
109    </td>
110    <td>Yes
111    </td>
112    <td>1.32.0 (2019-01-17) (via operating system default or specified allocator)
113    </td>
114   </tr>
115   <tr>
116    <td>Stack smashing protection
117    </td>
118    <td>No
119    </td>
120    <td>
121    </td>
122   </tr>
123   <tr>
124    <td>Forward-edge control flow protection
125    </td>
126    <td>Yes
127    </td>
128    <td>Nightly
129    </td>
130   </tr>
131   <tr>
132    <td>Backward-edge control flow protection (e.g., shadow and safe stack)
133    </td>
134    <td>No
135    </td>
136    <td>
137    </td>
138   </tr>
139 </table>
140
141 <small id="fn:1">1\. See
142 <https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec>
143 for a list of targets and their default options. <a href="#fnref:1"
144 class="reversefootnote" role="doc-backlink">↩</a></small>
145
146
147 ### Position-independent executable
148
149 Position-independent executable increases the difficulty of the use of code
150 reuse exploitation techniques, such as return-oriented programming (ROP) and
151 variants, by generating position-independent code for the executable, and
152 instructing the dynamic linker to load it similarly to a shared object at a
153 random load address, thus also benefiting from address-space layout
154 randomization (ASLR). This is also referred to as “full ASLR”.
155
156 The Rust compiler supports position-independent executable, and enables it
157 by default since version 0.12.0 (2014-10-09)[10]–[13].
158
159 ```text
160 $ readelf -h target/release/hello-rust | grep Type:
161   Type:                              DYN (Shared object file)
162 ```
163 Fig. 1. Checking if an executable is a position-independent executable.
164
165 An executable with an object type of `ET_DYN` (i.e., shared object) and not
166 `ET_EXEC` (i.e., executable) is a position-independent executable (see Fig.
167 1).
168
169
170 ### Integer overflow checks
171
172 Integer overflow checks protects programs from undefined and unintended
173 behavior (which may cause vulnerabilities) by checking for results of signed
174 and unsigned integer computations that cannot be represented in their type,
175 resulting in an overflow or wraparound.
176
177 The Rust compiler supports integer overflow checks, and enables it when
178 debug assertions are enabled since version 1.1.0 (2015-06-25)[14]–[20].
179
180 ```compile_fail
181 fn main() {
182     let u: u8 = 255;
183     println!("u: {}", u + 1);
184 }
185 ```
186 Fig. 2. hello-rust-integer program.
187
188 ```text
189 $ cargo run
190    Compiling hello-rust-integer v0.1.0 (/home/rcvalle/hello-rust-integer)
191     Finished dev [unoptimized + debuginfo] target(s) in 0.23s
192      Running `target/debug/hello-rust-integer`
193 thread 'main' panicked at 'attempt to add with overflow', src/main.rs:3:23
194 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
195 ```
196 Fig. 3. Build and execution of hello-rust-integer with debug assertions
197 enabled.
198
199 ```text
200 $ cargo run --release
201    Compiling hello-rust-integer v0.1.0 (/home/rcvalle/hello-rust-integer)
202     Finished release [optimized] target(s) in 0.23s
203      Running `target/release/hello-rust-integer`
204 u: 0
205 ```
206 Fig. 4. Build and execution of hello-rust-integer with debug assertions
207 disabled.
208
209 Integer overflow checks are enabled when debug assertions are enabled (see
210 Fig. 3), and disabled when debug assertions are disabled (see Fig. 4). To
211 enable integer overflow checks independently, use the option to control
212 integer overflow checks, scoped attributes, or explicit checking methods
213 such as `checked_add`<sup id="fnref:2" role="doc-noteref"><a href="#fn:2"
214 class="footnote">2</a></sup>.
215
216 It is recommended that explicit wrapping methods such as `wrapping_add` be
217 used when wrapping semantics are intended, and that explicit checking and
218 wrapping methods always be used when using Unsafe Rust.
219
220 <small id="fn:2">2\. See [the `u32` docs](../std/primitive.u32.html)
221 for more information on the checked, overflowing, saturating, and wrapping
222 methods (using u32 as an example). <a href="#fnref:2"
223 class="reversefootnote" role="doc-backlink">↩</a></small>
224
225
226 ### Non-executable memory regions
227
228 Non-executable memory regions increase the difficulty of exploitation by
229 limiting the memory regions that can be used to execute arbitrary code. Most
230 modern processors provide support for the operating system to mark memory
231 regions as non executable, but it was previously emulated by software, such
232 as in grsecurity/PaX's
233 [PAGEEXEC](https://pax.grsecurity.net/docs/pageexec.txt) and
234 [SEGMEXEC](https://pax.grsecurity.net/docs/segmexec.txt), on processors that
235 did not provide support for it. This is also known as “No Execute (NX) Bit”,
236 “Execute Disable (XD) Bit”, “Execute Never (XN) Bit”, and others.
237
238 The Rust compiler supports non-executable memory regions, and enables it by
239 default since its initial release, version 0.1 (2012-01-20)[21], [22], but
240 has regressed since then[23]–[25], and enforced by default since version
241 1.8.0 (2016-04-14)[25].
242
243 ```text
244 $ readelf -l target/release/hello-rust | grep -A 1 GNU_STACK
245   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
246                  0x0000000000000000 0x0000000000000000  RW     0x10
247 ```
248 Fig. 5. Checking if non-executable memory regions are enabled for a given
249 binary.
250
251 The presence of an element of type `PT_GNU_STACK` in the program header
252 table with the `PF_X` (i.e., executable) flag unset indicates non-executable
253 memory regions<sup id="fnref:3" role="doc-noteref"><a href="#fn:3"
254 class="footnote">3</a></sup> are enabled for a given binary (see Fig. 5).
255 Conversely, the presence of an element of type `PT_GNU_STACK` in the program
256 header table with the `PF_X` flag set or the absence of an element of type
257 `PT_GNU_STACK` in the program header table indicates non-executable memory
258 regions are not enabled for a given binary.
259
260 <small id="fn:3">3\. See the Appendix section for more information on why it
261 affects other memory regions besides the stack. <a href="#fnref:3"
262 class="reversefootnote" role="doc-backlink">↩</a></small>
263
264
265 ### Stack clashing protection
266
267 Stack clashing protection protects the stack from overlapping with another
268 memory region—allowing arbitrary data in both to be overwritten using each
269 other—by reading from the stack pages as the stack grows to cause a page
270 fault when attempting to read from the guard page/region. This is also
271 referred to as “stack probes” or “stack probing”.
272
273 The Rust compiler supports stack clashing protection via stack probing, and
274 enables it by default since version 1.20.0 (2017-08-31)[26]–[29].
275
276 ![Screenshot of IDA Pro listing cross references to __rust_probestack in hello-rust.](images/image1.png "Cross references to __rust_probestack in hello-rust.")
277 Fig. 6. IDA Pro listing cross references to `__rust_probestack` in
278 hello-rust.
279
280 ```rust
281 fn hello() {
282     println!("Hello, world!");
283 }
284
285 fn main() {
286     let _: [u64; 1024] = [0; 1024];
287     hello();
288 }
289 ```
290 Fig 7. Modified hello-rust.
291
292 ![Screenshot of IDA Pro listing cross references to __rust_probestack in modified hello-rust.](images/image2.png "Cross references to __rust_probestack in modified hello-rust.")
293 Fig. 8. IDA Pro listing cross references to `__rust_probestack` in modified
294 hello-rust.
295
296 To check if stack clashing protection is enabled for a given binary, search
297 for cross references to `__rust_probestack`. The `__rust_probestack` is
298 called in the prologue of functions whose stack size is larger than a page
299 size (see Fig. 6), and can be forced for illustration purposes by modifying
300 the hello-rust example as seen in Fig. 7 and Fig. 8.
301
302
303 ### Read-only relocations and immediate binding
304
305 **Read-only relocations** protect segments containing relocations and
306 relocation information (i.e., `.init_array`, `.fini_array`, `.dynamic`, and
307 `.got`) from being overwritten by marking these segments read only. This is
308 also referred to as “partial RELRO”.
309
310 The Rust compiler supports read-only relocations, and enables it by default
311 since version 1.21.0 (2017-10-12)[30], [31].
312
313 ```text
314 $ readelf -l target/release/hello-rust | grep GNU_RELRO
315   GNU_RELRO      0x000000000002ee00 0x000000000002fe00 0x000000000002fe00
316 ```
317 Fig. 9. Checking if read-only relocations is enabled for a given binary.
318
319 The presence of an element of type `PT_GNU_RELRO` in the program header
320 table indicates read-only relocations are enabled for a given binary (see
321 Fig. 9). Conversely, the absence of an element of type `PT_GNU_RELRO` in the
322 program header table indicates read-only relocations are not enabled for a
323 given binary.
324
325 **Immediate binding** protects additional segments containing relocations
326 (i.e., `.got.plt`) from being overwritten by instructing the dynamic linker
327 to perform all relocations before transferring control to the program during
328 startup, so all segments containing relocations can be marked read only
329 (when combined with read-only relocations). This is also referred to as
330 “full RELRO”.
331
332 The Rust compiler supports immediate binding, and enables it by default
333 since version 1.21.0 (2017-10-12)[30], [31].
334
335 ```text
336 $ readelf -d target/release/hello-rust | grep BIND_NOW
337  0x000000000000001e (FLAGS)              BIND_NOW
338 ```
339 Fig. 10. Checking if immediate binding is enabled for a given binary.
340
341 The presence of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW`
342 flag<sup id="fnref:4" role="doc-noteref"><a href="#fn:4"
343 class="footnote">4</a></sup> in the dynamic section indicates immediate
344 binding is enabled for a given binary (see Fig. 10). Conversely, the absence
345 of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag in the
346 dynamic section indicates immediate binding is not enabled for a given
347 binary.
348
349 The presence of both an element of type `PT_GNU_RELRO` in the program header
350 table and of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW`
351 flag in the dynamic section indicates full RELRO is enabled for a given
352 binary (see Fig. 9 and Fig. 10).
353
354 <small id="fn:4">4\. And the `DF_1_NOW` flag for some link editors. <a
355 href="#fnref:4" class="reversefootnote" role="doc-backlink">↩</a></small>
356
357
358 ### Heap corruption protection
359
360 Heap corruption protection protects memory allocated dynamically by
361 performing several checks, such as checks for corrupted links between list
362 elements, invalid pointers, invalid sizes, double/multiple “frees” of the
363 same memory allocated, and many corner cases of these. These checks are
364 implementation specific, and vary per allocator.
365
366 [ARM Memory Tagging Extension
367 (MTE)](https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/enhancing-memory-safety),
368 when available, will provide hardware assistance for a probabilistic
369 mitigation to detect memory safety violations by tagging memory allocations,
370 and automatically checking that the correct tag is used on every memory
371 access.
372
373 Rust’s default allocator has historically been
374 [jemalloc](http://jemalloc.net/), and it has long been the cause of issues
375 and the subject of much discussion[32]–[38]. Consequently, it has been
376 removed as the default allocator in favor of the operating system’s standard
377 C library default allocator<sup id="fnref:5" role="doc-noteref"><a
378 href="#fn:5" class="footnote">5</a></sup> since version 1.32.0
379 (2019-01-17)[39].
380
381 ```rust,no_run
382 fn main() {
383     let mut x = Box::new([0; 1024]);
384
385     for i in 0..1026 {
386         unsafe {
387             let elem = x.get_unchecked_mut(i);
388             *elem = 0x4141414141414141u64;
389         }
390     }
391 }
392 ```
393 Fig. 11. hello-rust-heap program.
394
395 ```text
396 $ cargo run
397    Compiling hello-rust-heap v0.1.0 (/home/rcvalle/hello-rust-heap)
398     Finished dev [unoptimized + debuginfo] target(s) in 0.25s
399      Running `target/debug/hello-rust-heap`
400 free(): invalid next size (normal)
401 Aborted
402 ```
403 Fig. 12. Build and execution of hello-rust-heap with debug assertions
404 enabled.
405
406 ```text
407 $ cargo run --release
408    Compiling hello-rust-heap v0.1.0 (/home/rcvalle/hello-rust-heap)
409     Finished release [optimized] target(s) in 0.25s
410      Running `target/release/hello-rust-heap`
411 free(): invalid next size (normal)
412 Aborted
413 ```
414 Fig. 13. Build and execution of hello-rust-heap with debug assertions
415 disabled.
416
417 Heap corruption checks are being performed when using the default allocator
418 (i.e., the GNU Allocator) as seen in Fig. 12 and Fig. 13.
419
420 <small id="fn:5">5\. Linux's standard C library default allocator is the GNU
421 Allocator, which is derived from ptmalloc (pthreads malloc) by Wolfram
422 Gloger, which in turn is derived from dlmalloc (Doug Lea malloc) by Doug
423 Lea. <a href="#fnref:5" class="reversefootnote"
424 role="doc-backlink">↩</a></small>
425
426
427 ### Stack smashing protection
428
429 Stack smashing protection protects programs from stack-based buffer
430 overflows by inserting a random guard value between local variables and the
431 saved return instruction pointer, and checking if this value has changed
432 when returning from a function. This is also known as “Stack Protector” or
433 “Stack Smashing Protector (SSP)”.
434
435 The Rust compiler does not support stack smashing protection. However, more
436 comprehensive alternatives to stack smashing protection exist, such as
437 shadow and safe stack (see backward-edge control flow protection).
438
439 ![Screenshot of IDA Pro listing cross references to __stack_chk_fail in hello-rust.](images/image3.png "Cross references to __stack_chk_fail in hello-rust.")
440 Fig. 14. IDA Pro listing cross references to `__stack_chk_fail` in
441 hello-rust.
442
443 To check if stack smashing protection is enabled for a given binary, search
444 for cross references to `__stack_chk_fail`. The only cross references to
445 `__stack_chk_fail` in hello-rust are from the statically-linked libbacktrace
446 library (see Fig. 14).
447
448
449 ### Forward-edge control flow protection
450
451 Forward-edge control flow protection protects programs from having its
452 control flow changed/hijacked by performing checks to ensure that
453 destinations of indirect branches are one of their valid destinations in the
454 control flow graph. The comprehensiveness of these checks vary per
455 implementation. This is also known as “forward-edge control flow integrity
456 (CFI)”.
457
458 Newer processors provide hardware assistance for forward-edge control flow
459 protection, such as ARM Branch Target Identification (BTI), ARM Pointer
460 Authentication, and Intel Indirect Branch Tracking (IBT) as part of Intel
461 Control-flow Enforcement Technology (CET). However, ARM BTI and Intel IBT
462 -based implementations are less comprehensive than software-based
463 implementations such as [LLVM ControlFlowIntegrity
464 (CFI)](https://clang.llvm.org/docs/ControlFlowIntegrity.html), and the
465 commercially available [grsecurity/PaX Reuse Attack Protector
466 (RAP)](https://grsecurity.net/rap_faq).
467
468 The Rust compiler supports forward-edge control flow protection on nightly
469 builds[40]-[41] <sup id="fnref:6" role="doc-noteref"><a href="#fn:6"
470 class="footnote">6</a></sup>.
471
472 ```text
473 $ readelf -s -W target/debug/rust-cfi | grep "\.cfi"
474     12: 0000000000005170    46 FUNC    LOCAL  DEFAULT   14 _RNvCsjaOHoaNjor6_8rust_cfi7add_one.cfi
475     15: 00000000000051a0    16 FUNC    LOCAL  DEFAULT   14 _RNvCsjaOHoaNjor6_8rust_cfi7add_two.cfi
476     17: 0000000000005270   396 FUNC    LOCAL  DEFAULT   14 _RNvCsjaOHoaNjor6_8rust_cfi4main.cfi
477 ...
478 ```
479 Fig. 15. Checking if LLVM CFI is enabled for a given binary[41].
480
481 The presence of symbols suffixed with ".cfi" or the `__cfi_init` symbol (and
482 references to `__cfi_check`) indicates that LLVM CFI (i.e., forward-edge control
483 flow protection) is enabled for a given binary. Conversely, the absence of
484 symbols suffixed with ".cfi" or the `__cfi_init` symbol (and references to
485 `__cfi_check`) indicates that LLVM CFI is not enabled for a given binary (see
486 Fig. 15).
487
488 <small id="fn:6">6\. It also supports Control Flow Guard (CFG) on Windows (see
489 <https://github.com/rust-lang/rust/issues/68793>). <a href="#fnref:6"
490 class="reversefootnote" role="doc-backlink">↩</a></small>
491
492
493 ### Backward-edge control flow protection
494
495 **Shadow stack** protects saved return instruction pointers from being
496 overwritten by storing a copy of them on a separate (shadow) stack, and
497 using these copies as authoritative values when returning from functions.
498 This is also known as “ShadowCallStack” and “Return Flow Guard”, and is
499 considered an implementation of backward-edge control flow protection (or
500 “backward-edge CFI”).
501
502 **Safe stack** protects not only the saved return instruction pointers, but
503 also register spills and some local variables from being overwritten by
504 storing unsafe variables, such as large arrays, on a separate (unsafe)
505 stack, and using these unsafe variables on the separate stack instead. This
506 is also known as “SafeStack”, and is also considered an implementation of
507 backward-edge control flow protection.
508
509 Both shadow and safe stack are intended to be a more comprehensive
510 alternatives to stack smashing protection as they protect the saved return
511 instruction pointers (and other data in the case of safe stack) from
512 arbitrary writes and non-linear out-of-bounds writes.
513
514 Newer processors provide hardware assistance for backward-edge control flow
515 protection, such as ARM Pointer Authentication, and Intel Shadow Stack as
516 part of Intel CET.
517
518 The Rust compiler does not support shadow or safe stack. There is work
519 currently ongoing to add support for the sanitizers[40], which may or may
520 not include support for safe stack<sup id="fnref:7" role="doc-noteref"><a
521 href="#fn:7" class="footnote">7</a></sup>.
522
523 ```text
524 $ readelf -s target/release/hello-rust | grep __safestack_init
525 ```
526 Fig. 16. Checking if LLVM SafeStack is enabled for a given binary.
527
528 The presence of the `__safestack_init` symbol indicates that LLVM SafeStack
529 is enabled for a given binary. Conversely, the absence of the
530 `__safestack_init` symbol indicates that LLVM SafeStack is not enabled for a
531 given binary (see Fig. 16).
532
533 <small id="fn:7">7\. The shadow stack implementation for the AMD64
534 architecture and equivalent in LLVM was removed due to performance and
535 security issues. <a href="#fnref:7" class="reversefootnote"
536 role="doc-backlink">↩</a></small>
537
538
539 ## Appendix
540
541 As of the latest version of the [Linux Standard Base (LSB) Core
542 Specification](https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/progheader.html),
543 the `PT_GNU_STACK` program header indicates whether the stack should be
544 executable, and the absence of this header indicates that the stack should
545 be executable. However, the Linux kernel currently sets the
546 `READ_IMPLIES_EXEC` personality upon loading any executable with the
547 `PT_GNU_STACK` program header and the `PF_X `flag set or with the absence of
548 this header, resulting in not only the stack, but also all readable virtual
549 memory mappings being executable.
550
551 An attempt to fix this [was made in
552 2012](https://lore.kernel.org/lkml/f298f914-2239-44e4-8aa1-a51282e7fac0@zmail15.collab.prod.int.phx2.redhat.com/),
553 and another [was made in
554 2020](https://lore.kernel.org/kernel-hardening/20200327064820.12602-1-keescook@chromium.org/).
555 The former never landed, and the latter partially fixed it, but introduced
556 other issues—the absence of the `PT_GNU_STACK` program header still causes
557 not only the stack, but also all readable virtual memory mappings to be
558 executable in some architectures, such as IA-32 and equivalent (or causes
559 the stack to be non-executable in some architectures, such as AMD64 and
560 equivalent, contradicting the LSB).
561
562 The `READ_IMPLIES_EXEC` personality needs to be completely separated from
563 the `PT_GNU_STACK` program header by having a separate option for it (or
564 setarch -X could just be used whenever `READ_IMPLIES_EXEC` is needed), and
565 the absence of the `PT_GNU_STACK` program header needs to have more secure
566 defaults (unrelated to `READ_IMPLIES_EXEC`).
567
568
569 ## References
570
571 1. D. Hosfelt. “Fearless security: memory safety.” Mozilla Hacks.
572    <https://hacks.mozilla.org/2019/01/fearless-security-memory-safety/>.
573
574 2. D. Hosfelt. “Fearless security: thread safety.” Mozilla Hacks.
575    <https://hacks.mozilla.org/2019/02/fearless-security-thread-safety/>.
576
577 3. S. Klabnik and C. Nichols. “What Is Ownership?.” The Rust Programming
578    Language. [https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html](../book/ch04-01-what-is-ownership.html).
579
580 4. S. Klabnik and C. Nichols. “References and Borrowing.” The Rust
581    Programming Language.
582    [https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html](../book/ch04-02-references-and-borrowing.html).
583
584 5. S. Klabnik and C. Nichols. “The Slice Type.” The Rust Programming
585    Language. [https://doc.rust-lang.org/book/ch04-03-slices.html](../book/ch04-03-slices.html).
586
587 6. S. Klabnik and C. Nichols. “Unsafe Rust.” The Rust Programming Language.
588    [https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html](../book/ch19-01-unsafe-rust.html).
589
590 7. S. Davidoff. “How Rust’s standard library was vulnerable for years and
591    nobody noticed.” Medium.
592    <https://medium.com/@shnatsel/how-rusts-standard-library-was-vulnerable-for-years-and-nobody-noticed-aebf0503c3d6>.
593
594 8. “Improper restriction of operations within the bounds of a memory buffer
595    (CWE-119).” MITRE CWE List.
596    <https://cwe.mitre.org/data/definitions/119.html>.
597
598 9. “Concurrency issues (CWE-557).” MITRE CWE List.
599    <https://cwe.mitre.org/data/definitions/557.html>.
600
601 10. K. McAllister. “Memory exploit mitigations #15179.” GitHub.
602     <https://github.com/rust-lang/rust/issues/15179>.
603
604 11. K. McAllister. “RFC: Memory exploit mitigation #145.” GitHub.
605     <https://github.com/rust-lang/rfcs/pull/145>.
606
607 12. K. McAllister. “RFC: Memory exploit mitigation.” GitHub.
608     <https://github.com/kmcallister/rfcs/blob/hardening/active/0000-memory-exploit-mitigation.md>.
609
610 13. D. Micay. “Enable PIE by default on Linux for full ASLR #16340.” GitHub.
611     <https://github.com/rust-lang/rust/pull/16340>.
612
613 14. N. Matsakis. “Integer overflow #560.” GitHub.
614     <https://github.com/rust-lang/rfcs/pull/560>.
615
616 15. G. Lehel and N. Matsakis. “Integer overflow.” GitHub.
617     <https://rust-lang.github.io/rfcs/0560-integer-overflow.html>.
618
619 16. A. Turon. “Tracking issue for integer overflow (RFC 560) #22020.”
620     GitHub. <https://github.com/rust-lang/rust/issues/22020>.
621
622 17. H. Wilson. “Myths and legends about integer overflow in Rust.” Huon on
623     the Internet.
624     <http://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/>.
625
626 18. B. Anderson. “Stabilize -C overflow-checks #1535.” GitHub.
627     <https://github.com/rust-lang/rfcs/pull/1535>.
628
629 19. B. Anderson. “Stable overflow checks.” GitHub.
630     <https://github.com/brson/rfcs/blob/overflow/text/0000-stable-overflow-checks.md>.
631
632 20. N. Froyd. “Add -C overflow-checks option #40037.” GitHub.
633     <https://github.com/rust-lang/rust/pull/40037>.
634
635 21. R. Á. de Espíndola. “rustc requires executable stack #798.” GitHub.
636     <https://github.com/rust-lang/rust/issues/798>.
637
638 22. A. Seipp. “Make sure librustrt.so is linked with a non-executable stack.
639     #1066.” GitHub. <https://github.com/rust-lang/rust/pull/1066>.
640
641 23. D. Micay. “Rust binaries should not have an executable stack #5643.”
642     GitHub. <https://github.com/rust-lang/rust/issues/5643>.
643
644 24. D. Micay. “Mark the assembly object stacks as non-executable #5647.”
645     GitHub. <https://github.com/rust-lang/rust/pull/5647>.
646
647 25. A. Clark. “Explicitly disable stack execution on linux and bsd #30859.”
648     GitHub. <https://github.com/rust-lang/rust/pull/30859>.
649
650 26. “Replace stack overflow checking with stack probes #16012.” GitHub.
651     <https://github.com/rust-lang/rust/issues/16012>.
652
653 27. B. Striegel. “Extend stack probe support to non-tier-1 platforms, and
654     clarify policy for mitigating LLVM-dependent unsafety #43241.” GitHub.
655     <https://github.com/rust-lang/rust/issues/43241>.
656
657 28. A. Crichton. “rustc: Implement stack probes for x86 #42816.” GitHub.
658     <https://github.com/rust-lang/rust/pull/42816>.
659
660 29. A. Crichton. “Add \_\_rust\_probestack intrinsic #175.” GitHub.
661     <https://github.com/rust-lang/compiler-builtins/pull/175>.
662
663 30. B. Anderson. “Consider applying -Wl,-z,relro or -Wl,-z,relro,-z,now by
664     default #29877.” GitHub. <https://github.com/rust-lang/rust/issues/29877>.
665
666 31. J. Löthberg. “Add support for full RELRO #43170.” GitHub.
667     <https://github.com/rust-lang/rust/pull/43170>.
668
669 32. N. Matsakis. “Allocators in Rust.” Baby Steps.
670     <http://smallcultfollowing.com/babysteps/blog/2014/11/14/allocators-in-rust/>.
671
672 33. A. Crichton. “RFC: Allow changing the default allocator #1183.” GitHub.
673     <https://github.com/rust-lang/rfcs/pull/1183>.
674
675 34. A. Crichton. “RFC: Swap out jemalloc.” GitHub.
676     <https://rust-lang.github.io/rfcs/1183-swap-out-jemalloc.html>.
677
678 35. A. Crichton. “Tracking issue for changing the global, default allocator
679     (RFC 1974) #27389.” GitHub.
680     <https://github.com/rust-lang/rust/issues/27389>.
681
682 36. S. Fackler. “Prepare global allocators for stabilization #1974.” GitHub.
683     <https://github.com/rust-lang/rfcs/pull/1974>.
684
685 37. A. Crichton. “RFC: Global allocators.” GitHub.
686     <https://rust-lang.github.io/rfcs/1974-global-allocators.html>.
687
688 38. B. Anderson. “Switch the default global allocator to System, remove
689     alloc\_jemalloc, use jemallocator in rustc #36963.” GitHub.
690     <https://github.com/rust-lang/rust/issues/36963>.
691
692 39. A. Crichton. “Remove the alloc\_jemalloc crate #55238.” GitHub.
693     <https://github.com/rust-lang/rust/pull/55238>.
694
695 40. R. de C Valle. “Tracking Issue for LLVM Control Flow Integrity (CFI) Support
696     for Rust #89653.” GitHub. <https://github.com/rust-lang/rust/issues/89653>.
697
698 41. “ControlFlowIntegrity.” The Rust Unstable Book.
699     [https://doc.rust-lang.org/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity](../unstable-book/compiler-flags/sanitizer.html#controlflowintegrity).