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.
7 This chapter is for software engineers working with the Rust programming
8 language, and assumes prior knowledge of the Rust programming language and
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
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.
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
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.
42 ## Exploit mitigations
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>
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.
55 Summary of exploit mitigations supported by the Rust compiler when building
56 programs for the Linux operating system on the AMD64 architecture and
60 <td><strong>Exploit mitigation</strong>
62 <td><strong>Supported and enabled by default</strong>
64 <td><strong>Since</strong>
68 <td>Position-independent executable
72 <td>0.12.0 (2014-10-09)
76 <td>Integer overflow checks
78 <td>Yes (enabled when debug assertions are enabled, and disabled when debug assertions are disabled)
80 <td>1.1.0 (2015-06-25)
84 <td>Non-executable memory regions
88 <td>1.8.0 (2016-04-14)
92 <td>Stack clashing protection
96 <td>1.20.0 (2017-08-31)
100 <td>Read-only relocations and immediate binding
104 <td>1.21.0 (2017-10-12)
108 <td>Heap corruption protection
112 <td>1.32.0 (2019-01-17) (via operating system default or specified allocator)
116 <td>Stack smashing protection
124 <td>Forward-edge control flow protection
132 <td>Backward-edge control flow protection (e.g., shadow and safe stack)
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>
147 ### Position-independent executable
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”.
156 The Rust compiler supports position-independent executable, and enables it
157 by default since version 0.12.0 (2014-10-09)[10]–[13].
160 $ readelf -h target/release/hello-rust | grep Type:
161 Type: DYN (Shared object file)
163 Fig. 1. Checking if an executable is a position-independent executable.
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.
170 ### Integer overflow checks
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.
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].
183 println!("u: {}", u + 1);
186 Fig. 2. hello-rust-integer program.
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.
196 Fig. 3. Build and execution of hello-rust-integer with debug assertions
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`
206 Fig. 4. Build and execution of hello-rust-integer with debug assertions
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>.
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.
220 <small id="fn:2">2\. See <https://doc.rust-lang.org/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>
226 ### Non-executable memory regions
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.
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].
244 $ readelf -l target/release/hello-rust | grep -A 1 GNU_STACK
245 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
246 0x0000000000000000 0x0000000000000000 RW 0x10
248 Fig. 5. Checking if non-executable memory regions are enabled for a given
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.
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>
265 ### Stack clashing protection
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”.
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].
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
282 println!("Hello, world!");
286 let _: [u64; 1024] = [0; 1024];
290 Fig 7. Modified hello-rust.
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
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.
303 ### Read-only relocations and immediate binding
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”.
310 The Rust compiler supports read-only relocations, and enables it by default
311 since version 1.21.0 (2017-10-12)[30], [31].
314 $ readelf -l target/release/hello-rust | grep GNU_RELRO
315 GNU_RELRO 0x000000000002ee00 0x000000000002fe00 0x000000000002fe00
317 Fig. 9. Checking if read-only relocations is enabled for a given binary.
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
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
332 The Rust compiler supports immediate binding, and enables it by default
333 since version 1.21.0 (2017-10-12)[30], [31].
336 $ readelf -d target/release/hello-rust | grep BIND_NOW
337 0x000000000000001e (FLAGS) BIND_NOW
339 Fig. 10. Checking if immediate binding is enabled for a given binary.
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
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).
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>
358 ### Heap corruption protection
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.
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
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
383 let mut x = Box::new([0; 1024]);
387 let elem = x.get_unchecked_mut(i);
388 *elem = 0x4141414141414141u64;
393 Fig. 11. hello-rust-heap program.
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)
403 Fig. 12. Build and execution of hello-rust-heap with debug assertions
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)
414 Fig. 13. Build and execution of hello-rust-heap with debug assertions
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.
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>
427 ### Stack smashing protection
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)”.
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).
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
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).
449 ### Forward-edge control flow protection
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
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).
468 The Rust compiler does not support forward-edge control flow protection on
469 Linux<sup id="fnref:6" role="doc-noteref"><a href="#fn:6"
470 class="footnote">6</a></sup>. There is work currently ongoing to add support
471 for the [sanitizers](https://github.com/google/sanitizers)[40], which may or
472 may not include support for LLVM CFI.
475 $ readelf -s target/release/hello-rust | grep __cfi_init
477 Fig. 15. Checking if LLVM CFI is enabled for a given binary.
479 The presence of the `__cfi_init` symbol (and references to `__cfi_check`)
480 indicates that LLVM CFI (i.e., forward-edge control flow protection) is
481 enabled for a given binary. Conversely, the absence of the `__cfi_init`
482 symbol (and references to `__cfi_check`) indicates that LLVM CFI is not
483 enabled for a given binary (see Fig. 15).
485 <small id="fn:6">6\. It supports Control Flow Guard (CFG) on Windows (see
486 <https://github.com/rust-lang/rust/issues/68793>). <a href="#fnref:6"
487 class="reversefootnote" role="doc-backlink">↩</a></small>
490 ### Backward-edge control flow protection
492 **Shadow stack** protects saved return instruction pointers from being
493 overwritten by storing a copy of them on a separate (shadow) stack, and
494 using these copies as authoritative values when returning from functions.
495 This is also known as “ShadowCallStack” and “Return Flow Guard”, and is
496 considered an implementation of backward-edge control flow protection (or
497 “backward-edge CFI”).
499 **Safe stack** protects not only the saved return instruction pointers, but
500 also register spills and some local variables from being overwritten by
501 storing unsafe variables, such as large arrays, on a separate (unsafe)
502 stack, and using these unsafe variables on the separate stack instead. This
503 is also known as “SafeStack”, and is also considered an implementation of
504 backward-edge control flow protection.
506 Both shadow and safe stack are intended to be a more comprehensive
507 alternatives to stack smashing protection as they protect the saved return
508 instruction pointers (and other data in the case of safe stack) from
509 arbitrary writes and non-linear out-of-bounds writes.
511 Newer processors provide hardware assistance for backward-edge control flow
512 protection, such as ARM Pointer Authentication, and Intel Shadow Stack as
515 The Rust compiler does not support shadow or safe stack. There is work
516 currently ongoing to add support for the sanitizers[40], which may or may
517 not include support for safe stack<sup id="fnref:7" role="doc-noteref"><a
518 href="#fn:7" class="footnote">7</a></sup>.
521 $ readelf -s target/release/hello-rust | grep __safestack_init
523 Fig. 16. Checking if LLVM SafeStack is enabled for a given binary.
525 The presence of the `__safestack_init` symbol indicates that LLVM SafeStack
526 is enabled for a given binary. Conversely, the absence of the
527 `__safestack_init` symbol indicates that LLVM SafeStack is not enabled for a
528 given binary (see Fig. 16).
530 <small id="fn:7">7\. The shadow stack implementation for the AMD64
531 architecture and equivalent in LLVM was removed due to performance and
532 security issues. <a href="#fnref:7" class="reversefootnote"
533 role="doc-backlink">↩</a></small>
538 As of the latest version of the [Linux Standard Base (LSB) Core
539 Specification](https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/progheader.html),
540 the `PT_GNU_STACK` program header indicates whether the stack should be
541 executable, and the absence of this header indicates that the stack should
542 be executable. However, the Linux kernel currently sets the
543 `READ_IMPLIES_EXEC` personality upon loading any executable with the
544 `PT_GNU_STACK` program header and the `PF_X `flag set or with the absence of
545 this header, resulting in not only the stack, but also all readable virtual
546 memory mappings being executable.
548 An attempt to fix this [was made in
549 2012](https://lore.kernel.org/lkml/f298f914-2239-44e4-8aa1-a51282e7fac0@zmail15.collab.prod.int.phx2.redhat.com/),
550 and another [was made in
551 2020](https://lore.kernel.org/kernel-hardening/20200327064820.12602-1-keescook@chromium.org/).
552 The former never landed, and the latter partially fixed it, but introduced
553 other issues—the absence of the `PT_GNU_STACK` program header still causes
554 not only the stack, but also all readable virtual memory mappings to be
555 executable in some architectures, such as IA-32 and equivalent (or causes
556 the stack to be non-executable in some architectures, such as AMD64 and
557 equivalent, contradicting the LSB).
559 The `READ_IMPLIES_EXEC` personality needs to be completely separated from
560 the `PT_GNU_STACK` program header by having a separate option for it (or
561 setarch -X could just be used whenever `READ_IMPLIES_EXEC` is needed), and
562 the absence of the `PT_GNU_STACK` program header needs to have more secure
563 defaults (unrelated to `READ_IMPLIES_EXEC`).
568 1. D. Hosfelt. “Fearless security: memory safety.” Mozilla Hacks.
569 <https://hacks.mozilla.org/2019/01/fearless-security-memory-safety/>.
571 2. D. Hosfelt. “Fearless security: thread safety.” Mozilla Hacks.
572 <https://hacks.mozilla.org/2019/02/fearless-security-thread-safety/>.
574 3. S. Klabnik and C. Nichols. “What Is Ownership?.” The Rust Programming
575 Language. <https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html>.
577 4. S. Klabnik and C. Nichols. “References and Borrowing.” The Rust
578 Programming Language.
579 <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html>.
581 5. S. Klabnik and C. Nichols. “The Slice Type.” The Rust Programming
582 Language. <https://doc.rust-lang.org/book/ch04-03-slices.html>.
584 6. S. Klabnik and C. Nichols. “Unsafe Rust.” The Rust Programming Language.
585 <https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html>.
587 7. S. Davidoff. “How Rust’s standard library was vulnerable for years and
588 nobody noticed.” Medium.
589 <https://medium.com/@shnatsel/how-rusts-standard-library-was-vulnerable-for-years-and-nobody-noticed-aebf0503c3d6>.
591 8. “Improper restriction of operations within the bounds of a memory buffer
592 (CWE-119).” MITRE CWE List.
593 <https://cwe.mitre.org/data/definitions/119.html>.
595 9. “Concurrency issues (CWE-557).” MITRE CWE List.
596 <https://cwe.mitre.org/data/definitions/557.html>.
598 10. K. McAllister. “Memory exploit mitigations #15179.” GitHub.
599 <https://github.com/rust-lang/rust/issues/15179>.
601 11. K. McAllister. “RFC: Memory exploit mitigation #145.” GitHub.
602 <https://github.com/rust-lang/rfcs/pull/145>.
604 12. K. McAllister. “RFC: Memory exploit mitigation.” GitHub.
605 <https://github.com/kmcallister/rfcs/blob/hardening/active/0000-memory-exploit-mitigation.md>.
607 13. D. Micay. “Enable PIE by default on Linux for full ASLR #16340.” GitHub.
608 <https://github.com/rust-lang/rust/pull/16340>.
610 14. N. Matsakis. “Integer overflow #560.” GitHub.
611 <https://github.com/rust-lang/rfcs/pull/560>.
613 15. G. Lehel and N. Matsakis. “Integer overflow.” GitHub.
614 <https://rust-lang.github.io/rfcs/0560-integer-overflow.html>.
616 16. A. Turon. “Tracking issue for integer overflow (RFC 560) #22020.”
617 GitHub. <https://github.com/rust-lang/rust/issues/22020>.
619 17. H. Wilson. “Myths and legends about integer overflow in Rust.” Huon on
621 <http://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/>.
623 18. B. Anderson. “Stabilize -C overflow-checks #1535.” GitHub.
624 <https://github.com/rust-lang/rfcs/pull/1535>.
626 19. B. Anderson. “Stable overflow checks.” GitHub.
627 <https://github.com/brson/rfcs/blob/overflow/text/0000-stable-overflow-checks.md>.
629 20. N. Froyd. “Add -C overflow-checks option #40037.” GitHub.
630 <https://github.com/rust-lang/rust/pull/40037>.
632 21. R. Á. de Espíndola. “rustc requires executable stack #798.” GitHub.
633 <https://github.com/rust-lang/rust/issues/798>.
635 22. A. Seipp. “Make sure librustrt.so is linked with a non-executable stack.
636 #1066.” GitHub. <https://github.com/rust-lang/rust/pull/1066>.
638 23. D. Micay. “Rust binaries should not have an executable stack #5643.”
639 GitHub. <https://github.com/rust-lang/rust/issues/5643>.
641 24. D. Micay. “Mark the assembly object stacks as non-executable #5647.”
642 GitHub. <https://github.com/rust-lang/rust/pull/5647>.
644 25. A. Clark. “Explicitly disable stack execution on linux and bsd #30859.”
645 GitHub. <https://github.com/rust-lang/rust/pull/30859>.
647 26. “Replace stack overflow checking with stack probes #16012.” GitHub.
648 <https://github.com/rust-lang/rust/issues/16012>.
650 27. B. Striegel. “Extend stack probe support to non-tier-1 platforms, and
651 clarify policy for mitigating LLVM-dependent unsafety #43241.” GitHub.
652 <https://github.com/rust-lang/rust/issues/43241>.
654 28. A. Crichton. “rustc: Implement stack probes for x86 #42816.” GitHub.
655 <https://github.com/rust-lang/rust/pull/42816>.
657 29. A. Crichton. “Add \_\_rust\_probestack intrinsic #175.” GitHub.
658 <https://github.com/rust-lang/compiler-builtins/pull/175>.
660 30. B. Anderson. “Consider applying -Wl,-z,relro or -Wl,-z,relro,-z,now by
661 default #29877.” GitHub. <https://github.com/rust-lang/rust/issues/29877>.
663 31. J. Löthberg. “Add support for full RELRO #43170.” GitHub.
664 <https://github.com/rust-lang/rust/pull/43170>.
666 32. N. Matsakis. “Allocators in Rust.” Baby Steps.
667 <http://smallcultfollowing.com/babysteps/blog/2014/11/14/allocators-in-rust/>.
669 33. A. Crichton. “RFC: Allow changing the default allocator #1183.” GitHub.
670 <https://github.com/rust-lang/rfcs/pull/1183>.
672 34. A. Crichton. “RFC: Swap out jemalloc.” GitHub.
673 <https://rust-lang.github.io/rfcs/1183-swap-out-jemalloc.html>.
675 35. A. Crichton. “Tracking issue for changing the global, default allocator
676 (RFC 1974) #27389.” GitHub.
677 <https://github.com/rust-lang/rust/issues/27389>.
679 36. S. Fackler. “Prepare global allocators for stabilization #1974.” GitHub.
680 <https://github.com/rust-lang/rfcs/pull/1974>.
682 37. A. Crichton. “RFC: Global allocators.” GitHub.
683 <https://rust-lang.github.io/rfcs/1974-global-allocators.html>.
685 38. B. Anderson. “Switch the default global allocator to System, remove
686 alloc\_jemalloc, use jemallocator in rustc #36963.” GitHub.
687 <https://github.com/rust-lang/rust/issues/36963>.
689 39. A. Crichton. “Remove the alloc\_jemalloc crate #55238.” GitHub.
690 <https://github.com/rust-lang/rust/pull/55238>.
692 40. J. Aparicio. 2017. “Tracking issue for sanitizer support #39699.”
693 <https://github.com/rust-lang/rust/issues/39699>.