├── .gitignore ├── CNAME ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── Makefile ├── README.md ├── book.toml ├── code_snippets ├── chp12 │ └── diff_fuzz │ │ ├── Cargo.toml │ │ └── src │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── map.rs │ │ ├── map_types.rs │ │ ├── set.rs │ │ ├── set_types.rs │ │ └── tree │ │ ├── arena.rs │ │ ├── error.rs │ │ ├── iter.rs │ │ ├── mod.rs │ │ ├── node.rs │ │ ├── node_dispatch.rs │ │ └── tree.rs ├── chp2 │ └── crypto_tool │ │ ├── Cargo.toml │ │ ├── rc4 │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ │ └── rcli │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── chp3 │ ├── c_snippets │ │ ├── scope.cpp │ │ └── undef.c │ ├── prime_test │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── proc │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── proc_2 │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── rc4 │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs └── chp4 │ ├── c_snippets │ ├── spatial.c │ ├── temporal.c │ └── type.c │ ├── greeting │ ├── Cargo.toml │ └── src │ │ └── main.rs │ ├── stack_example │ ├── Cargo.toml │ └── src │ │ └── main.rs │ └── stack_example_iter │ ├── Cargo.toml │ └── src │ └── main.rs ├── docker_aarch64 └── Dockerfile ├── docs ├── .nojekyll ├── 404.html ├── CNAME ├── FontAwesome │ ├── css │ │ └── font-awesome.css │ └── fonts │ │ ├── FontAwesome.ttf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 ├── ayu-highlight.css ├── book.js ├── cfp.html ├── changelog.html ├── chp1 │ ├── _hands_on.html │ ├── _index.html │ ├── about_the_team.html │ ├── bugs_venn.svg │ ├── challenges.html │ ├── dreyfus.svg │ ├── how_is_this_book_structured.html │ ├── rust_stack.svg │ ├── sys_langs.svg │ └── why_this_book.html ├── chp12 │ └── diff_fuzz_PLACEHOLDER.html ├── chp16_appendix │ ├── _index.html │ ├── books.html │ ├── components.html │ ├── crypto.html │ ├── icfg.html │ ├── icfg_iter.svg │ ├── icfg_mut_rec.svg │ ├── icfg_rec.svg │ ├── mem_hierarch.html │ ├── mod_deep.svg │ ├── mod_shallow.svg │ ├── resources.html │ ├── stream_cipher.svg │ ├── tools.html │ └── types.html ├── chp2 │ ├── _hands_on.html │ ├── _index.html │ ├── cli.html │ ├── dynamic_assurance_1.html │ ├── dynamic_assurance_2.html │ ├── dynamic_assurance_3.html │ ├── incr_ptrs_alias.svg │ ├── incr_ptrs_bad.svg │ ├── incr_ptrs_ok.svg │ ├── incr_ptrs_ok_after.svg │ ├── limits.html │ ├── link_dynamic.svg │ ├── link_static.svg │ ├── operational_assurance_1.html │ ├── operational_assurance_2.html │ ├── rc4_1.svg │ ├── rc4_2.svg │ ├── rcli_model.svg │ ├── static_assurance_1.html │ ├── static_assurance_2.html │ ├── static_vs_dynamic.html │ └── tool_quad.svg ├── chp3 │ ├── _hands_on.html │ ├── _index.html │ ├── building_blocks.svg │ ├── count_primes_doc.png │ ├── misra.svg │ ├── mod_single_file.svg │ ├── modules.html │ ├── own_move.svg │ ├── own_move_copy.svg │ ├── proc_own_no_child.svg │ ├── proc_own_one_child.svg │ ├── proc_ref_no_child.svg │ ├── proc_ref_one_child.svg │ ├── ref_venn_interior_mut.svg │ ├── ref_venn_normal.svg │ ├── rust_1_low_data_rep.html │ ├── rust_2_high_data_rep.html │ ├── rust_3_ctrl_flow.html │ ├── rust_4_own_1.html │ ├── rust_5_own_2.html │ ├── rust_6_error.html │ ├── tooling.html │ └── undef.html ├── chp4 │ ├── _index.html │ ├── assure_stack_1.html │ ├── attack_1.html │ ├── attack_2.html │ ├── behavior_concentric.svg │ ├── cpu_model.svg │ ├── exploit_jop_model.svg │ ├── exploit_rop_model.svg │ ├── mem_safety_block.svg │ ├── program_process.svg │ ├── safe_rust_PLACEHOLDER.html │ ├── safety_buffer_overflow.svg │ ├── safety_spatial_grow_up.svg │ ├── safety_temporal_grow_up.svg │ ├── safety_type_grow_up.svg │ ├── socket_state_machine.svg │ ├── socket_weird_machine.svg │ ├── stack_example.svg │ ├── stack_scaling_1.svg │ ├── stack_scaling_2.svg │ ├── static_strings.svg │ └── sw_stack_1.html ├── chp7 │ └── traits.html ├── clipboard.min.js ├── css │ ├── chrome.css │ ├── general.css │ ├── print.css │ └── variables.css ├── download.html ├── elasticlunr.min.js ├── engage.html ├── faq.html ├── favicon.png ├── favicon.svg ├── fonts │ ├── OPEN-SANS-LICENSE.txt │ ├── SOURCE-CODE-PRO-LICENSE.txt │ ├── fonts.css │ ├── open-sans-v17-all-charsets-300.woff2 │ ├── open-sans-v17-all-charsets-300italic.woff2 │ ├── open-sans-v17-all-charsets-600.woff2 │ ├── open-sans-v17-all-charsets-600italic.woff2 │ ├── open-sans-v17-all-charsets-700.woff2 │ ├── open-sans-v17-all-charsets-700italic.woff2 │ ├── open-sans-v17-all-charsets-800.woff2 │ ├── open-sans-v17-all-charsets-800italic.woff2 │ ├── open-sans-v17-all-charsets-italic.woff2 │ ├── open-sans-v17-all-charsets-regular.woff2 │ └── source-code-pro-v11-all-charsets-500.woff2 ├── highlight.css ├── highlight.js ├── img │ ├── book_topics.svg │ ├── faq_venn.svg │ ├── har_logo.svg │ ├── har_logo_inkscape.svg │ ├── har_logo_social.png │ ├── recommended_books │ │ ├── book_c.jpg │ │ ├── book_crypto.jpg │ │ ├── book_csapp.jpg │ │ ├── book_pba.jpg │ │ ├── book_phil.jpg │ │ ├── book_rust_1.jpg │ │ └── book_rust_2.jpg │ └── rust_foundation_logo.png ├── index.html ├── landing.html ├── license.html ├── mark.min.js ├── print.html ├── searcher.js ├── searchindex.js ├── searchindex.json ├── templates │ └── placeholder_img.png └── tomorrow-night.css ├── img ├── har_logo.svg └── rust_foundation_logo.png ├── internal_tools └── har_analyze │ ├── Cargo.toml │ └── src │ ├── book.rs │ ├── chapter.rs │ ├── content.rs │ ├── lint.rs │ ├── main.rs │ ├── mod.rs │ ├── rules.rs │ ├── traits.rs │ └── update.rs ├── src ├── SUMMARY.md ├── cfp.md ├── changelog.md ├── chp1 │ ├── _hands_on.md │ ├── _index.md │ ├── about_the_team.md │ ├── bugs_venn.svg │ ├── challenges.md │ ├── dreyfus.svg │ ├── how_is_this_book_structured.md │ ├── rust_stack.svg │ ├── sys_langs.svg │ └── why_this_book.md ├── chp12 │ └── diff_fuzz_PLACEHOLDER.md ├── chp16_appendix │ ├── _index.md │ ├── books.md │ ├── components.md │ ├── crypto.md │ ├── icfg.md │ ├── icfg_iter.svg │ ├── icfg_mut_rec.svg │ ├── icfg_rec.svg │ ├── mem_hierarch.md │ ├── mod_deep.svg │ ├── mod_shallow.svg │ ├── resources.md │ ├── stream_cipher.svg │ ├── tools.md │ └── types.md ├── chp2 │ ├── _hands_on.md │ ├── _index.md │ ├── cli.md │ ├── dynamic_assurance_1.md │ ├── dynamic_assurance_2.md │ ├── dynamic_assurance_3.md │ ├── incr_ptrs_alias.svg │ ├── incr_ptrs_bad.svg │ ├── incr_ptrs_ok.svg │ ├── incr_ptrs_ok_after.svg │ ├── limits.md │ ├── link_dynamic.svg │ ├── link_static.svg │ ├── operational_assurance_1.md │ ├── operational_assurance_2.md │ ├── rc4_1.svg │ ├── rc4_2.svg │ ├── rcli_model.svg │ ├── static_assurance_1.md │ ├── static_assurance_2.md │ ├── static_vs_dynamic.md │ └── tool_quad.svg ├── chp3 │ ├── _hands_on.md │ ├── _index.md │ ├── building_blocks.svg │ ├── count_primes_doc.png │ ├── misra.svg │ ├── mod_single_file.svg │ ├── modules.md │ ├── own_move.svg │ ├── own_move_copy.svg │ ├── proc_own_no_child.svg │ ├── proc_own_one_child.svg │ ├── proc_ref_no_child.svg │ ├── proc_ref_one_child.svg │ ├── ref_venn_interior_mut.svg │ ├── ref_venn_normal.svg │ ├── rust_1_low_data_rep.md │ ├── rust_2_high_data_rep.md │ ├── rust_3_ctrl_flow.md │ ├── rust_4_own_1.md │ ├── rust_5_own_2.md │ ├── rust_6_error.md │ ├── tooling.md │ └── undef.md ├── chp4 │ ├── _index.md │ ├── assure_stack_1.md │ ├── attack_1.md │ ├── attack_2.md │ ├── behavior_concentric.svg │ ├── cpu_model.svg │ ├── exploit_jop_model.svg │ ├── exploit_rop_model.svg │ ├── mem_safety_block.svg │ ├── program_process.svg │ ├── safe_rust_PLACEHOLDER.md │ ├── safety_buffer_overflow.svg │ ├── safety_spatial_grow_up.svg │ ├── safety_temporal_grow_up.svg │ ├── safety_type_grow_up.svg │ ├── socket_state_machine.svg │ ├── socket_weird_machine.svg │ ├── stack_example.svg │ ├── stack_scaling_1.svg │ ├── stack_scaling_2.svg │ ├── static_strings.svg │ └── sw_stack_1.md ├── chp7 │ └── traits.md ├── download.md ├── engage.md ├── faq.md ├── img │ ├── book_topics.svg │ ├── faq_venn.svg │ ├── har_logo.svg │ ├── har_logo_inkscape.svg │ ├── har_logo_social.png │ ├── recommended_books │ │ ├── book_c.jpg │ │ ├── book_crypto.jpg │ │ ├── book_csapp.jpg │ │ ├── book_pba.jpg │ │ ├── book_phil.jpg │ │ ├── book_rust_1.jpg │ │ └── book_rust_2.jpg │ └── rust_foundation_logo.png ├── landing.md ├── license.md └── templates │ ├── _hands_on.md │ ├── _index.md │ ├── placeholder_img.png │ └── section.md └── theme └── css └── variables.css /.gitignore: -------------------------------------------------------------------------------- 1 | # VSCode 2 | .vscode/ 3 | 4 | # Generated mdbook 5 | book/ 6 | 7 | # VSCode 8 | .vscode/* 9 | 10 | # C/C++ Binaries 11 | bypass 12 | undef 13 | scope 14 | set_1 15 | set_2 16 | 17 | # Generated by Cargo 18 | # will have compiled files and executables 19 | debug/ 20 | target/ 21 | 22 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 23 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 24 | Cargo.lock 25 | 26 | # These are backup files generated by rustfmt 27 | **/*.rs.bk 28 | 29 | # MSVC Windows builds of rustc generate these, which store debugging information 30 | *.pdb 31 | 32 | # ODT export 33 | *.odt 34 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | highassurance.rs -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This repository adopts the Rust Language's Code of Conduct, which [can be found here](https://www.rust-lang.org/conduct.html). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to *High Assurance Rust*! 4 | 5 | Your efforts make the book better for all other readers and are greatly appreciated. 6 | 7 | ## Contributions We Accept 8 | 9 | * **Grammar, Spelling, Capitalization, or Punctuation Errors:** Anything objectively wrong in the English language. 10 | 11 | * Please open a [Pull Request (PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with the fix. 12 | 13 | * **Factual or Technical Errors:** Anything provably incorrect. A counterexample or citation is recommended, but not required. 14 | 15 | * Please open an [Issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue) explaining the error found. 16 | 17 | * **Docker and CI Improvements:** Anything related to the testing or maintenance of this book's Docker container. 18 | 19 | * Please open a [Pull Request (PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with the fix or update. 20 | 21 | * **Formatting Fixes:** Almost every diagram in this book was created using [diagrams.net](https://github.com/jgraph/drawio) and there may be SVG rendering issues on mobile, with different browsers or font settings, etc. Text content could also be subject to device-specific formatting issues. 22 | 23 | * Please open a [Pull Request (PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with the fix or update. If it fixes your formatting issue and still works on our version of Firefox on Linux desktop, we'll accept it! 24 | 25 | ## Contributions We Cannot Accept 26 | 27 | Anything outside of the above, including: rewording for style or clarity, addition of new content, removal of existing content, etc. 28 | 29 | These kinds of changes tend to be subjective and require back-and-forth collaboration to reach consensus. 30 | We'd like to maintain a consistent voice. 31 | 32 | If you'd like to suggest a content revision, have any questions about contributing not answered by this guide, or do not wish to use GitHub for any reason, please reach out via email: 33 | 34 | **contact@highassurance.rs** 35 | 36 | **These contributing guidelines are not set in stone, we're very much "learning as we go".** If there's a change to the contribution model that'd make this project better in the long-term, please feel free to suggest it via email or GitHub issue! 37 | 38 | ## Files to Change in a PR 39 | 40 | Please only modify `.md`, `.rs`, or `.svg` files. 41 | We'll generate the book using a local copy of the [`mdbook`](https://rust-lang.github.io/mdBook/) binary. 42 | This eliminates the need to review large diffs which may include generated JavaScript code. 43 | 44 | ## Adding Yourself to the Community Contributors List 45 | 46 | If this is your first PR, please add your GitHub username/URL to the "Community Contributors" list [here](./src/chp1/about_the_team.md#community-contributors). 47 | Be sure to maintain alphabetical order. 48 | 49 | If you open an Issue and a fix or update is made, you can open a subsequent PR adding yourself to the list and referencing the relevant issue. 50 | 51 | > **Why Maintain a Contributors List?** 52 | > 53 | > 1. Every change counts. No matter how small, the cumulative effect is significant! 54 | > 55 | > 2. In a traditional book publishing process, proofreading is a paid, full-time job. Listing contributors is a simple way to recognize effort for the same task. 56 | 57 | ## Building and Reading the Book Locally 58 | 59 | Setup [`mdbook`](https://rust-lang.github.io/mdBook/index.html) (assumes you've already installed Rust per [these instructions](https://www.rust-lang.org/tools/install)): 60 | 61 | ``` 62 | cargo install mdbook 63 | ``` 64 | 65 | If you're on Linux, you can leverage the `Makefile` provided in this repo. 66 | The supported `make` targets are below. 67 | 68 | Render book (start webserver listening on [http://localhost:3000](http://localhost:3000), open book in default browser): 69 | 70 | ``` 71 | make read 72 | ``` 73 | 74 | Check progress (run checks and perform a page count): 75 | 76 | ``` 77 | make check 78 | ``` 79 | 80 | Clean (remove any artifacts generated by the above commands): 81 | 82 | ``` 83 | make clean 84 | ``` 85 | 86 | ## License 87 | 88 | All text in this book, including any text contributions, is licensed under the [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)](https://creativecommons.org/licenses/by-nc-nd/4.0/) license. 89 | 90 | All code in this book, including any code contributions, is licensed under the [MIT License](https://opensource.org/licenses/MIT). 91 | 92 | > **An Aside on Writing** 93 | > 94 | > If you're ever considering writing your own content, we say go for it! 95 | > Blog posts are a great way to start, and you can always rework the contents into a book if appropriate. 96 | > We believe that: 97 | > 98 | > 1. Writing can help you refine ideas and deepen understanding, even if you never make it public. 99 | > 100 | > 2. No matter what level you're at, there's always someone out there that's looking to reach your level and could benefit from your experience. 101 | > 102 | > Static site generators like [`zola`](https://www.getzola.org/) and [`mdbook`](https://rust-lang.github.io/mdBook/) make it easier than ever to get up and running. 103 | > [GitHub pages](https://pages.github.com/) makes hosting hassle-free (supports custom domains and rotates SSL certs for you). 104 | > No time like the present :) -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # x86_64 2 | FROM rust:1.59-slim 3 | 4 | # Non-Rust tooling 5 | ENV TZ=US/New_York 6 | RUN apt-get update -y 7 | RUN DEBIAN_FRONTEND="noninteractive" apt-get update && apt-get install -y \ 8 | build-essential \ 9 | libssl-dev \ 10 | pkg-config \ 11 | rr \ 12 | tree \ 13 | xxd \ 14 | git \ 15 | vim 16 | 17 | # Rust tooling 18 | RUN rustup toolchain install nightly 19 | RUN rustup component add llvm-tools-preview 20 | RUN cargo install mdbook 21 | RUN cargo install cargo-fuzz 22 | RUN cargo install cargo-binutils 23 | RUN cargo install cargo-modules 24 | RUN cargo install cargo-audit 25 | 26 | # Src import 27 | RUN mkdir /code_snippets 28 | WORKDIR /code_snippets 29 | COPY ./code_snippets /code_snippets/ -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | serve: 2 | mdbook serve 3 | 4 | read: 5 | mdbook serve --open 6 | 7 | # TODO: clean up command duplication, this is gross 8 | check: 9 | # Book 10 | mdbook test 11 | 12 | # Code snippets 13 | cd code_snippets/chp2/crypto_tool && cargo fmt && cargo test && cargo test --all-features 14 | cd code_snippets/chp3/rc4 && cargo fmt && RUSTFLAGS=-Awarnings cargo test 15 | cd code_snippets/chp3/proc && cargo fmt && RUSTFLAGS=-Awarnings cargo test 16 | cd code_snippets/chp3/proc_2 && cargo fmt && RUSTFLAGS=-Awarnings cargo test 17 | cd code_snippets/chp3/prime_test && cargo test 18 | cd code_snippets/chp4/greeting && cargo fmt && cargo test 19 | cd code_snippets/chp4/stack_example && cargo fmt 20 | cd code_snippets/chp4/stack_example_iter && cargo fmt 21 | 22 | # Metrics and linting 23 | cd internal_tools/har_analyze && cargo fmt && cargo test && cargo clippy && cargo run -- --metrics --lint --log-warn 24 | 25 | # TODO: clean code_snippet binaries 26 | clean: 27 | mdbook clean 28 | cd internal_tools/har_analyze && cargo clean 29 | 30 | site: 31 | cd internal_tools/har_analyze && cargo run -- --lint --update 32 | rm -rf docs/ 33 | mdbook build 34 | mv book/ docs/ 35 | cp CNAME docs/ 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

High Assurance Rust


2 | 3 | # High Assurance Rust 4 | 5 | [![Pages](https://img.shields.io/badge/Pages-178-purple.svg)](https://github.com/tnballo/high-assurance-rust) 6 | [![Diagrams](https://img.shields.io/badge/Diagrams-51-blue.svg)](https://github.com/tnballo/high-assurance-rust) 7 | [![Price](https://img.shields.io/badge/Price-$0.00-orange.svg)](https://highassurance.rs/cfp.html) 8 | [![Text License: CC BY-NC-ND 4.0](https://img.shields.io/badge/Text%20License-CC%20BY--NC--ND%204.0-yellow.svg)](https://highassurance.rs/license.html) 9 | [![Code License: MIT](https://img.shields.io/badge/Code%20License-MIT-yellowgreen.svg)](https://highassurance.rs/license.html) 10 | [![Assurance](https://img.shields.io/badge/Assurance-High-brightgreen.svg)](https://highassurance.rs) 11 | 12 | ### Click here to read now: [https://highassurance.rs/](https://highassurance.rs/) 13 | 14 | #### What does this book aim to do? 15 | 16 | 1. Provide an accessible but principled introduction to developing secure and robust systems. At the overlap of "state-of-the-art" and "near-term practical": mostly production-grade tools and techniques, but also some cutting-edge research projects. All open-source. 17 | 18 | 2. Help experienced developers both learn a new language and delve deeper into fundamental Computer Science and Computer Architecture topics. 19 | 20 | #### How can I help? 21 | 22 | If you find this content valuable, consider increasing its visibility among developers by starring this GitHub repo. 23 | Much appreciated! :) 24 | 25 | To cite this book directly in your own work, please use this BibTeX or similar: 26 | 27 | ``` 28 | @misc{high_assurance_rust, 29 | title={High Assurance Rust: Developing Secure and Robust Software}, 30 | url={https://highassurance.rs}, 31 | howpublished = "\url{https://highassurance.rs}", 32 | author={Ballo, Tiemoko and Ballo, Moumine and James, Alex}, 33 | year={2022} 34 | } 35 | ``` 36 | 37 | #### Interested in a physical print? 38 | 39 | Please [sign up here](https://forms.gle/ESYgXgswCjEoCSHT9) if you'd like to be notified when the book is finished and hard copies are available. 40 | The email you provide not be shared or used for any other purpose. 41 | 42 | #### Have feedback or questions? 43 | 44 | Your input matters. 45 | We'd love to hear from you, please send an email to: 46 | 47 | **contact@highassurance.rs** 48 | 49 | #### Can I contribute? 50 | 51 | Contributions are welcome and appreciated. 52 | Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md). 53 | 54 | #### Anything else I should know? 55 | 56 | A great deal of effort went into making this book a reality. 57 | We hope you have as much fun reading as we did writing. 58 | Let's hack together! 59 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Tiemoko Ballo", "Moumine Ballo", "Alex James"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "High Assurance Rust: Developing Secure and Robust Software" 7 | 8 | [output.html] 9 | default-theme = "light" 10 | preferred-dark-theme = "navy" 11 | cname = "highassurance.rs" 12 | git-repository-url = "https://github.com/tnballo/high-assurance-rust" 13 | git-repository-icon = "fa-github" 14 | edit-url-template = "https://highassurance.rs/engage.html#submit-feedback-questions-issues-or-prs" 15 | mathjax-support = true 16 | 17 | [output.html.playground] 18 | editable = false # allows editing the source code 19 | copyable = true # include the copy button for copying code snippets 20 | copy-js = false # includes the JavaScript for the code editor 21 | line-numbers = false # displays line numbers for editable code 22 | 23 | # https://crates.io/crates/mdbook-epub/ 24 | #[output.epub] 25 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "buggy_scapegoat" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | tinyvec = { version = "^1.5", features = ["rustc_1_55"] } 8 | micromath = "^2.0" 9 | smallnum = "^0.4" 10 | 11 | [dev-dependencies] 12 | rand = { version = "0.7", features = ["small_rng"] } -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/lib.rs: -------------------------------------------------------------------------------- 1 | /*! 2 | Buggy version of the [`scapegoat` crate](https://docs.rs/scapegoat/latest/scapegoat/), for differential fuzzing blog post. 3 | */ 4 | 5 | #![forbid(unsafe_code)] 6 | #![cfg_attr(not(any(test, fuzzing)), no_std)] 7 | #![cfg_attr(not(any(test, fuzzing)), deny(missing_docs))] 8 | 9 | mod tree; 10 | pub use crate::tree::SgError; 11 | 12 | mod map; 13 | pub use crate::map::SgMap; 14 | 15 | /// [`SgMap`][crate::map::SgMap]'s iterator return types and [`Entry`](crate::map_types::Entry) enum. 16 | pub mod map_types; 17 | 18 | mod set; 19 | pub use crate::set::SgSet; 20 | 21 | /// [`SgSet`][crate::set::SgSet]'s iterator return types. 22 | pub mod set_types; 23 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/tree/error.rs: -------------------------------------------------------------------------------- 1 | /// Errors for fallible operations. 2 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] 3 | #[non_exhaustive] 4 | pub enum SgError { 5 | /// Cannot construct instance, maximum supported capacity exceeded. 6 | MaximumCapacityExceeded, 7 | 8 | /// Requested operation cannot complete, stack storage is full. 9 | StackCapacityExceeded, 10 | 11 | /* 12 | /// Requested operation cannot complete, heap storage is full. 13 | HeapCapacityExceeded, 14 | */ 15 | /// Reserved for future use 16 | #[doc(hidden)] 17 | Reserved3, 18 | 19 | /// Reserved for future use 20 | #[doc(hidden)] 21 | Reserved4, 22 | 23 | /// Reserved for future use 24 | #[doc(hidden)] 25 | Reserved5, 26 | 27 | /// Reserved for future use 28 | #[doc(hidden)] 29 | Reserved6, 30 | 31 | /// Reserved for future use 32 | #[doc(hidden)] 33 | Reserved7, 34 | 35 | /// Invalid rebalance factor requested, cannot set. 36 | RebalanceFactorOutOfRange, 37 | } 38 | 39 | /* 40 | 41 | Requires nightly feature: 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use crate::SgError; 46 | use std::mem::variant_count; 47 | 48 | #[test] 49 | fn test_err_var_cnt() { 50 | assert_eq!(variant_count::(), 8); 51 | } 52 | } 53 | */ 54 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/tree/iter.rs: -------------------------------------------------------------------------------- 1 | use tinyvec::ArrayVec; 2 | 3 | use super::node::Node; 4 | use super::node_dispatch::SmallNode; 5 | use super::tree::{Idx, SgTree}; 6 | 7 | // Immutable Reference Iterator ---------------------------------------------------------------------------------------- 8 | 9 | /// Uses iterative in-order tree traversal algorithm. 10 | /// Maintains a small stack of arena indexes (won't contain all indexes simultaneously for a balanced tree). 11 | pub struct Iter<'a, K: Default, V: Default, const N: usize> { 12 | bst: &'a SgTree, 13 | idx_stack: ArrayVec<[usize; N]>, 14 | total_cnt: usize, 15 | spent_cnt: usize, 16 | } 17 | 18 | impl<'a, K: Ord + Default, V: Default, const N: usize> Iter<'a, K, V, N> { 19 | pub fn new(bst: &'a SgTree) -> Self { 20 | let mut ordered_iter = Iter { 21 | bst, 22 | idx_stack: ArrayVec::<[usize; N]>::new(), 23 | total_cnt: bst.len(), 24 | spent_cnt: 0, 25 | }; 26 | 27 | if let Some(root_idx) = ordered_iter.bst.opt_root_idx { 28 | let mut curr_idx = root_idx; 29 | loop { 30 | let node = &ordered_iter.bst.arena[curr_idx]; 31 | match node.left_idx() { 32 | Some(lt_idx) => { 33 | ordered_iter.idx_stack.push(curr_idx); 34 | curr_idx = lt_idx; 35 | } 36 | None => { 37 | ordered_iter.idx_stack.push(curr_idx); 38 | break; 39 | } 40 | } 41 | } 42 | } 43 | 44 | ordered_iter 45 | } 46 | } 47 | 48 | impl<'a, K: Ord + Default, V: Default, const N: usize> Iterator for Iter<'a, K, V, N> { 49 | type Item = (&'a K, &'a V); 50 | 51 | fn next(&mut self) -> Option { 52 | match self.idx_stack.pop() { 53 | Some(pop_idx) => { 54 | let node = &self.bst.arena[pop_idx]; 55 | if let Some(gt_idx) = node.right_idx() { 56 | let mut curr_idx = gt_idx; 57 | loop { 58 | let node = &self.bst.arena[curr_idx]; 59 | match node.left_idx() { 60 | Some(lt_idx) => { 61 | self.idx_stack.push(curr_idx); 62 | curr_idx = lt_idx; 63 | } 64 | None => { 65 | self.idx_stack.push(curr_idx); 66 | break; 67 | } 68 | } 69 | } 70 | } 71 | 72 | let node = &self.bst.arena[pop_idx]; 73 | self.spent_cnt += 1; 74 | Some((node.key(), node.val())) 75 | } 76 | None => None, 77 | } 78 | } 79 | } 80 | 81 | impl<'a, K: Ord + Default, V: Default, const N: usize> ExactSizeIterator for Iter<'a, K, V, N> { 82 | fn len(&self) -> usize { 83 | debug_assert!(self.spent_cnt <= self.total_cnt); 84 | self.total_cnt - self.spent_cnt 85 | } 86 | } 87 | 88 | // Mutable Reference Iterator ------------------------------------------------------------------------------------------ 89 | 90 | pub struct IterMut<'a, K, V, const N: usize> { 91 | arena_iter_mut: core::slice::IterMut<'a, Option>>, 92 | } 93 | 94 | impl<'a, K: Ord + Default, V: Default, const N: usize> IterMut<'a, K, V, N> { 95 | pub fn new(bst: &'a mut SgTree) -> Self { 96 | bst.sort_arena(); 97 | IterMut { 98 | arena_iter_mut: bst.arena.iter_mut(), 99 | } 100 | } 101 | } 102 | 103 | impl<'a, K: Ord + Default, V: Default, const N: usize> Iterator for IterMut<'a, K, V, N> { 104 | type Item = (&'a K, &'a mut V); 105 | 106 | fn next(&mut self) -> Option { 107 | match self.arena_iter_mut.next() { 108 | Some(Some(node)) => Some(node.get_mut()), 109 | _ => None, 110 | } 111 | } 112 | } 113 | 114 | impl<'a, K: Ord + Default, V: Default, const N: usize> ExactSizeIterator for IterMut<'a, K, V, N> { 115 | fn len(&self) -> usize { 116 | self.arena_iter_mut.len() 117 | } 118 | } 119 | 120 | // Consuming Iterator -------------------------------------------------------------------------------------------------- 121 | 122 | /// Cheats a little by using internal flattening logic to sort, instead of re-implementing proper traversal. 123 | /// Maintains a shrinking list of arena indexes, initialized with all of them. 124 | pub struct IntoIter { 125 | bst: SgTree, 126 | sorted_idxs: ArrayVec<[usize; N]>, 127 | } 128 | 129 | impl IntoIter { 130 | pub fn new(bst: SgTree) -> Self { 131 | let mut ordered_iter = IntoIter { 132 | bst, 133 | sorted_idxs: ArrayVec::<[usize; N]>::new(), 134 | }; 135 | 136 | if let Some(root_idx) = ordered_iter.bst.opt_root_idx { 137 | ordered_iter.sorted_idxs = ordered_iter.bst.flatten_subtree_to_sorted_idxs(root_idx); 138 | ordered_iter.sorted_idxs.reverse(); 139 | } 140 | 141 | ordered_iter 142 | } 143 | } 144 | 145 | impl Iterator for IntoIter { 146 | type Item = (K, V); 147 | 148 | fn next(&mut self) -> Option { 149 | match self.sorted_idxs.pop() { 150 | Some(idx) => match self.bst.priv_remove_by_idx(idx) { 151 | Some((key, val)) => Some((key, val)), 152 | None => { 153 | debug_assert!(false, "Use of invalid index in consuming iterator!"); 154 | None 155 | } 156 | }, 157 | None => None, 158 | } 159 | } 160 | } 161 | 162 | impl ExactSizeIterator for IntoIter { 163 | fn len(&self) -> usize { 164 | self.sorted_idxs.len() 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/tree/mod.rs: -------------------------------------------------------------------------------- 1 | mod node_dispatch; 2 | pub use node_dispatch::SmallNode; 3 | 4 | mod arena; 5 | 6 | pub(super) mod node; 7 | 8 | mod iter; 9 | pub use iter::{IntoIter, Iter, IterMut}; 10 | 11 | mod error; 12 | pub use error::SgError; 13 | 14 | #[allow(clippy::module_inception)] 15 | mod tree; 16 | pub use tree::{Idx, SgTree}; 17 | -------------------------------------------------------------------------------- /code_snippets/chp12/diff_fuzz/src/tree/node_dispatch.rs: -------------------------------------------------------------------------------- 1 | // Size-optimized Node Trait ------------------------------------------------------------------------------------------- 2 | 3 | /// Interface encapsulates `U`. 4 | pub trait SmallNode { 5 | /// Get key. 6 | fn key(&self) -> &K; 7 | 8 | /// Set key. 9 | fn set_key(&mut self, key: K); 10 | 11 | // Take key, replacing current with `K::Default()`. 12 | fn take_key(&mut self) -> K; 13 | 14 | /// Get value. 15 | fn val(&self) -> &V; 16 | 17 | /// Get key and mutable value. 18 | fn get_mut(&mut self) -> (&K, &mut V); 19 | 20 | /// Set value. 21 | fn set_val(&mut self, val: V); 22 | 23 | // Take value, replacing current with `V::Default()`. 24 | fn take_val(&mut self) -> V; 25 | 26 | /// Get left index as `usize`. 27 | fn left_idx(&self) -> Option; 28 | 29 | /// Set left index. 30 | fn set_left_idx(&mut self, opt_idx: Option); 31 | 32 | /// Get right index as `usize`. 33 | fn right_idx(&self) -> Option; 34 | 35 | /// Set right index. 36 | fn set_right_idx(&mut self, opt_idx: Option); 37 | 38 | /// Get subtree size. 39 | #[cfg(feature = "fast_rebalance")] 40 | fn subtree_size(&self) -> usize; 41 | 42 | /// Set subtree size. 43 | #[cfg(feature = "fast_rebalance")] 44 | fn set_subtree_size(&mut self, size: usize); 45 | } 46 | 47 | /* 48 | NOTE: This is draft code for upgrades when `feature(generic_const_exprs)` stabilizes. 49 | 50 | use super::node::Node; 51 | use smallnum::SmallUnsignedLabel; 52 | 53 | // Enum Dispatch ------------------------------------------------------------------------------------------------------- 54 | 55 | #[derive(Clone)] 56 | pub enum SmallNodeDispatch { 57 | NodeUSIZE(Node), 58 | NodeU8(Node), 59 | 60 | #[cfg(any( 61 | target_pointer_width = "16", 62 | target_pointer_width = "32", 63 | target_pointer_width = "64", 64 | target_pointer_width = "128", 65 | ))] 66 | NodeU16(Node), 67 | 68 | #[cfg(any( 69 | target_pointer_width = "32", 70 | target_pointer_width = "64", 71 | target_pointer_width = "128", 72 | ))] 73 | NodeU32(Node), 74 | 75 | #[cfg(any(target_pointer_width = "64", target_pointer_width = "128",))] 76 | NodeU64(Node), 77 | 78 | #[cfg(target_pointer_width = "128")] 79 | NodeU128(Node), 80 | } 81 | 82 | impl SmallNodeDispatch { 83 | pub const fn new(key: K, val: V, uint: SmallUnsignedLabel) -> Self { 84 | match uint { 85 | SmallUnsignedLabel::USIZE => SmallNodeDispatch::NodeUSIZE(Node::::new(key, val)), 86 | SmallUnsignedLabel::U8 => SmallNodeDispatch::NodeU8(Node::::new(key, val)), 87 | 88 | #[cfg(any( 89 | target_pointer_width = "16", 90 | target_pointer_width = "32", 91 | target_pointer_width = "64", 92 | target_pointer_width = "128", 93 | ))] 94 | SmallUnsignedLabel::U16 => SmallNodeDispatch::NodeU16(Node::::new(key, val)), 95 | 96 | #[cfg(any( 97 | target_pointer_width = "32", 98 | target_pointer_width = "64", 99 | target_pointer_width = "128", 100 | ))] 101 | SmallUnsignedLabel::U32 => SmallNodeDispatch::NodeU32(Node::::new(key, val)), 102 | 103 | #[cfg(any(target_pointer_width = "64", target_pointer_width = "128",))] 104 | SmallUnsignedLabel::U64 => SmallNodeDispatch::NodeU64(Node::::new(key, val)), 105 | 106 | #[cfg(target_pointer_width = "128")] 107 | SmallUnsignedLabel::U128 => SmallNodeDispatch::NodeU128(Node::::new(key, val)), 108 | 109 | _ => unreachable!() 110 | } 111 | } 112 | } 113 | 114 | macro_rules! dispatch { 115 | ( $self:ident, $func:ident $(, $args:expr)* $(,)? ) => { 116 | match $self { 117 | SmallNodeDispatch::NodeUSIZE(node) => node.$func($($args,)*), 118 | SmallNodeDispatch::NodeU8(node) => node.$func($($args,)*), 119 | 120 | #[cfg(any( 121 | target_pointer_width = "16", 122 | target_pointer_width = "32", 123 | target_pointer_width = "64", 124 | target_pointer_width = "128", 125 | ))] 126 | SmallNodeDispatch::NodeU16(node) => node.$func($($args,)*), 127 | 128 | #[cfg(any( 129 | target_pointer_width = "32", 130 | target_pointer_width = "64", 131 | target_pointer_width = "128", 132 | ))] 133 | SmallNodeDispatch::NodeU32(node) => node.$func($($args,)*), 134 | 135 | #[cfg(any(target_pointer_width = "64", target_pointer_width = "128",))] 136 | SmallNodeDispatch::NodeU64(node) => node.$func($($args,)*), 137 | 138 | #[cfg(target_pointer_width = "128")] 139 | SmallNodeDispatch::NodeU128(node) => node.$func($($args,)*), 140 | } 141 | }; 142 | } 143 | 144 | impl SmallNode for SmallNodeDispatch { 145 | fn key(&self) -> &K { 146 | dispatch!(self, key) 147 | } 148 | 149 | fn set_key(&mut self, key: K) { 150 | dispatch!(self, set_key, key); 151 | } 152 | 153 | fn take_key(&mut self) -> K { 154 | dispatch!(self, take_key) 155 | } 156 | 157 | fn val(&self) -> &V { 158 | dispatch!(self, val) 159 | } 160 | 161 | fn get_mut(&mut self) -> (&K, &mut V) { 162 | dispatch!(self, get_mut) 163 | } 164 | 165 | fn set_val(&mut self, val: V) { 166 | dispatch!(self, set_val, val); 167 | } 168 | 169 | fn take_val(&mut self) -> V { 170 | dispatch!(self, take_val) 171 | } 172 | 173 | fn left_idx(&self) -> Option { 174 | dispatch!(self, left_idx) 175 | } 176 | 177 | fn set_left_idx(&mut self, opt_idx: Option) { 178 | dispatch!(self, set_left_idx, opt_idx); 179 | } 180 | 181 | fn right_idx(&self) -> Option { 182 | dispatch!(self, right_idx) 183 | } 184 | 185 | fn set_right_idx(&mut self, opt_idx: Option) { 186 | dispatch!(self, set_right_idx, opt_idx); 187 | } 188 | 189 | #[cfg(feature = "fast_rebalance")] 190 | fn subtree_size(&self) -> usize { 191 | dispatch!(self, subtree_size) 192 | } 193 | 194 | #[cfg(feature = "fast_rebalance")] 195 | fn set_subtree_size(&mut self, size: usize) { 196 | dispatch!(self, set_subtree_size, size); 197 | } 198 | } 199 | */ 200 | -------------------------------------------------------------------------------- /code_snippets/chp2/crypto_tool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["rc4", "rcli"] 4 | 5 | [profile.release] 6 | strip = true 7 | -------------------------------------------------------------------------------- /code_snippets/chp2/crypto_tool/rc4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rc4" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [features] 11 | naive_backdoor = [] 12 | -------------------------------------------------------------------------------- /code_snippets/chp2/crypto_tool/rcli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rcli" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | rc4 = { path = "../rc4" } 10 | clap = { version = "^4", features = ["derive"] } 11 | -------------------------------------------------------------------------------- /code_snippets/chp2/crypto_tool/rcli/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: full_imports 2 | use clap::Parser; 3 | use rc4::Rc4; 4 | use std::fs::File; 5 | use std::io::prelude::{Read, Seek, Write}; 6 | // ANCHOR_END: full_imports 7 | 8 | // ANCHOR: clap_args 9 | /// RC4 file en/decryption 10 | #[derive(Parser, Debug)] 11 | struct Args { 12 | /// Name of file to en/decrypt 13 | #[arg(short, long, required = true, value_name = "FILE_NAME")] 14 | file: String, 15 | 16 | /// En/Decryption key (hexadecimal bytes) 17 | #[arg( 18 | short, 19 | long, 20 | required = true, 21 | value_name = "HEX_BYTE", 22 | num_args = 5..=256, 23 | )] 24 | key: Vec, 25 | } 26 | // ANCHOR_END: clap_args 27 | 28 | // ANCHOR: cli_main 29 | fn main() -> std::io::Result<()> { 30 | let args = Args::parse(); 31 | let mut contents = Vec::new(); 32 | 33 | // Convert key strings to byte array 34 | let key_bytes = args 35 | .key 36 | .iter() 37 | .map(|s| s.trim_start_matches("0x")) 38 | .map(|s| u8::from_str_radix(s, 16).expect("Invalid key hex byte!")) 39 | .collect::>(); 40 | 41 | // Validation note: 42 | // `Args` enforces (5 <= key_bytes.len() && key_bytes.len() <= 256) 43 | 44 | // Open the file for both reading and writing 45 | let mut file = File::options().read(true).write(true).open(&args.file)?; 46 | 47 | // Read all file contents into memory 48 | file.read_to_end(&mut contents)?; 49 | 50 | // En/decrypt file contents in-memory 51 | Rc4::apply_keystream_static(&key_bytes, &mut contents); 52 | 53 | // Overwrite existing file with the result 54 | file.rewind()?; // "Seek" to start of file stream 55 | file.write_all(&contents)?; 56 | 57 | // Print success message 58 | println!("Processed {}", args.file); 59 | 60 | // Return success 61 | Ok(()) 62 | } 63 | // ANCHOR_END: cli_main 64 | -------------------------------------------------------------------------------- /code_snippets/chp3/c_snippets/scope.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int *p; // Pointer to an integer 5 | 6 | { // Start of scope A 7 | int x = 1337; // Value 8 | p = &x; // Reference to value 9 | } // End of scope A 10 | 11 | // Undefined behavior! :( 12 | std::cout << "x = " << *p << std::endl; 13 | return 0; 14 | } -------------------------------------------------------------------------------- /code_snippets/chp3/c_snippets/undef.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int undef_func() { 4 | int uninit_var; 5 | if (uninit_var > 0) { 6 | return 1; 7 | } else { 8 | return 0; 9 | } 10 | } 11 | 12 | int main() { 13 | printf("%d\n", undef_func()); 14 | } -------------------------------------------------------------------------------- /code_snippets/chp3/prime_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prime_test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp3/prime_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: prime_test 2 | 3 | //! This library does unoptimized primality testing. 4 | 5 | /// Given a list of numbers, get the count of prime numbers present. 6 | /// 7 | /// # Example 8 | /// 9 | /// ``` 10 | /// use prime_test::count_primes; 11 | /// 12 | /// let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 13 | /// assert_eq!(count_primes(&list), 4); 14 | /// ``` 15 | #[doc(alias = "primality")] 16 | pub fn count_primes(num_list: &[usize]) -> usize { 17 | // Unnecessary, unidiomatic check 18 | if num_list == [] { 19 | return 0; 20 | } 21 | 22 | num_list.iter().filter(|n| is_prime(**n)).count() 23 | } 24 | 25 | // Prime number check. 26 | // This is a naive implementation, 27 | // there are much more efficient implementations. 28 | // Returns `true` if `n` is prime, `false` if not. 29 | fn is_prime(n: usize) -> bool { 30 | if n <= 1 { 31 | return false; 32 | } 33 | 34 | for i in 2..n { 35 | if n % i == 0 { 36 | return false; 37 | } 38 | } 39 | 40 | true 41 | } 42 | // ANCHOR_END: prime_test 43 | 44 | #[cfg(test)] 45 | mod tests { 46 | use super::{count_primes, is_prime}; 47 | 48 | #[test] 49 | fn test_count_primes() { 50 | let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 51 | assert_eq!(count_primes(&list), 4); 52 | } 53 | 54 | #[test] 55 | fn test_is_prime() { 56 | // Positive 57 | assert!(is_prime(2)); 58 | assert!(is_prime(3)); 59 | assert!(is_prime(5)); 60 | assert!(is_prime(23)); 61 | assert!(is_prime(83)); 62 | assert!(is_prime(31)); 63 | 64 | // Negative 65 | assert!(!is_prime(1)); 66 | assert!(!is_prime(10)); 67 | assert!(!is_prime(300)); 68 | assert!(!is_prime(65)); 69 | assert!(!is_prime(74)); 70 | assert!(!is_prime(96)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /code_snippets/chp3/proc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp3/proc/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: detailed_state 2 | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] 3 | pub enum StopKind { 4 | Mandatory, // Linux SIGSTOP 5 | Ignorable, // Linux SIGTSTP 6 | } 7 | 8 | pub enum DetailedState { 9 | Running, 10 | Stopped { reason: StopKind }, 11 | Sleeping { start_time: u64 }, 12 | } 13 | // ANCHOR_END: detailed_state 14 | 15 | // ANCHOR: process_struct 16 | #[derive(Debug)] 17 | // ANCHOR: state 18 | pub enum State { 19 | Running, 20 | Stopped, 21 | Sleeping, 22 | } 23 | // ANCHOR_END: state 24 | 25 | #[derive(Debug)] 26 | pub struct Proc { 27 | name: &'static str, // Process name (update: nicer print than u32 pid) 28 | state: State, // Current state 29 | children: Vec, // Children (update: now owned!) 30 | } 31 | 32 | impl Proc { 33 | pub fn new(name: &'static str, state: State, children: Vec) -> Self { 34 | Proc { 35 | name, 36 | state, 37 | children, 38 | } 39 | } 40 | } 41 | // ANCHOR_END: process_struct 42 | 43 | // ANCHOR: drop 44 | impl Drop for Proc { 45 | fn drop(&mut self) { 46 | println!("De-alloc-ing \'{}\' Proc @ {:p}", self.name, self); 47 | } 48 | } 49 | // ANCHOR_END: drop 50 | 51 | fn main() { 52 | // ANCHOR: initial_tree 53 | // Build process tree using 3 "moves" (more info soon): 54 | // 55 | // init 56 | // |- cron 57 | // |- rsyslogd 58 | // |- bash 59 | // 60 | // Run "pstree -n -g" (in container) to see your OS's real process tree! 61 | 62 | // Alloc bash 63 | let bash = Proc::new("bash", State::Running, Vec::new()); 64 | 65 | // Alloc rsyslogd, 1st move: bash -> rsyslogd 66 | let rsyslogd = Proc::new("rsyslogd", State::Running, vec![bash]); 67 | 68 | // Alloc cron 69 | let cron = Proc::new("cron", State::Sleeping, Vec::new()); 70 | 71 | // Alloc init, 2nd and 3rd moves: cron -> init, rsyslogd -> init 72 | let init = Proc::new("init", State::Running, vec![cron, rsyslogd]); 73 | 74 | // Print serialized tree to see ownership hierarchy 75 | dbg!(init); 76 | // ANCHOR_END: initial_tree 77 | } 78 | 79 | #[cfg(test)] 80 | mod tests { 81 | use super::{DetailedState, Proc, State, StopKind}; 82 | 83 | #[test] 84 | fn test_size() { 85 | assert_eq!(core::mem::size_of::(), 48); 86 | } 87 | 88 | #[test] 89 | fn test_stop_match() { 90 | let s = State::Stopped; 91 | match s { 92 | State::Running => unreachable!(), 93 | State::Stopped => {} 94 | State::Sleeping => unreachable!(), 95 | } 96 | } 97 | 98 | #[test] 99 | fn test_detailed_stop_match() { 100 | let s = DetailedState::Stopped { 101 | reason: StopKind::Mandatory, 102 | }; 103 | match s { 104 | DetailedState::Stopped { reason } => { 105 | assert_eq!(reason, StopKind::Mandatory); 106 | } 107 | _ => unreachable!(), 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /code_snippets/chp3/proc_2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proc_2" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp3/proc_2/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: detailed_state 2 | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] 3 | pub enum StopKind { 4 | Mandatory, // Linux SIGSTOP 5 | Ignorable, // Linux SIGTSTP 6 | } 7 | 8 | #[derive(Debug)] 9 | pub enum DetailedState { 10 | Running, 11 | Stopped { reason: StopKind }, 12 | Sleeping { wake_time: u64 }, 13 | } 14 | // ANCHOR_END: detailed_state 15 | 16 | // ANCHOR: state 17 | #[derive(Debug)] 18 | pub enum State { 19 | Running, 20 | Stopped, 21 | Sleeping, 22 | } 23 | // ANCHOR_END: state 24 | 25 | // ANCHOR: process_struct 26 | #[derive(Debug)] 27 | pub struct Proc<'a> { 28 | name: &'static str, // Process name 29 | state: State, // Current state 30 | children: Vec<&'a Proc<'a>>, // Children (update: now borrowed!) 31 | } 32 | 33 | impl<'a> Proc<'a> { 34 | pub fn new(name: &'static str, state: State, children: Vec<&'a Proc>) -> Self { 35 | Proc { 36 | name, 37 | state, 38 | children, 39 | } 40 | } 41 | } 42 | // ANCHOR_END: process_struct 43 | 44 | // ANCHOR: drop 45 | impl Drop for Proc<'_> { 46 | fn drop(&mut self) { 47 | println!("De-alloc-ing \'{}\' proc @ {:p}", self.name, self); 48 | } 49 | } 50 | // ANCHOR_END: drop 51 | 52 | fn main() { 53 | // ANCHOR: initial_tree 54 | // Alloc bash 55 | let bash = Proc::new("bash", State::Running, Vec::new()); 56 | 57 | // Alloc rsyslogd, 1st move: bash -> rsyslogd 58 | let rsyslogd = Proc::new("rsyslogd", State::Running, vec![&bash]); 59 | 60 | // Print owned value (new!) 61 | dbg!(&bash); 62 | 63 | // Alloc cron 64 | let cron = Proc::new("cron", State::Sleeping, Vec::new()); 65 | 66 | // Alloc init, 2nd and 3rd moves: cron -> init, rsyslogd -> init 67 | let init = Proc::new("init", State::Running, vec![&cron, &rsyslogd]); 68 | 69 | // Print another owned value (new!) 70 | dbg!(&cron); 71 | 72 | // Print serialized tree to see ownership hierarchy 73 | dbg!(&init); 74 | // ANCHOR_END: initial_tree 75 | } 76 | 77 | #[cfg(test)] 78 | mod tests { 79 | use super::{DetailedState, Proc, State, StopKind}; 80 | 81 | #[test] 82 | fn test_size() { 83 | assert_eq!(core::mem::size_of::(), 48); 84 | } 85 | 86 | #[test] 87 | fn test_stop_match() { 88 | let s = State::Stopped; 89 | match s { 90 | State::Running => unreachable!(), 91 | State::Stopped => {} 92 | State::Sleeping => unreachable!(), 93 | } 94 | } 95 | 96 | #[test] 97 | fn test_detailed_stop_match() { 98 | let s = DetailedState::Stopped { 99 | reason: StopKind::Mandatory, 100 | }; 101 | match s { 102 | DetailedState::Stopped { reason } => { 103 | assert_eq!(reason, StopKind::Mandatory); 104 | } 105 | _ => unreachable!(), 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /code_snippets/chp3/rc4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rc4" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [features] 11 | naive_backdoor = [] 12 | -------------------------------------------------------------------------------- /code_snippets/chp3/rc4/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(test), no_std)] 2 | #![forbid(unsafe_code)] 3 | #[allow(warnings)] 4 | #[derive(Debug)] 5 | pub struct Rc4 { 6 | s: [u8; 256], 7 | i: u8, 8 | j: u8, 9 | } 10 | 11 | // ANCHOR: new_error_handling 12 | #[derive(Debug)] 13 | pub enum Rc4Error { 14 | KeyTooShort(usize), 15 | KeyTooLong(usize), 16 | } 17 | 18 | impl Rc4 { 19 | /// Init a new Rc4 stream cipher instance 20 | pub fn new(key: &[u8]) -> Result { 21 | const MIN_KEY_LEN: usize = 5; 22 | const MAX_KEY_LEN: usize = 256; 23 | 24 | // Verify valid key length (40 to 2048 bits) 25 | if key.len() < MIN_KEY_LEN { 26 | return Err(Rc4Error::KeyTooShort(MIN_KEY_LEN)); 27 | } else if key.len() > MAX_KEY_LEN { 28 | return Err(Rc4Error::KeyTooLong(MAX_KEY_LEN)); 29 | } 30 | 31 | // Zero-init our struct 32 | let mut rc4 = Rc4 { 33 | s: [0; 256], 34 | i: 0, 35 | j: 0, 36 | }; 37 | 38 | // ...more initialization code here... 39 | 40 | // Return our initialized Rc4 41 | Ok(rc4) 42 | } 43 | } 44 | // ANCHOR_END: new_error_handling 45 | 46 | #[cfg(test)] 47 | mod tests { 48 | #[allow(warnings)] 49 | use super::{Rc4, Rc4Error}; 50 | 51 | // TODO: add error test 52 | #[test] 53 | fn test_new() { 54 | let key = [0x1, 0x2, 0x3]; 55 | match Rc4::new(&key) { 56 | Ok(rc4) => println!("Do en/decryption here!"), 57 | Err(e) => match e { 58 | Rc4Error::KeyTooShort(min) => eprintln!("Key len >= {} bytes required!", min), 59 | Rc4Error::KeyTooLong(max) => eprintln!("Key len <= {} bytes required!", max), 60 | }, 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /code_snippets/chp4/c_snippets/spatial.c: -------------------------------------------------------------------------------- 1 | #include // assert 2 | #include // puts 3 | #include // strncpy 4 | #include // malloc 5 | 6 | char* get_greeting() { 7 | char* greeting = (char*)malloc(6); 8 | if (greeting == NULL) { 9 | return NULL; 10 | } else { 11 | strncpy(greeting, "Hello", 6); 12 | assert(greeting[5] == '\0'); 13 | return greeting; 14 | } 15 | } 16 | 17 | int main() { 18 | char* greeting = get_greeting(); 19 | if (greeting != NULL) { 20 | // Buffer overwrite, spatial safety violation! 21 | greeting[12] = '!'; 22 | 23 | puts(greeting); 24 | free(greeting); 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /code_snippets/chp4/c_snippets/temporal.c: -------------------------------------------------------------------------------- 1 | #include // assert 2 | #include // puts 3 | #include // strncpy, strlen 4 | #include // malloc 5 | 6 | char* get_greeting() { 7 | char* greeting = (char*)malloc(6); 8 | if (greeting == NULL) { 9 | return NULL; 10 | } else { 11 | strncpy(greeting, "Hello", 6); 12 | assert(greeting[5] == '\0'); 13 | return greeting; 14 | } 15 | } 16 | 17 | int main() { 18 | char* greeting = get_greeting(); 19 | size_t greeting_len = strlen(greeting); // Excludes null byte 20 | if (greeting != NULL) { 21 | // Append "!" correctly 22 | greeting = (char*)realloc(greeting, greeting_len + 2); 23 | if (greeting != NULL) { 24 | // strcat could be used here instead of the two lines below 25 | greeting[greeting_len] = '!'; 26 | greeting[greeting_len + 1] = '\0'; 27 | } 28 | puts(greeting); 29 | free(greeting); 30 | } 31 | 32 | // Double-free, temporal safety violation! 33 | free(greeting); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /code_snippets/chp4/c_snippets/type.c: -------------------------------------------------------------------------------- 1 | #include // assert 2 | #include // puts 3 | #include // strncpy, strlen 4 | #include // malloc 5 | 6 | #define TYPE_NEW_USR 1 // New user, to be greeted 7 | #define TYPE_CUR_USR 2 // Current user, increment visit count 8 | 9 | struct user_record_t { 10 | int type; 11 | union { 12 | char *greeting; 13 | unsigned visit_count; 14 | }; 15 | }; 16 | 17 | int main() { 18 | struct user_record_t rec; 19 | 20 | rec.type = TYPE_NEW_USR; 21 | rec.greeting = "Hello!"; 22 | 23 | // Logic error: should be `TYPE_CUR_USR` 24 | if (rec.type == TYPE_NEW_USR) { 25 | rec.visit_count += 1; // Type confusion, a type safety violation! 26 | } 27 | 28 | if (rec.type == TYPE_NEW_USR) { 29 | printf("%s\n", rec.greeting); 30 | } 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /code_snippets/chp4/greeting/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greeting" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp4/greeting/src/main.rs: -------------------------------------------------------------------------------- 1 | fn get_greeting() -> String { 2 | String::from("Hello") 3 | } 4 | 5 | fn main() { 6 | let mut greeting = get_greeting(); 7 | greeting.push('!'); 8 | println!("{}", greeting); 9 | } 10 | -------------------------------------------------------------------------------- /code_snippets/chp4/stack_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stack_example" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp4/stack_example/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: stack_example 2 | // ANCHOR: recursive_count_down 3 | #[inline(never)] 4 | fn recursive_count_down(x: usize) -> usize { 5 | // Base case 6 | if x == 0 { 7 | println!("Boom!"); 8 | return x; 9 | // Recursive case 10 | } else { 11 | println!("{x}..."); 12 | return recursive_count_down(x - 1); 13 | } 14 | } 15 | // ANCHOR_END: recursive_count_down 16 | 17 | #[inline(never)] 18 | fn square(x: usize) -> usize { 19 | x * x 20 | } 21 | 22 | fn main() { 23 | let args: Vec = std::env::args().collect(); 24 | 25 | // 1st arg is binary name, e.g. "./stack_example 2" 26 | assert!(args.len() <= 2, "Too many arguments - enter one number"); 27 | 28 | let x = args 29 | .iter() 30 | .nth(1) 31 | .expect("No arguments") 32 | .parse() 33 | .expect("Please provide a number"); 34 | 35 | let _ = recursive_count_down(square(x)); 36 | } 37 | // ANCHOR_END: stack_example 38 | -------------------------------------------------------------------------------- /code_snippets/chp4/stack_example_iter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stack_example_iter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /code_snippets/chp4/stack_example_iter/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: iterative_count_down 2 | #[inline(never)] 3 | fn iterative_count_down(x: usize) { 4 | for i in (0..=x).rev() { 5 | match i { 6 | i if i == 0 => println!("Boom!"), 7 | _ => println!("{i}..."), 8 | } 9 | } 10 | } 11 | // ANCHOR_END: iterative_count_down 12 | 13 | #[inline(never)] 14 | fn square(x: usize) -> usize { 15 | x * x 16 | } 17 | 18 | fn main() { 19 | let args: Vec = std::env::args().collect(); 20 | 21 | // 1st arg is binary name, e.g. "./stack_example 2" 22 | assert!(args.len() <= 2, "Too many arguments - enter one number"); 23 | 24 | let x = args 25 | .iter() 26 | .nth(1) 27 | .expect("No arguments") 28 | .parse() 29 | .expect("Please provide a number"); 30 | 31 | iterative_count_down(square(x)); 32 | } 33 | -------------------------------------------------------------------------------- /docker_aarch64/Dockerfile: -------------------------------------------------------------------------------- 1 | # aarch64 (Apple silicon, etc) 2 | FROM arm64v8/rust:1.59-slim 3 | 4 | # Non-Rust tooling 5 | ENV TZ=US/New_York 6 | RUN apt-get update -y 7 | RUN DEBIAN_FRONTEND="noninteractive" apt-get update && apt-get install -y \ 8 | build-essential \ 9 | libssl-dev \ 10 | pkg-config \ 11 | tree \ 12 | xxd \ 13 | git \ 14 | vim 15 | 16 | # Rust tooling 17 | RUN rustup toolchain install nightly 18 | RUN rustup component add llvm-tools-preview 19 | RUN cargo install mdbook 20 | RUN cargo install cargo-fuzz 21 | RUN cargo install cargo-binutils 22 | RUN cargo install cargo-modules 23 | RUN cargo install cargo-audit 24 | 25 | # Src import 26 | RUN mkdir /code_snippets 27 | WORKDIR /code_snippets 28 | COPY ./code_snippets /code_snippets/ -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | This file makes sure that Github Pages doesn't process mdBook's output. 2 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | highassurance.rs -------------------------------------------------------------------------------- /docs/FontAwesome/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/FontAwesome/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /docs/FontAwesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/FontAwesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/FontAwesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/FontAwesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/FontAwesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/FontAwesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/FontAwesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/FontAwesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/ayu-highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | Based off of the Ayu theme 3 | Original by Dempfi (https://github.com/dempfi/ayu) 4 | */ 5 | 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | background: #191f26; 10 | color: #e6e1cf; 11 | } 12 | 13 | .hljs-comment, 14 | .hljs-quote { 15 | color: #5c6773; 16 | font-style: italic; 17 | } 18 | 19 | .hljs-variable, 20 | .hljs-template-variable, 21 | .hljs-attribute, 22 | .hljs-attr, 23 | .hljs-regexp, 24 | .hljs-link, 25 | .hljs-selector-id, 26 | .hljs-selector-class { 27 | color: #ff7733; 28 | } 29 | 30 | .hljs-number, 31 | .hljs-meta, 32 | .hljs-builtin-name, 33 | .hljs-literal, 34 | .hljs-type, 35 | .hljs-params { 36 | color: #ffee99; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-bullet { 41 | color: #b8cc52; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-built_in, 46 | .hljs-section { 47 | color: #ffb454; 48 | } 49 | 50 | .hljs-keyword, 51 | .hljs-selector-tag, 52 | .hljs-symbol { 53 | color: #ff7733; 54 | } 55 | 56 | .hljs-name { 57 | color: #36a3d9; 58 | } 59 | 60 | .hljs-tag { 61 | color: #00568d; 62 | } 63 | 64 | .hljs-emphasis { 65 | font-style: italic; 66 | } 67 | 68 | .hljs-strong { 69 | font-weight: bold; 70 | } 71 | 72 | .hljs-addition { 73 | color: #91b362; 74 | } 75 | 76 | .hljs-deletion { 77 | color: #d96c75; 78 | } 79 | -------------------------------------------------------------------------------- /docs/chp1/bugs_venn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Bugs Unique to
Memory-Safe
Languages
Bugs Unique to...
Bugs Unique to
Memory-Unsafe
Languages
Bugs Unique to...

Bugs
Agnostic to
Language
Bugs...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /docs/chp3/building_blocks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Module
Module
Item
Item

Crate (lib or bin)
Crate (lib or bin)...

System
System...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /docs/chp3/count_primes_doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/chp3/count_primes_doc.png -------------------------------------------------------------------------------- /docs/css/general.css: -------------------------------------------------------------------------------- 1 | /* Base styles and content styles */ 2 | 3 | @import 'variables.css'; 4 | 5 | :root { 6 | /* Browser default font-size is 16px, this way 1 rem = 10px */ 7 | font-size: 62.5%; 8 | color-scheme: var(--color-scheme); 9 | } 10 | 11 | html { 12 | font-family: "Open Sans", sans-serif; 13 | color: var(--fg); 14 | background-color: var(--bg); 15 | text-size-adjust: none; 16 | -webkit-text-size-adjust: none; 17 | } 18 | 19 | body { 20 | margin: 0; 21 | font-size: 1.6rem; 22 | overflow-x: hidden; 23 | } 24 | 25 | code { 26 | font-family: var(--mono-font) !important; 27 | font-size: var(--code-font-size); 28 | direction: ltr !important; 29 | } 30 | 31 | /* make long words/inline code not x overflow */ 32 | main { 33 | overflow-wrap: break-word; 34 | } 35 | 36 | /* make wide tables scroll if they overflow */ 37 | .table-wrapper { 38 | overflow-x: auto; 39 | } 40 | 41 | /* Don't change font size in headers. */ 42 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { 43 | font-size: unset; 44 | } 45 | 46 | .left { float: left; } 47 | .right { float: right; } 48 | .boring { opacity: 0.6; } 49 | .hide-boring .boring { display: none; } 50 | .hidden { display: none !important; } 51 | 52 | h2, h3 { margin-block-start: 2.5em; } 53 | h4, h5 { margin-block-start: 2em; } 54 | 55 | .header + .header h3, 56 | .header + .header h4, 57 | .header + .header h5 { 58 | margin-block-start: 1em; 59 | } 60 | 61 | h1:target::before, 62 | h2:target::before, 63 | h3:target::before, 64 | h4:target::before, 65 | h5:target::before, 66 | h6:target::before { 67 | display: inline-block; 68 | content: "»"; 69 | margin-inline-start: -30px; 70 | width: 30px; 71 | } 72 | 73 | /* This is broken on Safari as of version 14, but is fixed 74 | in Safari Technology Preview 117 which I think will be Safari 14.2. 75 | https://bugs.webkit.org/show_bug.cgi?id=218076 76 | */ 77 | :target { 78 | /* Safari does not support logical properties */ 79 | scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); 80 | } 81 | 82 | .page { 83 | outline: 0; 84 | padding: 0 var(--page-padding); 85 | margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ 86 | } 87 | .page-wrapper { 88 | box-sizing: border-box; 89 | background-color: var(--bg); 90 | } 91 | .no-js .page-wrapper, 92 | .js:not(.sidebar-resizing) .page-wrapper { 93 | transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ 94 | } 95 | [dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { 96 | transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ 97 | } 98 | 99 | .content { 100 | overflow-y: auto; 101 | padding: 0 5px 50px 5px; 102 | } 103 | .content main { 104 | margin-inline-start: auto; 105 | margin-inline-end: auto; 106 | max-width: var(--content-max-width); 107 | } 108 | .content p { line-height: 1.45em; } 109 | .content ol { line-height: 1.45em; } 110 | .content ul { line-height: 1.45em; } 111 | .content a { text-decoration: none; } 112 | .content a:hover { text-decoration: underline; } 113 | .content img, .content video { max-width: 100%; } 114 | .content .header:link, 115 | .content .header:visited { 116 | color: var(--fg); 117 | } 118 | .content .header:link, 119 | .content .header:visited:hover { 120 | text-decoration: none; 121 | } 122 | 123 | table { 124 | margin: 0 auto; 125 | border-collapse: collapse; 126 | } 127 | table td { 128 | padding: 3px 20px; 129 | border: 1px var(--table-border-color) solid; 130 | } 131 | table thead { 132 | background: var(--table-header-bg); 133 | } 134 | table thead td { 135 | font-weight: 700; 136 | border: none; 137 | } 138 | table thead th { 139 | padding: 3px 20px; 140 | } 141 | table thead tr { 142 | border: 1px var(--table-header-bg) solid; 143 | } 144 | /* Alternate background colors for rows */ 145 | table tbody tr:nth-child(2n) { 146 | background: var(--table-alternate-bg); 147 | } 148 | 149 | 150 | blockquote { 151 | margin: 20px 0; 152 | padding: 0 20px; 153 | color: var(--fg); 154 | background-color: var(--quote-bg); 155 | border-block-start: .1em solid var(--quote-border); 156 | border-block-end: .1em solid var(--quote-border); 157 | } 158 | 159 | .warning { 160 | margin: 20px; 161 | padding: 0 20px; 162 | border-inline-start: 2px solid var(--warning-border); 163 | } 164 | 165 | .warning:before { 166 | position: absolute; 167 | width: 3rem; 168 | height: 3rem; 169 | margin-inline-start: calc(-1.5rem - 21px); 170 | content: "ⓘ"; 171 | text-align: center; 172 | background-color: var(--bg); 173 | color: var(--warning-border); 174 | font-weight: bold; 175 | font-size: 2rem; 176 | } 177 | 178 | blockquote .warning:before { 179 | background-color: var(--quote-bg); 180 | } 181 | 182 | kbd { 183 | background-color: var(--table-border-color); 184 | border-radius: 4px; 185 | border: solid 1px var(--theme-popup-border); 186 | box-shadow: inset 0 -1px 0 var(--theme-hover); 187 | display: inline-block; 188 | font-size: var(--code-font-size); 189 | font-family: var(--mono-font); 190 | line-height: 10px; 191 | padding: 4px 5px; 192 | vertical-align: middle; 193 | } 194 | 195 | :not(.footnote-definition) + .footnote-definition, 196 | .footnote-definition + :not(.footnote-definition) { 197 | margin-block-start: 2em; 198 | } 199 | .footnote-definition { 200 | font-size: 0.9em; 201 | margin: 0.5em 0; 202 | } 203 | .footnote-definition p { 204 | display: inline; 205 | } 206 | 207 | .tooltiptext { 208 | position: absolute; 209 | visibility: hidden; 210 | color: #fff; 211 | background-color: #333; 212 | transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ 213 | left: -8px; /* Half of the width of the icon */ 214 | top: -35px; 215 | font-size: 0.8em; 216 | text-align: center; 217 | border-radius: 6px; 218 | padding: 5px 8px; 219 | margin: 5px; 220 | z-index: 1000; 221 | } 222 | .tooltipped .tooltiptext { 223 | visibility: visible; 224 | } 225 | 226 | .chapter li.part-title { 227 | color: var(--sidebar-fg); 228 | margin: 5px 0px; 229 | font-weight: bold; 230 | } 231 | 232 | .result-no-output { 233 | font-style: italic; 234 | } 235 | -------------------------------------------------------------------------------- /docs/css/print.css: -------------------------------------------------------------------------------- 1 | 2 | #sidebar, 3 | #menu-bar, 4 | .nav-chapters, 5 | .mobile-nav-chapters { 6 | display: none; 7 | } 8 | 9 | #page-wrapper.page-wrapper { 10 | transform: none; 11 | margin-inline-start: 0px; 12 | overflow-y: initial; 13 | } 14 | 15 | #content { 16 | max-width: none; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .page { 22 | overflow-y: initial; 23 | } 24 | 25 | code { 26 | direction: ltr !important; 27 | } 28 | 29 | pre > .buttons { 30 | z-index: 2; 31 | } 32 | 33 | a, a:visited, a:active, a:hover { 34 | color: #4183c4; 35 | text-decoration: none; 36 | } 37 | 38 | h1, h2, h3, h4, h5, h6 { 39 | page-break-inside: avoid; 40 | page-break-after: avoid; 41 | } 42 | 43 | pre, code { 44 | page-break-inside: avoid; 45 | white-space: pre-wrap; 46 | } 47 | 48 | .fa { 49 | display: none !important; 50 | } 51 | -------------------------------------------------------------------------------- /docs/css/variables.css: -------------------------------------------------------------------------------- 1 | 2 | /* Globals */ 3 | 4 | :root { 5 | --sidebar-width: 400px; 6 | --page-padding: 15px; 7 | --content-max-width: 800px; 8 | --menu-bar-height: 50px; 9 | } 10 | 11 | /* Themes */ 12 | 13 | .ayu { 14 | --bg: hsl(210, 25%, 8%); 15 | --fg: #c5c5c5; 16 | 17 | --sidebar-bg: #14191f; 18 | --sidebar-fg: #c8c9db; 19 | --sidebar-non-existant: #5c6773; 20 | --sidebar-active: #ffb454; 21 | --sidebar-spacer: #2d334f; 22 | 23 | --scrollbar: var(--sidebar-fg); 24 | 25 | --icons: #737480; 26 | --icons-hover: #b7b9cc; 27 | 28 | --links: #0096cf; 29 | 30 | --inline-code-color: #ffb454; 31 | 32 | --theme-popup-bg: #14191f; 33 | --theme-popup-border: #5c6773; 34 | --theme-hover: #191f26; 35 | 36 | --quote-bg: hsl(226, 15%, 17%); 37 | --quote-border: hsl(226, 15%, 22%); 38 | 39 | --table-border-color: hsl(210, 25%, 13%); 40 | --table-header-bg: hsl(210, 25%, 28%); 41 | --table-alternate-bg: hsl(210, 25%, 11%); 42 | 43 | --searchbar-border-color: #848484; 44 | --searchbar-bg: #424242; 45 | --searchbar-fg: #fff; 46 | --searchbar-shadow-color: #d4c89f; 47 | --searchresults-header-fg: #666; 48 | --searchresults-border-color: #888; 49 | --searchresults-li-bg: #252932; 50 | --search-mark-bg: #e3b171; 51 | } 52 | 53 | .coal { 54 | --bg: hsl(200, 7%, 8%); 55 | --fg: #98a3ad; 56 | 57 | --sidebar-bg: #292c2f; 58 | --sidebar-fg: #a1adb8; 59 | --sidebar-non-existant: #505254; 60 | --sidebar-active: #3473ad; 61 | --sidebar-spacer: #393939; 62 | 63 | --scrollbar: var(--sidebar-fg); 64 | 65 | --icons: #43484d; 66 | --icons-hover: #b3c0cc; 67 | 68 | --links: #2b79a2; 69 | 70 | --inline-code-color: #c5c8c6; 71 | 72 | --theme-popup-bg: #141617; 73 | --theme-popup-border: #43484d; 74 | --theme-hover: #1f2124; 75 | 76 | --quote-bg: hsl(234, 21%, 18%); 77 | --quote-border: hsl(234, 21%, 23%); 78 | 79 | --table-border-color: hsl(200, 7%, 13%); 80 | --table-header-bg: hsl(200, 7%, 28%); 81 | --table-alternate-bg: hsl(200, 7%, 11%); 82 | 83 | --searchbar-border-color: #aaa; 84 | --searchbar-bg: #b7b7b7; 85 | --searchbar-fg: #000; 86 | --searchbar-shadow-color: #aaa; 87 | --searchresults-header-fg: #666; 88 | --searchresults-border-color: #98a3ad; 89 | --searchresults-li-bg: #2b2b2f; 90 | --search-mark-bg: #355c7d; 91 | } 92 | 93 | .light { 94 | --bg: hsl(0, 0%, 100%); 95 | --fg: hsl(0, 0%, 0%); 96 | 97 | --sidebar-bg: #fafafa; 98 | --sidebar-fg: hsl(0, 0%, 0%); 99 | --sidebar-non-existant: #aaaaaa; 100 | --sidebar-active: #1f1fff; 101 | --sidebar-spacer: #f4f4f4; 102 | 103 | --scrollbar: #8F8F8F; 104 | 105 | --icons: #747474; 106 | --icons-hover: #000000; 107 | 108 | --links: #20609f; 109 | 110 | --inline-code-color: #301900; 111 | 112 | --theme-popup-bg: #fafafa; 113 | --theme-popup-border: #cccccc; 114 | --theme-hover: #e6e6e6; 115 | 116 | --quote-bg: hsl(197, 37%, 96%); 117 | --quote-border: hsl(197, 37%, 91%); 118 | 119 | --table-border-color: hsl(0, 0%, 95%); 120 | --table-header-bg: hsl(0, 0%, 80%); 121 | --table-alternate-bg: hsl(0, 0%, 97%); 122 | 123 | --searchbar-border-color: #aaa; 124 | --searchbar-bg: #fafafa; 125 | --searchbar-fg: #000; 126 | --searchbar-shadow-color: #aaa; 127 | --searchresults-header-fg: #666; 128 | --searchresults-border-color: #888; 129 | --searchresults-li-bg: #e4f2fe; 130 | --search-mark-bg: #a2cff5; 131 | } 132 | 133 | .navy { 134 | --bg: hsl(226, 23%, 11%); 135 | --fg: #bcbdd0; 136 | 137 | --sidebar-bg: #282d3f; 138 | --sidebar-fg: #c8c9db; 139 | --sidebar-non-existant: #505274; 140 | --sidebar-active: #2b79a2; 141 | --sidebar-spacer: #2d334f; 142 | 143 | --scrollbar: var(--sidebar-fg); 144 | 145 | --icons: #737480; 146 | --icons-hover: #b7b9cc; 147 | 148 | --links: #2b79a2; 149 | 150 | --inline-code-color: #c5c8c6; 151 | 152 | --theme-popup-bg: #161923; 153 | --theme-popup-border: #737480; 154 | --theme-hover: #282e40; 155 | 156 | --quote-bg: hsl(226, 15%, 17%); 157 | --quote-border: hsl(226, 15%, 22%); 158 | 159 | --table-border-color: hsl(226, 23%, 16%); 160 | --table-header-bg: hsl(226, 23%, 31%); 161 | --table-alternate-bg: hsl(226, 23%, 14%); 162 | 163 | --searchbar-border-color: #aaa; 164 | --searchbar-bg: #aeaec6; 165 | --searchbar-fg: #000; 166 | --searchbar-shadow-color: #aaa; 167 | --searchresults-header-fg: #5f5f71; 168 | --searchresults-border-color: #5c5c68; 169 | --searchresults-li-bg: #242430; 170 | --search-mark-bg: #a2cff5; 171 | } 172 | 173 | .rust { 174 | --bg: hsl(60, 9%, 87%); 175 | --fg: #262625; 176 | 177 | --sidebar-bg: #3b2e2a; 178 | --sidebar-fg: #c8c9db; 179 | --sidebar-non-existant: #505254; 180 | --sidebar-active: #e69f67; 181 | --sidebar-spacer: #45373a; 182 | 183 | --scrollbar: var(--sidebar-fg); 184 | 185 | --icons: #737480; 186 | --icons-hover: #262625; 187 | 188 | --links: #2b79a2; 189 | 190 | --inline-code-color: #6e6b5e; 191 | 192 | --theme-popup-bg: #e1e1db; 193 | --theme-popup-border: #b38f6b; 194 | --theme-hover: #99908a; 195 | 196 | --quote-bg: hsl(60, 5%, 75%); 197 | --quote-border: hsl(60, 5%, 70%); 198 | 199 | --table-border-color: hsl(60, 9%, 82%); 200 | --table-header-bg: #b3a497; 201 | --table-alternate-bg: hsl(60, 9%, 84%); 202 | 203 | --searchbar-border-color: #aaa; 204 | --searchbar-bg: #fafafa; 205 | --searchbar-fg: #000; 206 | --searchbar-shadow-color: #aaa; 207 | --searchresults-header-fg: #666; 208 | --searchresults-border-color: #888; 209 | --searchresults-li-bg: #dec2a2; 210 | --search-mark-bg: #e69f67; 211 | } 212 | 213 | @media (prefers-color-scheme: dark) { 214 | .light.no-js { 215 | --bg: hsl(200, 7%, 8%); 216 | --fg: #98a3ad; 217 | 218 | --sidebar-bg: #292c2f; 219 | --sidebar-fg: #a1adb8; 220 | --sidebar-non-existant: #505254; 221 | --sidebar-active: #3473ad; 222 | --sidebar-spacer: #393939; 223 | 224 | --scrollbar: var(--sidebar-fg); 225 | 226 | --icons: #43484d; 227 | --icons-hover: #b3c0cc; 228 | 229 | --links: #2b79a2; 230 | 231 | --inline-code-color: #c5c8c6; 232 | 233 | --theme-popup-bg: #141617; 234 | --theme-popup-border: #43484d; 235 | --theme-hover: #1f2124; 236 | 237 | --quote-bg: hsl(234, 21%, 18%); 238 | --quote-border: hsl(234, 21%, 23%); 239 | 240 | --table-border-color: hsl(200, 7%, 13%); 241 | --table-header-bg: hsl(200, 7%, 28%); 242 | --table-alternate-bg: hsl(200, 7%, 11%); 243 | 244 | --searchbar-border-color: #aaa; 245 | --searchbar-bg: #b7b7b7; 246 | --searchbar-fg: #000; 247 | --searchbar-shadow-color: #aaa; 248 | --searchresults-header-fg: #666; 249 | --searchresults-border-color: #98a3ad; 250 | --searchresults-li-bg: #2b2b2f; 251 | --search-mark-bg: #355c7d; 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/favicon.png -------------------------------------------------------------------------------- /docs/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/fonts/SOURCE-CODE-PRO-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /docs/fonts/fonts.css: -------------------------------------------------------------------------------- 1 | /* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ 2 | /* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ 3 | 4 | /* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 5 | @font-face { 6 | font-family: 'Open Sans'; 7 | font-style: normal; 8 | font-weight: 300; 9 | src: local('Open Sans Light'), local('OpenSans-Light'), 10 | url('open-sans-v17-all-charsets-300.woff2') format('woff2'); 11 | } 12 | 13 | /* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 14 | @font-face { 15 | font-family: 'Open Sans'; 16 | font-style: italic; 17 | font-weight: 300; 18 | src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), 19 | url('open-sans-v17-all-charsets-300italic.woff2') format('woff2'); 20 | } 21 | 22 | /* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 23 | @font-face { 24 | font-family: 'Open Sans'; 25 | font-style: normal; 26 | font-weight: 400; 27 | src: local('Open Sans Regular'), local('OpenSans-Regular'), 28 | url('open-sans-v17-all-charsets-regular.woff2') format('woff2'); 29 | } 30 | 31 | /* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 32 | @font-face { 33 | font-family: 'Open Sans'; 34 | font-style: italic; 35 | font-weight: 400; 36 | src: local('Open Sans Italic'), local('OpenSans-Italic'), 37 | url('open-sans-v17-all-charsets-italic.woff2') format('woff2'); 38 | } 39 | 40 | /* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 41 | @font-face { 42 | font-family: 'Open Sans'; 43 | font-style: normal; 44 | font-weight: 600; 45 | src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), 46 | url('open-sans-v17-all-charsets-600.woff2') format('woff2'); 47 | } 48 | 49 | /* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 50 | @font-face { 51 | font-family: 'Open Sans'; 52 | font-style: italic; 53 | font-weight: 600; 54 | src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), 55 | url('open-sans-v17-all-charsets-600italic.woff2') format('woff2'); 56 | } 57 | 58 | /* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 59 | @font-face { 60 | font-family: 'Open Sans'; 61 | font-style: normal; 62 | font-weight: 700; 63 | src: local('Open Sans Bold'), local('OpenSans-Bold'), 64 | url('open-sans-v17-all-charsets-700.woff2') format('woff2'); 65 | } 66 | 67 | /* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 68 | @font-face { 69 | font-family: 'Open Sans'; 70 | font-style: italic; 71 | font-weight: 700; 72 | src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), 73 | url('open-sans-v17-all-charsets-700italic.woff2') format('woff2'); 74 | } 75 | 76 | /* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 77 | @font-face { 78 | font-family: 'Open Sans'; 79 | font-style: normal; 80 | font-weight: 800; 81 | src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), 82 | url('open-sans-v17-all-charsets-800.woff2') format('woff2'); 83 | } 84 | 85 | /* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ 86 | @font-face { 87 | font-family: 'Open Sans'; 88 | font-style: italic; 89 | font-weight: 800; 90 | src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), 91 | url('open-sans-v17-all-charsets-800italic.woff2') format('woff2'); 92 | } 93 | 94 | /* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ 95 | @font-face { 96 | font-family: 'Source Code Pro'; 97 | font-style: normal; 98 | font-weight: 500; 99 | src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2'); 100 | } 101 | -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-300.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-300italic.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-600.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-600italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-600italic.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-700.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-700italic.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-800.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-800italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-800italic.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-italic.woff2 -------------------------------------------------------------------------------- /docs/fonts/open-sans-v17-all-charsets-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/open-sans-v17-all-charsets-regular.woff2 -------------------------------------------------------------------------------- /docs/fonts/source-code-pro-v11-all-charsets-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/fonts/source-code-pro-v11-all-charsets-500.woff2 -------------------------------------------------------------------------------- /docs/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | * An increased contrast highlighting scheme loosely based on the 3 | * "Base16 Atelier Dune Light" theme by Bram de Haan 4 | * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) 5 | * Original Base16 color scheme by Chris Kempson 6 | * (https://github.com/chriskempson/base16) 7 | */ 8 | 9 | /* Comment */ 10 | .hljs-comment, 11 | .hljs-quote { 12 | color: #575757; 13 | } 14 | 15 | /* Red */ 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-attribute, 19 | .hljs-tag, 20 | .hljs-name, 21 | .hljs-regexp, 22 | .hljs-link, 23 | .hljs-name, 24 | .hljs-selector-id, 25 | .hljs-selector-class { 26 | color: #d70025; 27 | } 28 | 29 | /* Orange */ 30 | .hljs-number, 31 | .hljs-meta, 32 | .hljs-built_in, 33 | .hljs-builtin-name, 34 | .hljs-literal, 35 | .hljs-type, 36 | .hljs-params { 37 | color: #b21e00; 38 | } 39 | 40 | /* Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet { 44 | color: #008200; 45 | } 46 | 47 | /* Blue */ 48 | .hljs-title, 49 | .hljs-section { 50 | color: #0030f2; 51 | } 52 | 53 | /* Purple */ 54 | .hljs-keyword, 55 | .hljs-selector-tag { 56 | color: #9d00ec; 57 | } 58 | 59 | .hljs { 60 | display: block; 61 | overflow-x: auto; 62 | background: #f6f7f6; 63 | color: #000; 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic; 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | 74 | .hljs-addition { 75 | color: #22863a; 76 | background-color: #f0fff4; 77 | } 78 | 79 | .hljs-deletion { 80 | color: #b31d28; 81 | background-color: #ffeef0; 82 | } 83 | -------------------------------------------------------------------------------- /docs/img/faq_venn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Systems
Programming
Systems...
Data
Structures
Data...
Software
Security
Software...
Rust
(Programming
Language)
Rust...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /docs/img/har_logo_social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/har_logo_social.png -------------------------------------------------------------------------------- /docs/img/recommended_books/book_c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_c.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_crypto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_crypto.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_csapp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_csapp.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_pba.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_pba.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_phil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_phil.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_rust_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_rust_1.jpg -------------------------------------------------------------------------------- /docs/img/recommended_books/book_rust_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/recommended_books/book_rust_2.jpg -------------------------------------------------------------------------------- /docs/img/rust_foundation_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/img/rust_foundation_logo.png -------------------------------------------------------------------------------- /docs/templates/placeholder_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/docs/templates/placeholder_img.png -------------------------------------------------------------------------------- /docs/tomorrow-night.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Theme */ 2 | /* https://github.com/jmblog/color-themes-for-highlightjs */ 3 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 4 | /* https://github.com/jmblog/color-themes-for-highlightjs */ 5 | 6 | /* Tomorrow Comment */ 7 | .hljs-comment { 8 | color: #969896; 9 | } 10 | 11 | /* Tomorrow Red */ 12 | .hljs-variable, 13 | .hljs-attribute, 14 | .hljs-tag, 15 | .hljs-regexp, 16 | .ruby .hljs-constant, 17 | .xml .hljs-tag .hljs-title, 18 | .xml .hljs-pi, 19 | .xml .hljs-doctype, 20 | .html .hljs-doctype, 21 | .css .hljs-id, 22 | .css .hljs-class, 23 | .css .hljs-pseudo { 24 | color: #cc6666; 25 | } 26 | 27 | /* Tomorrow Orange */ 28 | .hljs-number, 29 | .hljs-preprocessor, 30 | .hljs-pragma, 31 | .hljs-built_in, 32 | .hljs-literal, 33 | .hljs-params, 34 | .hljs-constant { 35 | color: #de935f; 36 | } 37 | 38 | /* Tomorrow Yellow */ 39 | .ruby .hljs-class .hljs-title, 40 | .css .hljs-rule .hljs-attribute { 41 | color: #f0c674; 42 | } 43 | 44 | /* Tomorrow Green */ 45 | .hljs-string, 46 | .hljs-value, 47 | .hljs-inheritance, 48 | .hljs-header, 49 | .hljs-name, 50 | .ruby .hljs-symbol, 51 | .xml .hljs-cdata { 52 | color: #b5bd68; 53 | } 54 | 55 | /* Tomorrow Aqua */ 56 | .hljs-title, 57 | .css .hljs-hexcolor { 58 | color: #8abeb7; 59 | } 60 | 61 | /* Tomorrow Blue */ 62 | .hljs-function, 63 | .python .hljs-decorator, 64 | .python .hljs-title, 65 | .ruby .hljs-function .hljs-title, 66 | .ruby .hljs-title .hljs-keyword, 67 | .perl .hljs-sub, 68 | .javascript .hljs-title, 69 | .coffeescript .hljs-title { 70 | color: #81a2be; 71 | } 72 | 73 | /* Tomorrow Purple */ 74 | .hljs-keyword, 75 | .javascript .hljs-function { 76 | color: #b294bb; 77 | } 78 | 79 | .hljs { 80 | display: block; 81 | overflow-x: auto; 82 | background: #1d1f21; 83 | color: #c5c8c6; 84 | } 85 | 86 | .coffeescript .javascript, 87 | .javascript .xml, 88 | .tex .hljs-formula, 89 | .xml .javascript, 90 | .xml .vbscript, 91 | .xml .css, 92 | .xml .hljs-cdata { 93 | opacity: 0.5; 94 | } 95 | 96 | .hljs-addition { 97 | color: #718c00; 98 | } 99 | 100 | .hljs-deletion { 101 | color: #c82829; 102 | } 103 | -------------------------------------------------------------------------------- /img/rust_foundation_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/img/rust_foundation_logo.png -------------------------------------------------------------------------------- /internal_tools/har_analyze/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "har_analyze" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Tiemoko Ballo"] 6 | description = "Internal tooling for https://highassurance.rs/" 7 | 8 | [dependencies] 9 | clap = { version = "4", features = ["derive"] } 10 | colored = "2" 11 | color-eyre = "0.6" 12 | lazy_static = "1" 13 | rayon = "1" 14 | regex = "1" 15 | separator = "0.4" 16 | scraper = "0.17" 17 | svg = "0.14" 18 | walkdir = "2" 19 | 20 | [lib] 21 | name = "har_analyze" 22 | path = "src/mod.rs" 23 | 24 | [[bin]] 25 | name = "har_analyze" 26 | path = "src/main.rs" 27 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/chapter.rs: -------------------------------------------------------------------------------- 1 | use crate::{content::Content, traits::GetMetrics, WORDS_PER_PAGE}; 2 | use colored::*; 3 | use separator::Separatable; 4 | use std::{ffi::OsStr, fmt}; 5 | 6 | /// Displayable chapter data model 7 | pub struct Chapter { 8 | /// Chapter contents 9 | pub contents: Vec, 10 | pub(crate) number: usize, 11 | } 12 | 13 | impl GetMetrics for Chapter { 14 | fn get_word_count(&self) -> usize { 15 | self.contents 16 | .iter() 17 | .map(|c| match c { 18 | Content::Section { word_count, .. } => word_count, 19 | Content::Svg { .. } => &0, 20 | }) 21 | .sum() 22 | } 23 | 24 | fn get_diagram_count(&self) -> usize { 25 | self.contents 26 | .iter() 27 | .map(|c| match c { 28 | Content::Section { .. } => 0, 29 | Content::Svg { .. } => 1, 30 | }) 31 | .sum() 32 | } 33 | } 34 | 35 | impl fmt::Display for Chapter { 36 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 | let word_count = self.get_word_count(); 38 | writeln!( 39 | f, 40 | "{}{} {} words ({} pages), {} diagrams", 41 | match self.number { 42 | 0 => "(frontmatter):".yellow(), 43 | _ => "chp ".yellow(), 44 | }, 45 | match self.number { 46 | 0 => "".yellow(), 47 | _ => (self.number.to_string() + ":").yellow(), 48 | }, 49 | word_count.separated_string().bright_green(), 50 | (word_count / WORDS_PER_PAGE) 51 | .separated_string() 52 | .bright_cyan(), 53 | self.get_diagram_count().separated_string().bright_blue() 54 | )?; 55 | 56 | for content in self.contents.iter() { 57 | match content { 58 | Content::Section { 59 | path, word_count, .. 60 | } => { 61 | if let Some(file_name) = path.as_path().file_name().and_then(OsStr::to_str) { 62 | writeln!( 63 | f, 64 | " - {}: {}", 65 | file_name.bright_magenta(), 66 | word_count.separated_string().bright_green() 67 | )?; 68 | } 69 | } 70 | Content::Svg { .. } => continue, 71 | } 72 | } 73 | 74 | Ok(()) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/content.rs: -------------------------------------------------------------------------------- 1 | use crate::traits::GetChapter; 2 | use std::path::PathBuf; 3 | 4 | /// Displayable content data model 5 | #[derive(Debug)] 6 | #[cfg_attr(test, derive(PartialEq))] 7 | pub enum Content { 8 | /// An individual X.Y book section or chapter intro 9 | Section { 10 | /// Section path 11 | path: PathBuf, 12 | /// Section data (optionally collected, line-oriented) 13 | lines: Option>, 14 | /// Section word count 15 | word_count: usize, 16 | }, 17 | /// An individual diagram 18 | Svg { 19 | /// Diagram path 20 | path: PathBuf, 21 | /// SVG data (optionally collected, line-oriented) 22 | lines: Option>, 23 | }, 24 | } 25 | 26 | impl Content { 27 | /// Get file path for this content 28 | pub fn get_path(&self) -> &PathBuf { 29 | match self { 30 | Self::Section { path, .. } => path, 31 | Self::Svg { path, .. } => path, 32 | } 33 | } 34 | } 35 | 36 | impl GetChapter for Content { 37 | fn get_chp(&self) -> Option { 38 | match self { 39 | Self::Section { path, .. } => path.get_chp(), 40 | Self::Svg { path, .. } => path.get_chp(), 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/lint.rs: -------------------------------------------------------------------------------- 1 | use crate::{rules::Rule, Content}; 2 | use colored::*; 3 | use std::{fmt, num::NonZeroUsize, path::PathBuf}; 4 | 5 | #[derive(Debug)] 6 | #[cfg_attr(test, derive(PartialEq))] 7 | pub enum Level { 8 | Fatal, 9 | Warning, 10 | } 11 | 12 | #[cfg_attr(test, derive(PartialEq))] 13 | pub struct LineNumber { 14 | num: NonZeroUsize, 15 | } 16 | 17 | // Line index (internal) -> line number (human-readable) 18 | impl From for LineNumber { 19 | fn from(zero_idx_num: usize) -> Self { 20 | Self { 21 | // SAFETY: cannot panic, input always >= 1 22 | num: NonZeroUsize::new(zero_idx_num + 1).unwrap(), 23 | } 24 | } 25 | } 26 | 27 | // Defer `Display` impl to inner type 28 | impl fmt::Display for LineNumber { 29 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 30 | write!(f, "{}", self.num) 31 | } 32 | } 33 | 34 | // Defer `Debug` impl to `Display` impl 35 | impl fmt::Debug for LineNumber { 36 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 | write!(f, "{}", self) 38 | } 39 | } 40 | 41 | #[derive(Debug)] 42 | #[cfg_attr(test, derive(PartialEq))] 43 | pub enum LintError<'a> { 44 | Failed { 45 | path: &'a PathBuf, 46 | line_number: LineNumber, 47 | line: String, 48 | reason: String, 49 | }, 50 | } 51 | 52 | #[derive(Debug)] 53 | #[cfg_attr(test, derive(PartialEq))] 54 | pub enum LeveledLintError<'a> { 55 | Fatal(LintError<'a>), 56 | Warning(LintError<'a>), 57 | } 58 | 59 | #[cfg(test)] 60 | impl<'a> PartialEq for Rule<'a> { 61 | fn eq(&self, other: &Self) -> bool { 62 | // XXX: this is a test-only crime 63 | format!("{:?}", self) == format!("{:?}", other) 64 | } 65 | } 66 | 67 | #[derive(Default, Debug)] 68 | #[cfg_attr(test, derive(PartialEq))] 69 | pub struct Linter<'a> { 70 | rules: Vec<(Level, Rule<'a>)>, 71 | contents: Vec<&'a Content>, 72 | } 73 | 74 | impl<'a> Linter<'a> { 75 | pub fn builder() -> LinterBuilder<'a> { 76 | LinterBuilder::default() 77 | } 78 | 79 | pub fn run(&self, log_warn: bool) -> Result<(), LeveledLintError> { 80 | for content in &self.contents { 81 | let (path, lines) = match content { 82 | Content::Section { path, lines, .. } => (path, lines), 83 | Content::Svg { path, lines } => (path, lines), 84 | }; 85 | 86 | match lines { 87 | Some(lines) => { 88 | for (level, rule) in &self.rules { 89 | match rule.0(path, lines).map_err(|err| match level { 90 | Level::Fatal => LeveledLintError::Fatal(err), 91 | Level::Warning => LeveledLintError::Warning(err), 92 | }) { 93 | Ok(_) => continue, 94 | Err(e) => match &e { 95 | LeveledLintError::Fatal(_) => return Err(e), 96 | LeveledLintError::Warning(w) => { 97 | if log_warn { 98 | println!("{}: {:?}", "WARNING".yellow(), w); 99 | } else { 100 | return Err(e); 101 | } 102 | } 103 | }, 104 | } 105 | } 106 | } 107 | None => { 108 | return Err(LeveledLintError::Fatal(LintError::Failed { 109 | path, 110 | line_number: 0.into(), 111 | line: "N/A".to_string(), 112 | reason: "Empty content".to_string(), 113 | })) 114 | } 115 | } 116 | } 117 | 118 | Ok(()) 119 | } 120 | } 121 | 122 | #[derive(Default)] 123 | #[cfg_attr(test, derive(Debug, PartialEq))] 124 | pub struct LinterBuilder<'a> { 125 | rules: Vec<(Level, Rule<'a>)>, 126 | contents: Vec<&'a Content>, 127 | } 128 | 129 | impl<'a> LinterBuilder<'a> { 130 | pub fn new() -> LinterBuilder<'a> { 131 | LinterBuilder { 132 | rules: Vec::new(), 133 | contents: Vec::new(), 134 | } 135 | } 136 | 137 | pub fn add_rule(mut self, level: Level, rule: Rule<'a>) -> LinterBuilder<'a> { 138 | self.rules.push((level, rule)); 139 | self 140 | } 141 | 142 | pub fn add_content(mut self, content: &'a Content) -> LinterBuilder<'a> { 143 | self.contents.push(content); 144 | self 145 | } 146 | 147 | pub fn build(self) -> Linter<'a> { 148 | Linter { 149 | rules: self.rules, 150 | contents: self.contents, 151 | } 152 | } 153 | } 154 | 155 | #[cfg(test)] 156 | mod tests { 157 | use super::{Level, LeveledLintError, Linter, LinterBuilder}; 158 | use crate::{ 159 | rules::{rule_nonempty, Rule}, 160 | Content, 161 | }; 162 | use std::path::PathBuf; 163 | 164 | #[test] 165 | fn test_lint_builder() { 166 | let empty_section = Content::Section { 167 | path: PathBuf::from("/test/path/to/file.md"), 168 | word_count: 0, 169 | lines: None, 170 | }; 171 | 172 | let default_svg = Content::Svg { 173 | path: PathBuf::default(), 174 | lines: None, 175 | }; 176 | 177 | let linter = Linter { 178 | rules: vec![(Level::Fatal, Rule(&rule_nonempty))], 179 | contents: vec![&default_svg, &empty_section], 180 | }; 181 | 182 | let linter_from_builder: Linter = LinterBuilder::new() 183 | .add_rule(Level::Fatal, Rule(&rule_nonempty)) 184 | .add_content(&default_svg) 185 | .add_content(&empty_section) 186 | .build(); 187 | 188 | assert_eq!(linter, linter_from_builder); 189 | assert!(matches!(linter.run(true), Err(LeveledLintError::Fatal(_)))); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::{ 2 | builder::{styling::AnsiColor, Styles}, 3 | Parser, 4 | }; 5 | use color_eyre::eyre::Result; 6 | use colored::*; 7 | use lazy_static::lazy_static; 8 | 9 | lazy_static! { 10 | static ref CMD_COLOR: Styles = Styles::styled() 11 | .header(AnsiColor::Yellow.on_default()) 12 | .usage(AnsiColor::Green.on_default()) 13 | .valid(AnsiColor::Green.on_default()) 14 | .error(AnsiColor::Red.on_default()) 15 | .invalid(AnsiColor::Red.on_default()) 16 | .literal(AnsiColor::Cyan.on_default()) 17 | .placeholder(AnsiColor::BrightBlue.on_default()); 18 | } 19 | 20 | #[derive(Parser, Debug)] 21 | #[command( 22 | version, 23 | about, 24 | term_width = 150, 25 | styles = CMD_COLOR.clone(), 26 | )] 27 | #[group(required = true, multiple = true)] 28 | struct Args { 29 | /// Print page/diagram count metrics. 30 | #[arg(short, long)] 31 | metrics: bool, 32 | 33 | /// Run custom linter. 34 | #[arg(short, long)] 35 | lint: bool, 36 | 37 | /// Log linter warnings. If false (default), warnings become hard errors. 38 | #[arg(long, requires = "lint")] 39 | log_warn: bool, 40 | 41 | /// Update page/diagram count badges and missing meta tags. 42 | #[arg(short, long)] 43 | update: bool, 44 | } 45 | 46 | fn main() -> Result<()> { 47 | color_eyre::install()?; 48 | 49 | let args = Args::parse(); 50 | let book = har_analyze::Book::try_new(args.lint).unwrap(); 51 | 52 | // Status Report 53 | if args.metrics { 54 | println!("\n{}", book); 55 | } 56 | 57 | // Update/fix 58 | if args.update { 59 | har_analyze::update_badges(&book).unwrap(); 60 | har_analyze::update_meta_tags(&book).unwrap(); 61 | println!("Updates {}", "OK".green()); 62 | } 63 | 64 | // Verify 65 | if args.lint { 66 | book.get_non_chp_linter().run(args.log_warn).unwrap(); 67 | book.get_chp_intro_linter().run(args.log_warn).unwrap(); 68 | book.get_chp_sections_linter().run(args.log_warn).unwrap(); 69 | book.get_svg_linter().run(args.log_warn).unwrap(); 70 | println!("Lint {}", "OK".green()); 71 | } 72 | 73 | Ok(()) 74 | } 75 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/mod.rs: -------------------------------------------------------------------------------- 1 | //! MD Book metrics/linting. 2 | //! Internal tool for 3 | #![deny(missing_docs)] 4 | 5 | mod book; 6 | pub use book::*; 7 | 8 | mod chapter; 9 | pub use chapter::*; 10 | 11 | mod content; 12 | pub use content::*; 13 | 14 | #[allow(missing_docs)] 15 | mod lint; 16 | pub use lint::*; 17 | 18 | mod update; 19 | pub use update::*; 20 | 21 | mod rules; 22 | 23 | mod traits; 24 | 25 | pub(crate) const BOOK_SRC_DIR_RELATIVE: &str = "../../src"; 26 | pub(crate) const WORDS_PER_PAGE: usize = 500; 27 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/traits.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Component, PathBuf}; 2 | 3 | /// Get model metrics 4 | pub trait GetMetrics { 5 | fn get_word_count(&self) -> usize; 6 | fn get_diagram_count(&self) -> usize; 7 | } 8 | 9 | /// Get chapter number 10 | pub trait GetChapter { 11 | fn get_chp(&self) -> Option; 12 | } 13 | 14 | impl GetChapter for &PathBuf { 15 | fn get_chp(&self) -> Option { 16 | const CHP_PREFIX: &str = "chp"; 17 | const OPT_CHP_SUFFIX: &str = "_appendix"; 18 | 19 | // Non-ambiguity in chp labels (1 per path) 20 | debug_assert!( 21 | 2 > self 22 | .components() 23 | .filter(|c| { 24 | match c { 25 | Component::Normal(name) => name 26 | .to_str() 27 | .map_or(false, |n| n.strip_prefix(CHP_PREFIX).is_some()), 28 | _ => false, 29 | } 30 | }) 31 | .count(), 32 | "Ambiguous chapter for path: {}", 33 | &self.to_str().unwrap(), 34 | ); 35 | 36 | for component in self.components().rev() { 37 | match component { 38 | // No chapter number 39 | Component::RootDir | Component::Prefix(_) => return None, 40 | // Cannot determine chapter number 41 | Component::CurDir | Component::ParentDir => continue, 42 | // Extract chapter number 43 | Component::Normal(name) => match name.to_str() { 44 | Some(name) => match name.strip_prefix(CHP_PREFIX) { 45 | Some(number) => { 46 | let number = match number.strip_suffix(OPT_CHP_SUFFIX) { 47 | Some(number) => number, 48 | None => number, 49 | }; 50 | 51 | if let Ok(number) = number.parse() { 52 | return Some(number); 53 | } 54 | } 55 | None => continue, 56 | }, 57 | None => continue, 58 | }, 59 | } 60 | } 61 | 62 | // Other (non-chapter) files 63 | Some(0) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /internal_tools/har_analyze/src/update.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs::{File, OpenOptions}, 3 | io::{self, prelude::*, BufReader}, 4 | iter, 5 | path::PathBuf, 6 | }; 7 | 8 | use crate::{traits::GetMetrics, Book, Content, BOOK_SRC_DIR_RELATIVE, WORDS_PER_PAGE}; 9 | 10 | use separator::Separatable; 11 | 12 | const BADGE_LINK: &str = "https://github.com/tnballo/high-assurance-rust"; 13 | const PAGE_BADGE_START: &str = "[![Pages](https://img.shields.io/badge/Pages"; 14 | const DIAGRAM_BADGE_START: &str = "[![Diagrams](https://img.shields.io/badge/Diagrams"; 15 | 16 | pub(crate) const META_TAGS: [&str; 12] = [ 17 | "", 18 | "", 19 | "", 20 | "", 21 | "", 22 | "", 23 | "", 24 | "", 25 | "", 26 | "", 27 | "", 28 | "", 29 | ]; 30 | 31 | // TODO: don't use `BOOK_SRC_DIR_RELATIVE` 32 | /// Update page/diagram count badges in book `landing.md` and `README.md` 33 | pub fn update_badges(book: &Book) -> io::Result<()> { 34 | let page_cnt = book.get_word_count() / WORDS_PER_PAGE; 35 | let diagram_cnt = book.get_diagram_count(); 36 | let landing_path = PathBuf::from(BOOK_SRC_DIR_RELATIVE).join("landing.md"); 37 | let readme_path = PathBuf::from(BOOK_SRC_DIR_RELATIVE) 38 | .as_path() 39 | .parent() 40 | .expect("Failed to find book root path") 41 | .join("README.md"); 42 | 43 | for path in [readme_path, landing_path].into_iter() { 44 | let file = File::open(&path)?; 45 | let reader = BufReader::new(file); 46 | let content = reader 47 | .lines() 48 | .map_while(Result::ok) 49 | .map(|line| { 50 | if line.starts_with(PAGE_BADGE_START) { 51 | format!( 52 | "{}-{}-purple.svg)]({})", 53 | PAGE_BADGE_START, 54 | page_cnt.separated_string(), 55 | BADGE_LINK 56 | ) 57 | } else if line.starts_with(DIAGRAM_BADGE_START) { 58 | format!( 59 | "{}-{}-blue.svg)]({})", 60 | DIAGRAM_BADGE_START, 61 | diagram_cnt.separated_string(), 62 | BADGE_LINK 63 | ) 64 | } else { 65 | line 66 | } 67 | }) 68 | .collect::>() 69 | .join("\n") 70 | .chars() 71 | .chain(iter::once('\n')) 72 | .collect::(); 73 | 74 | let mut new_file = OpenOptions::new().write(true).truncate(true).open(path)?; 75 | new_file.write_all(content.as_bytes())?; 76 | } 77 | 78 | Ok(()) 79 | } 80 | 81 | // TODO: double-check and add to `--update` flag 82 | /// Add meta tags to the start of every single page of the book 83 | pub fn update_meta_tags(book: &Book) -> io::Result<()> { 84 | for chp in book.chapters.values() { 85 | for content in &chp.contents { 86 | if let Content::Section { path, .. } = content { 87 | let file = File::open(path)?; 88 | let reader = BufReader::new(file); 89 | let current_contents = reader 90 | .lines() 91 | .map_while(Result::ok) 92 | .collect::>(); 93 | 94 | let new_contents = if starts_with_meta_tags(current_contents.iter()) { 95 | current_contents 96 | } else { 97 | let without_tags = remove_meta_tags(current_contents.into_iter()); 98 | let with_correct_tags = prefix_meta_tags(without_tags); 99 | with_correct_tags.into_iter().collect() 100 | }; 101 | 102 | let new_contents = new_contents 103 | .join("\n") 104 | .chars() 105 | .chain(iter::once('\n')) 106 | .collect::(); 107 | 108 | let mut new_file = OpenOptions::new().write(true).truncate(true).open(path)?; 109 | new_file.write_all(new_contents.as_bytes())?; 110 | } 111 | } 112 | } 113 | 114 | Ok(()) 115 | } 116 | 117 | fn starts_with_meta_tags<'a>(lines: impl Iterator) -> bool { 118 | for (meta_tag_line, actual_line) in META_TAGS.iter().zip(lines) { 119 | if *meta_tag_line != actual_line { 120 | return false; 121 | } 122 | } 123 | 124 | true 125 | } 126 | 127 | fn remove_meta_tags(lines: impl IntoIterator) -> Box> { 128 | Box::new( 129 | lines 130 | .into_iter() 131 | .filter(|l| !META_TAGS.iter().any(|t| *t == l)) 132 | .collect::>() 133 | .into_iter(), 134 | ) 135 | } 136 | 137 | fn prefix_meta_tags(lines: impl IntoIterator) -> Box> { 138 | Box::new( 139 | META_TAGS 140 | .iter() 141 | .map(|tag| tag.to_string()) 142 | .chain(iter::once("\n".to_string())) 143 | .chain(lines) 144 | .collect::>() 145 | .into_iter(), 146 | ) 147 | } 148 | -------------------------------------------------------------------------------- /src/cfp.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Sponsor Call for Proposals (CFP) 16 | --- 17 | 18 | Readers of this book are likely interested in **software careers** and/or **security products**. 19 | This is a **discovery problem** with two stakeholders: 20 | 21 | 1. **Engineers** looking for exciting teams to join. 22 | 23 | 2. **Companies** looking to get quality tools in the hands of security-savvy engineers. 24 | 25 | The primary goal of this book is **free education**. 26 | But we'd also love to connect those stakeholders - should both parties stand to benefit. 27 | 28 | ## What we are asking 29 | 30 | * That your company meet **two criteria**: 31 | 32 | 1. Employer with technical roles (software development, security engineering, technical writing, product management, etc) 33 | 34 | 2. Offers a security-relevant product (SaaS, hardware, reports, etc) or professional service (consulting, training, R&D, etc) 35 | 36 | * **A one-time donation** to sponsor the development of this book. 37 | 38 | * Likely a tiny sum relative to your current marketing budget. 39 | 40 | * You'd be supporting a freely available resource for continuing education. 41 | 42 | * A **brief proposal** for a written section. 43 | 44 | * See below. 45 | 46 | ## What we can offer 47 | 48 | * Your **logo listed as a sponsor** on the landing page of this book, with two links of your choosing (your careers page, your product page, etc). 49 | 50 | * Logos will appear in order of sponsorship start date (first to latest). 51 | 52 | * Logo placement for the lifetime of this domain (guaranteed 10+ years). 53 | 54 | * You can request removal of your logo/links at any time, for any reason (e.g. future chapter of the book doesn't meet your values or quality standards). 55 | 56 | * A **written section** in a dedicated sponsor chapter at the end of the book. 57 | 58 | * Tutorial of product use, article on team culture, etc. 59 | 60 | * Up to 3,500 words, written by you (the experts on the topic). 61 | 62 | * **No tracking/analytics allowed** (respect reader privacy, like an old-school magazine ad). No reader information can be collected or shared. 63 | 64 | * The star count on this book's repos already serves as a *transparent* and *voluntary* metric of visibility. 65 | 66 | If you'd like to become a sponsor, please send your brief proposal (plaintext or PDF preferred) to: 67 | 68 | **contact@highassurance.rs** 69 | 70 | We'd love to hear from you! 71 | 72 | > We reserve the right to politely decline sponsorship requests for any reason (e.g. brand reputation, proposal topic, etc). We must do right by our readers. 73 | 74 | --- 75 | -------------------------------------------------------------------------------- /src/changelog.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Changelog 16 | --- 17 | 18 | **Note:** This book is a work in progress, and its contents (current or future) are subject to change. 19 | If you've found an error, please [get in touch](./engage.md#submit-feedback-questions-issues-or-prs). 20 | 21 | * **v0.4.2-alpha:** 22 | * Internal tools update (metrics, linter) 23 | * Landing/`README.md` badges with computed page and diagram counts 24 | * Updated EPUB download 25 | * Updated mentions of [Ferrocene](https://github.com/ferrocene/ferrocene) and [FLS](https://spec.ferrocene.dev/) in light of respective open-source releases (yay!) 26 | 27 | * **v0.4.1-alpha:** 28 | * New section: *4.2 Assurance Perspective: Stack Safety* 29 | * New section: *16.10 Theory: Inter-procedural CFGs* 30 | * Revisions to 4.0, 4.1, and 4.4. 31 | * Many new and revised 4.X diagrams. 32 | 33 | * **v0.4.0-alpha:** 34 | * New section: *4.1. Software Perspective: CPU to Stack* 35 | * New section: *4.3. Attacker's Perspective: Breaking Safety (1/2)* 36 | * New section: *4.4. Attacker's Perspective: Unifying Theory (2/2)* 37 | 38 | * **v0.3.2:** 39 | * [Rust Foundation](https://foundation.rust-lang.org/) sponsorship via the [2022 Project Grants Program](https://foundation.rust-lang.org/news/2022-06-14-community-grants-program-awards-announcement/)! 40 | * New diagrams and discussion in 1.1, 2.10. 41 | * New asides in 2.2 and 2.7. 42 | * [`CODE_OF_CONDUCT.md`](https://github.com/tnballo/high-assurance-rust/blob/main/CODE_OF_CONDUCT.md) added. 43 | * EPUB download now includes a SHA-3-256 hash and timestamp. 44 | 45 | * **v0.3.1:** 46 | * [Community Contributors list](./chp1/about_the_team.md#community-contributors) started, [`CONTRIBUTING.md`](https://github.com/tnballo/high-assurance-rust/blob/main/CONTRIBUTING.md) added. 47 | * Several fixes and improvements based on community feedback. 48 | * Shout-out to [jam1garner](https://www.jam1.re/) for a thorough review and deep technical insights. 49 | * Add EPUB download. 50 | 51 | * **v0.3.0:** 52 | * Hello, world! :) 53 | * Public release of initial content (Chapters 1, 2, 3, and most of Appendix). 54 | 55 | * **v0.0.0:** 56 | * [Open-source `scapegoat` library](https://github.com/tnballo/scapegoat) demonstrates that this book's core project is viable. 57 | * Maximizes Rust's major strengths: memory safety and bare metal portability. 58 | 59 | > Dates intentionally omitted to keep us focused on quality, not speed. Except for the code - that's pretty fast (stack-stored arena, no recursion). 60 | 61 | --- 62 | -------------------------------------------------------------------------------- /src/chp1/about_the_team.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # About the Team 16 | 17 | ## Core Team 18 | 19 | **Tiemoko Ballo, *Author*** ([tiemoko.com](https://tiemoko.com)) 20 | 21 | Tiemoko is a Senior Cybersecurity Researcher. 22 | His experience spans advanced tooling development at a US Department of Defense laboratory, publication at peer-reviewed academic conferences, and incident response at a Fortune 100 enterprise. 23 | He received his Masters degree in Information Security from Carnegie Mellon University. 24 | 25 | **Moumine Ballo, *Technical Editor*** ([LinkedIn](https://www.linkedin.com/in/moumine-ballo/)) 26 | 27 | Moumine is a Senior Staff Software Engineer. 28 | He's worked on a cutting-edge mobile GPU, and written graphics engines for both AAA games on resource-constrained consoles and autonomous vehicle simulation. 29 | He received his PhD in Computer Science from the Warsaw University of Technology. 30 | 31 | **Alex James, *Technical Editor*** ([buildbreak.net](https://buildbreak.net/)) 32 | 33 | Alex is a Security Software Engineer. 34 | He works on web-scale secure architecture and cloud infrastructure, designing and implementing distributed security systems that serve over 300 million daily active users. 35 | He received his Masters degree in Information Security from Carnegie Mellon University. 36 | 37 | ## Community Contributors 38 | 39 | Huge thank you to everyone making this book better[^Contrib]! 40 | Listed alphabetically: 41 | 42 | * [aelnona](https://github.com/aelnona) 43 | * [asher-gh](https://github.com/asher-gh) 44 | * [drlef](https://github.com/drlef) 45 | * [Druthyn](https://github.com/Druthyn) 46 | * [duzumaki](https://github.com/duzumaki) 47 | * [humb1t](https://github.com/humb1t) 48 | * [jam1garner](https://github.com/jam1garner) 49 | * [jamesreprise](https://github.com/jamesreprise) 50 | * [jkoeppeler](https://github.com/jkoeppeler) 51 | * [kaylynn234](https://github.com/kaylynn234) 52 | * [LoganDark](https://github.com/LoganDark) 53 | * [Michcioperz](https://github.com/Michcioperz) 54 | * [qrilka](https://github.com/qrilka) 55 | * [rrevi](https://github.com/rrevi) 56 | * [samestep](https://github.com/samestep) 57 | * [shak360](https://github.com/shak360) 58 | * [SilvanCodes](https://github.com/SilvanCodes) 59 | * [sshine](https://github.com/sshine) 60 | * [tshepang](https://github.com/tshepang) 61 | * [U007D](https://github.com/U007D) 62 | * [Vishal Lama](https://github.com/vishallama) 63 | 64 |
65 | 66 | --- 67 | 68 | [^Contrib]: Contributions are welcome and appreciated. Please see [`CONTRIBUTING.md`](https://github.com/tnballo/high-assurance-rust/blob/main/CONTRIBUTING.md). 69 | -------------------------------------------------------------------------------- /src/chp1/bugs_venn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Bugs Unique to
Memory-Safe
Languages
Bugs Unique to...
Bugs Unique to
Memory-Unsafe
Languages
Bugs Unique to...

Bugs
Agnostic to
Language
Bugs...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /src/chp1/challenges.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Hands-on Learning 16 | 17 | Both software developers and security engineers are practitioners first, theoreticians second. 18 | Understanding underlying concepts and situational context is critical, certainly. 19 | But at the end of the day you write and run code. 20 | And someone else may try to exploit that code while it's running. 21 | 22 | The aforementioned Dreyfus Model encapsulates both formal instruction and hands-on practice[^NewDreyfus]. 23 | It may be cliche, but practice makes perfect. 24 | Or makes expert, rather. 25 | There's a limit to how much you can learn skimming a book for concepts. 26 | 27 | You need to write, run, and debug code to progress through the Dreyfus stages. 28 | This means following along with examples presented in the chapters, and, more importantly, using this book as a starting point for real-world projects of your own choosing. 29 | 30 | Our goal here is to teach concepts and transferable skills, to get you to the level where real-world experience is a realistic potential. 31 | For the language-learning aspect, that's the point at which you'd feel comfortable: 32 | 33 | * Contributing to existing open-source projects written in Rust. 34 | * Publishing a Rust library of your own design. 35 | * Incorporating Rust into a new initiative in your workplace. 36 | * Etc. 37 | 38 | ## Chapter-End Challenges 39 | 40 | Each chapter ends with an optional challenge. 41 | These challenges are open-ended problems that require both designing a moderate-to-high complexity feature and actually coding it up. 42 | 43 | You'll need to explore the solution space independently, applying the chapter's concepts in a new context, finding resources beyond this book, and developing your own strategies. 44 | 45 | No challenge solutions are provided, it's up to you to work through the suggested problems! 46 | Or personal variations that motivate you. 47 | 48 | --- 49 | 50 | [^NewDreyfus]: [*The Five-Stage Model of Adult Skill Acquisition*](https://www.bumc.bu.edu/facdev-medicine/files/2012/03/Dreyfus-skill-level.pdf). Stuart E.Dreyfus (2004). 51 | -------------------------------------------------------------------------------- /src/chp12/diff_fuzz_PLACEHOLDER.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Building a Differential Fuzzing Harness 16 | 17 | > **Note:** This section is a work-in-progress. 18 | > For a preview, please see this blog post: 19 | > 20 | > [Beyond the Borrow Checker: Differential Fuzzing](https://tiemoko.com/blog/diff-fuzz/) 21 | 22 | --- 23 | 24 | -------------------------------------------------------------------------------- /src/chp16_appendix/_index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Appendix 16 | --- 17 | 18 | The appendix's supplemental content is categorized as follows: 19 | 20 | * **Setup** sections detail development environment configuration and usage. 21 | 22 | * **Inventory** sections catalog resources. Like tools covered and other books recommended. 23 | 24 | * **Foundations** sections provide brief, optional introductions to key concepts. To accommodate readers of different backgrounds. 25 | 26 | * **Misc** (miscellaneous) sections cover topics that, while important, don't fit naturally within the arc of the book. 27 | 28 | Appendix sections aren't just a tack-on - they're written with the same care and effort as the main chapters. 29 | 30 | --- 31 | -------------------------------------------------------------------------------- /src/chp16_appendix/books.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Inventory: Recommended Reading 16 | 17 | This is a complete inventory of recommended reading, books that appear with the tag ***[PERSONAL FAVORITE]*** in footnotes. 18 | We genuinely feel each book listed is either an essential read in its field or a reference worth keeping in arm's reach. 19 | 20 | If you purchase a book using one of the affiliate links below, it helps support ***High Assurance Rust*** - in addition to the book you're buying! 21 | 22 | ## Rust 23 | 24 |
25 |
26 | 27 |
28 | 29 | * ***Programming Rust: Fast, Safe Systems Development***. Jim Blandy, Jason Orendorff, Leonora Tindall (2021). 30 | 31 | * [https://amzn.to/35cu1Za](https://amzn.to/35cu1Za) 32 | 33 |
34 |
35 | 36 |
37 | 38 | * ***Rust for Rustaceans***. Jon Gjengset (2021). 39 | 40 | * [https://amzn.to/36GfSDU](https://amzn.to/36GfSDU) 41 | 42 | ## Software 43 | 44 |
45 |
46 | 47 |
48 | 49 | * ***Computer Systems: A Programmer's Perspective***. Randal Bryant, David O'Hallaron (2015). 50 | 51 | * [https://amzn.to/3IBnFA7](https://amzn.to/3IBnFA7) 52 | 53 |
54 |
55 | 56 |
57 | 58 | * ***A Philosophy of Software Design***. John Ousterhout (2021). 59 | 60 | * [https://amzn.to/3DbaPrp](https://amzn.to/3DbaPrp) 61 | 62 |
63 |
64 | 65 |
66 | 67 | * ***Effective C: An Introduction to Professional C Programming***. Robert Seacord (2020). 68 | 69 | * [https://amzn.to/3wBuNu7](https://amzn.to/3wBuNu7) 70 | 71 | ## Security 72 | 73 |
74 |
75 | 76 |
77 | 78 | * ***Practical Binary Analysis: Build Your Own Linux Tools for Binary Instrumentation, Analysis, and Disassembly***. Dennis Andriesse (2018). 79 | 80 | * [https://amzn.to/3wvtCwa](https://amzn.to/3wvtCwa) 81 | 82 |
83 |
84 | 85 |
86 | 87 | * ***Understanding Cryptography***. Christof Paar, Jan Pelzl (2009). 88 | 89 | * [https://amzn.to/3IEYuNd](https://amzn.to/3IEYuNd) 90 | 91 | --- 92 | -------------------------------------------------------------------------------- /src/chp16_appendix/icfg.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Inter-procedural Control Flow Graphs (ICFGs) 16 | 17 | When possible, eliminating a bug category with a pattern is ideal for static assurance. 18 | We saw this when exploring stack safety and MISRA C 17.2[^MISRA_2012] ("no recursion") in Chapter 4, Section 2. 19 | 20 | What impact does recursion have on the more general case, arbitrary static analysis and/or verification tooling? 21 | 22 | Technically, it depends. 23 | Realistically, many useful tools need to build a static **Inter-procedural Control Flow Graph (ICFG)**. 24 | Because it's a "backbone" common analysis algorithms run on. 25 | And because understanding all possible call sequences often enables judgments about all possible executions. 26 | 27 | We're going to consider 3 ICFGs of increasing complexity. 28 | First, our MISRA C 17.2-compatible, iterative program from Chapter 4.2: 29 | 30 |
31 |

32 | 33 |

34 |
Iterative program ICFG - a Directed Acyclic Graph (DAG)

35 |
36 |

37 | 38 | * This is a **Directed Acyclic Graph (DAG)**. For analysis authors, this graph enables certain algorithms or possibilities. 39 | 40 | * Example: topological sort[^TopSort], which can be used to represent a valid sequence of tasks, requires a DAG. 41 | 42 | Next, our initial, recursive version (also from 4.2): 43 | 44 |
45 |

46 | 47 |

48 |
Recursive program ICFG - a Directed Graph (DG)

49 |
50 |

51 | 52 | 53 | * This is a **Directed Graph (DG)**. For some analysis authors, a problem just got harder. They may be forced to over-approximate (allow false positives) or relax guarantees (weaker analysis). 54 | 55 | * Example: static calculation of a program's worst case stack utilization. 56 | 57 | There's also mutual recursion, where two or more functions call each other. 58 | Let's just consider it an even less desirable variation of the prior recursive version: 59 | 60 |
61 |

62 | 63 |

64 |
Mutually recursive program ICFG - a Directed Graph (DG) variation.

65 |
66 |

67 | 68 | A DAG vs DG comparison is intentionally vague, we can't really make any claims about static analyzers as a whole - there probably exist thousands of static analyzers serving hundreds of use cases. 69 | But it helps build an intuition. 70 | Imagine writing logic to traverse these graphs - a DAG avoids edge cases. 71 | 72 | ## Takeaway 73 | 74 | Recursion isn't only a problem for runtime memory exhaustion. 75 | It impacts a program's Inter-procedural Control Flow Graph (ICFG), generally hindering static analysis. 76 | 77 | --- 78 | 79 | [^MISRA_2012]: *MISRA C: 2012 Guidelines for the use of the C language in critical systems (3rd edition)*. MISRA (2019). 80 | 81 | [^TopSort]: [*Topological sorting*](https://en.wikipedia.org/wiki/Topological_sorting). Wikipedia (Accessed 2023). 82 | -------------------------------------------------------------------------------- /src/chp16_appendix/icfg_iter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
I
I
Iterative Program ICFG
Iterative Program ICFG
square
square
main
main
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /src/chp16_appendix/resources.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Additional Resources 16 | 17 | This section collects reference resources for professional developers. 18 | It's curated, not exhaustive. 19 | 20 | ## Official 21 | 22 | * **The Rust Reference** 23 | 24 | * [https://doc.rust-lang.org/reference/](https://doc.rust-lang.org/reference/) 25 | 26 | * **Rust API Guidelines** 27 | 28 | * [https://rust-lang.github.io/api-guidelines/](https://rust-lang.github.io/api-guidelines/) 29 | 30 | * **Unsafe Code Guidelines Reference** 31 | 32 | * [https://rust-lang.github.io/unsafe-code-guidelines/](https://rust-lang.github.io/unsafe-code-guidelines/) 33 | 34 | * **Guide to Rustc Development** 35 | 36 | * [https://rustc-dev-guide.rust-lang.org/](https://rustc-dev-guide.rust-lang.org/) 37 | 38 | ## Unofficial 39 | 40 | * **Secure Rust Guidelines** (ANSSI) 41 | 42 | * [https://anssi-fr.github.io/rust-guide/](https://anssi-fr.github.io/rust-guide/) 43 | 44 | * **Rust Fuzz Book** (`cargo-fuzz`) 45 | 46 | * [https://rust-fuzz.github.io/book/](https://rust-fuzz.github.io/book/) 47 | 48 | * **The Kani Rust Verifier** (`kani`) 49 | 50 | * [https://model-checking.github.io/kani/](https://model-checking.github.io/kani/) 51 | 52 | --- 53 | -------------------------------------------------------------------------------- /src/chp16_appendix/tools.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Tools of the Trade 16 | 17 | This is a complete inventory of all the software assurance tools and Rust libraries you'll use in this book. 18 | You'll get deep experience in a few, but only a taste of most. 19 | Each name below is a link to the tool's homepage or documentation. 20 | 21 | > **Rust's Open Formal Verification Ecosystem** 22 | > 23 | > With a spectrum of open-source options, Rust's assurance ecosystem is thriving. 24 | > The Rust Formal Methods Interest Group (RFMIG) maintains a list of verification tools, [available here](https://rust-formal-methods.github.io/tools.html), more comprehensive than the sample we cover in this book. 25 | 26 | ### Core Tooling 27 | 28 | **Static Assurance** 29 | 30 | Most tools in this category reason about source-level semantics to prove the absence of certain bugs. 31 | They trust the compiler and, by extension, its backend. 32 | 33 | * [`rustc`](https://rustc-dev-guide.rust-lang.org/) (Rust-only, it's literally the compiler!) 34 | * [`cbmc` via `kani`](https://github.com/model-checking/kani) (Rust front-end, underlying tool also supports C/C++) 35 | * [`viper` via `prusti`*](https://www.pm.inf.ethz.ch/research/prusti.html) (Underlying tool supports Rust, Python, Java, ...). 36 | * [`creusot`*](https://github.com/xldenis/creusot) (Rust-only) 37 | 38 | **Dynamic Assurance** 39 | 40 | Most tools in this category test compiled executables to discover specific bugs or observe program behavior. 41 | They remove the compiler from the chain of trust. 42 | 43 | * [`valgrind`*](https://valgrind.org/) (x86, x86_64, ARM32, ARM64, MIPS, PPC) 44 | * [`rr`](https://rr-project.org/) (x86, x86_64) 45 | * [`libfuzzer` via `cargo-fuzz`](https://llvm.org/docs/LibFuzzer.html) (x86, x86_64, ARM64) 46 | * [`qemu`](https://www.qemu.org/) (x86, x86_64, ARM32, ARM64, MIPS, PPC, AVR, ...) 47 | * [`miri`](https://github.com/rust-lang/miri) (Rust-only) 48 | 49 | **Operational Assurance** 50 | 51 | Tools that support a system's lifecycle. 52 | 53 | * [`docker`](https://docs.docker.com/engine/reference/commandline/cli/) (Linux guests) 54 | * [`cbindgen`](https://crates.io/crates/cbindgen) (CFFI) 55 | 56 | ### Rust Ecosystem 57 | 58 | Open-source binaries and libraries hosted on [crates.io](https://crates.io/). 59 | 60 | **Development** 61 | 62 | * [`clap`](https://crates.io/crates/clap) - Command line argument parsing. 63 | * [`serde`*](https://crates.io/crates/serde) - Rust structure serialization and deserialization. 64 | * [`tinyvec`](https://crates.io/crates/smallvec) - `!#[no_std]`, `#![forbid(unsafe_code)]` `Vec` alternative. 65 | * [`micromath`](https://crates.io/crates/micromath) - `!#[no_std]`, `#![forbid(unsafe_code)]` floating point approximations. 66 | * [`lazy_static`*](https://crates.io/crates/lazy_static) - runtime-initialized static variables. 67 | * [`owo-colors`](https://crates.io/crates/owo-colors) - embedded-friendly text coloring. 68 | 69 | **Testing** 70 | 71 | * [`criterion`](https://crates.io/crates/criterion) - micro-benchmarking toolset. 72 | * [`cargo-modules`](https://crates.io/crates/cargo-modules) - text render of project's module architecture. 73 | * [`cargo-audit`](https://crates.io/crates/cargo-audit) - search project's decency graph for known-vulnerable versions. 74 | * [`cargo-binutils`](https://crates.io/crates/cargo-binutils) - inspect the properties and contents of Linux binaries. 75 | * [`cargo-bloat`](https://crates.io/crates/cargo-bloat) - determine what parts of an executable contribute to it's size. 76 | * [`siderophile`*](https://crates.io/crates/siderophile) - search project's call graph for pockets of `unsafe` code. 77 | * [`cargo-tarpaulin`*](https://crates.io/crates/cargo-tarpaulin) - code coverage reporting (MC/DC support planned). 78 | 79 | **Other** 80 | 81 | * [`xgadget`*](https://crates.io/crates/xgadget) - ROP/JOP exploit development. 82 | 83 | --- 84 | 85 | > \* == may be subject to change. This book is a [work in progress](./faq.md#8-is-this-book-free). 86 | > 87 | > Additional tools are likely to be added as the book matures. Though unlikely, tools may also be removed. 88 | -------------------------------------------------------------------------------- /src/chp2/_hands_on.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Hands-on Challenge: Extend the CLI Encryption Tool 16 | 17 | The `rcli` tool we wrote in this chapter is rather basic. 18 | That's by design, it was a short showcase of Rust's features and tooling. 19 | 20 | The goal of our first challenge is to extend this CLI encryption tool. 21 | Some readers may prefer to tackle this challenge after finishing the next chapter, which introduces the Rust language in a more structured fashion. 22 | Others may be itching to write code right now, and willing to pick up more Rust as they go. 23 | 24 | Below are several suggestions for extending the tool. 25 | You may choose one or more. 26 | Feel free to implement your own ideas as well! 27 | 28 | ## Core Cryptography 29 | 30 | * Switch the encryption algorithm from our RC4 implementation to a modern AEAD cipher of your choosing. Making a choice will require some research into the pros and cons of various ciphers. 31 | 32 | * The RustCrypto organization maintains several AEAD algorithm implementations[^AEADList], but you may find other mature libraries suitable. 33 | 34 | * The threat model for a hardware product may include an attacker with 24/7 physical access to a device. Can you find an algorithm and implementation that makes guarantees about timing and power side-channel resistance?[^SideChannel] 35 | 36 | ## CLI UX 37 | 38 | * Add the ability for a user to create a new encrypted file instead of overwriting an existing file. If the user opts to overwrite an existing file, present a color-coded warning (you will want to choose a 3rd party library for coloring terminal output). 39 | 40 | * Add the ability to recursively encrypt every file in a directory (be very careful when testing this, you'll likely want to create a new directory with dummy files!). 41 | 42 | * Instead of printing `Processed {file_name}` to the console, update the tool to print either `Encrypted {file_name}` or `Decrypted {file_name}` (hint: is there a heuristic you can test to identify encrypted byte streams?). 43 | 44 | * Support encryption of files too large to read into memory at once, via buffering. 45 | 46 | ## CLI Integration Testing 47 | 48 | * Add an integration test that runs your CLI binary, providing both command line arguments and temporary files to encrypt or decrypt. You'll likely want to use one or more 3rd party libraries to set up your test harness. 49 | 50 | * Negative tests, meaning those that check for graceful handling of invalid inputs, are a critical part of security testing. Ensure that your integration harness explicitly checks such cases. 51 | 52 |
53 | 54 | --- 55 | 56 | [^AEADList]: [*RustCrypto: Authenticated Encryption with Associated Data (AEAD) Algorithms*](https://github.com/RustCrypto/AEADs). RustCrypto organization (Accessed 2022). 57 | 58 | [^SideChannel]: Side-channel attacks leverage information *leaked* by a physical system (timing, power consumption, electromagnetic emissions, acoustic emissions, etc) to compromise security. In the context of cryptography, this often means extracting secret key material via an indirect means (no software bugs exploited!). Some cryptographic algorithms are designed with this threat model in mind. Their operations are carefully constructed to reduce any externally observable variance, making side-channel attacks significantly more difficult or outright impractical. 59 | -------------------------------------------------------------------------------- /src/chp3/_hands_on.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Hands-on Challenge: Port a Program 16 | 17 | We've covered the bulk of Rust's most important syntax and features. 18 | While you're likely not comfortable with Rust yet, you now know the basics. 19 | 20 | One great way to learn a new language, including its idioms and quirks, is to port an existing program written in a language you're already familiar with. 21 | That's the goal of this challenge. 22 | 23 | Now we're not advocates of the "Rewrite-It-In-Rust" (RIIR) trend, although there are some great Rust alternatives to existing tools out there[^RIIR]. 24 | Rewriting a large piece of software is a risky proposition that, in many contexts, has questionable payoff. 25 | 26 | It's typically wiser to write new features, new services, or hardened components in Rust - such that they can interoperate with existing code. 27 | Chapter 13 will cover integrating Rust into non-Rust codebases. 28 | 29 | Our motivation for this challenge is gaining a deeper understanding of Rust via contrast. 30 | Not all idioms and patterns of other languages readily translate, so experiencing those differences first-hand can be enlightening. 31 | 32 | ## "Failing" is OK 33 | 34 | You might get stuck somewhere in your port attempt. 35 | Depending on the program you choose. 36 | That's fine! 37 | 38 | If that happens, use this challenge as a "personal watermark" - note how far you've come and what the error was. 39 | You can return to the challenge later, after you've had more Rust experience. 40 | Whenever you're up for it. 41 | 42 | ## Port a Program of Your Choice To Rust 43 | 44 | * Choose a small program (maybe less than 1,000 lines) written in a language you know, and rewrite it from scratch in Rust. We recommend you pick a program you've personally written, especially if you ran into performance limitations. But any program you're deeply interested in is a good choice. 45 | 46 | * Before starting your rewrite, review your program's dependencies. If it uses one or more libraries that have no counterpart on Rust's [crates.io](https://crates.io/), you will either need to choose a different program or also write the dependency yourself. Don't over-scope this challenge! 47 | 48 | ## Semi-automate a C to Rust Port 49 | 50 | * If you're already an experienced C developer, you can try porting an existing C program using the `c2rust`[^C2Rust] tool. It's an unofficial, open-source, best-effort transpiler that ingests C source code and outputs Rust source code. 51 | 52 | * The output Rust is, however, both unidiomatic and as `unsafe` as the input C. Translating C to safe Rust is an open research problem[^C2SaferRust] that involves inferring program semantics. So you will still need to do extensive refactoring. 53 | 54 | * Some readers may prefer to return to this challenge after Chapter 13, which covers CFFI and `unsafe`. 55 | 56 | * If you've never written C before but you're incredibly brave and want or need to learn it, you can still do this challenge! We recommend picking up a copy of *Effective C*[^Ccord] to get started. 57 | 58 |
59 | 60 | --- 61 | 62 | [^RIIR]: [*Awesome Alternatives in Rust*](https://github.com/TaKO8Ki/awesome-alternatives-in-rust). Takayuki Maeda (Accessed 2022). 63 | 64 | [^C2Rust]: [*`c2rust`*](https://github.com/immunant/c2rust). Immunant (Accessed 2022). 65 | 66 | [^C2SaferRust]: [*Translating C to Safer Rust*](https://sites.cs.ucsb.edu/~benh/research/papers/oopsla21-extended.pdf). Mehmet Emre, Ryan Schroeder, Kyle Dewey, Ben Hardekopf (2021). 67 | 68 | [^Ccord]: [***[PERSONAL FAVORITE]** Effective C: An Introduction to Professional C Programming*](https://amzn.to/3wBuNu7). Robert Seacord (2020). 69 | -------------------------------------------------------------------------------- /src/chp3/building_blocks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Module
Module
Item
Item

Crate (lib or bin)
Crate (lib or bin)...

System
System...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /src/chp3/count_primes_doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/chp3/count_primes_doc.png -------------------------------------------------------------------------------- /src/chp4/safe_rust_PLACEHOLDER.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Rust's Memory Safety Guarantees 16 | 17 | > **Note:** This section is a work-in-progress. 18 | > For a preview, please see this blog post: 19 | > 20 | > [Blue Team Rust: What is "Memory Safety", Really?](https://tiemoko.com/blog/blue-team-rust/) 21 | 22 |
23 |

24 | 25 |

26 |
An overview of Rust's memory safety model.

27 |
28 |

29 | 30 | --- 31 | -------------------------------------------------------------------------------- /src/download.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Download 16 | --- 17 | 18 | Viewing this book as a webpage is recommended. 19 | For offline viewing, you can clone [the repo](https://github.com/tnballo/high-assurance-rust) to get a full local copy (`make read` to serve locally). 20 | Alternatively: 21 | 22 | * [EPUB](https://tiemoko.com/publications/har.epub) 23 | * Last export: 10/8/23 24 | * SHA-3-256: `23e158a622087b88c906b269c8a0523ae81d17b2e01a89ccb4ea81e4342c5e2e` 25 | 26 | * PDF (coming one day) 27 | 28 | Hashes can be verified with: `openssl dgst -sha3-256 `. 29 | 30 | Enjoy! 31 | -------------------------------------------------------------------------------- /src/engage.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Engage with this Book! 16 | --- 17 | 18 | ## Submit Feedback, Questions, Issues, or PRs 19 | 20 | Have general feedback? 21 | Or maybe a burning question? 22 | 23 | This book is a work-in-progress and your input matters. 24 | We'd love to hear from you, please send an email to: 25 | 26 | **contact@highassurance.rs** 27 | 28 | Spotted a factual or grammatical error? 29 | 30 | Please submit an Issue or Pull Request (PR) on GitHub. 31 | See the project's [`CONTRIBUTING.md`](https://github.com/tnballo/high-assurance-rust/blob/main/CONTRIBUTING.md). 32 | 33 | ## Star the Repos 34 | 35 | You can help increase the visibility of this project among developers by starring its GitHub repos. 36 | We greatly appreciate your support. 37 | 38 | **This Book:** 39 | 40 | 41 | 42 | **`scapegoat` Crate:** 43 | 44 | 45 | 46 | ## Recommend to a Friend 47 | 48 | Consider shooting a link to a friend, they can read the whole book for free! 49 | 50 | Clicking on a subheading within a chapter will display a targeted URL in your browser's address bar. 51 | 52 | ## Cite *High Assurance Rust* 53 | 54 | Though this book is designed with accessibility in mind, we'll delve into advanced topics and contextualize relevant research. 55 | Bottom-of-page footnotes cite primary sources. 56 | 57 | If you'd like to cite this book directly in your own work, please use this BibTeX or similar: 58 | 59 | ```ignore 60 | @misc{high_assurance_rust, 61 | title={High Assurance Rust: Developing Secure and Robust Software}, 62 | url={https://highassurance.rs}, 63 | howpublished = "\url{https://highassurance.rs}", 64 | author={Ballo, Tiemoko and Ballo, Moumine and James, Alex}, 65 | year={2022} 66 | } 67 | ``` 68 | 69 | ## Other Ways to Support this Project 70 | 71 | Please see the [FAQ's question #8, here](./faq.md#8-is-this-book-free). 72 | 73 | Thanks in advance! 74 | 75 | --- 76 | -------------------------------------------------------------------------------- /src/img/faq_venn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Systems
Programming
Systems...
Data
Structures
Data...
Software
Security
Software...
Rust
(Programming
Language)
Rust...
Text is not SVG - cannot display
-------------------------------------------------------------------------------- /src/img/har_logo_social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/har_logo_social.png -------------------------------------------------------------------------------- /src/img/recommended_books/book_c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_c.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_crypto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_crypto.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_csapp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_csapp.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_pba.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_pba.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_phil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_phil.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_rust_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_rust_1.jpg -------------------------------------------------------------------------------- /src/img/recommended_books/book_rust_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/recommended_books/book_rust_2.jpg -------------------------------------------------------------------------------- /src/img/rust_foundation_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/img/rust_foundation_logo.png -------------------------------------------------------------------------------- /src/landing.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |

High Assurance Rust

19 | 20 | 33 | 34 |
35 |
36 |

High Assurance Rust

37 |
38 |

Developing Secure and Robust Software

39 |
40 |
41 | 42 | --- 43 | 44 |
45 |
46 | 47 | [![Repo](https://img.shields.io/github/stars/tnballo/high-assurance-rust?style=social)](https://github.com/tnballo/high-assurance-rust) 48 | [![Pages](https://img.shields.io/badge/Pages-178-purple.svg)](https://github.com/tnballo/high-assurance-rust) 49 | [![Diagrams](https://img.shields.io/badge/Diagrams-51-blue.svg)](https://github.com/tnballo/high-assurance-rust) 50 | [![Price](https://img.shields.io/badge/Price-$0.00-orange.svg)](https://highassurance.rs/cfp.html) 51 | [![Text License: CC BY-NC-ND 4.0](https://img.shields.io/badge/Text%20License-CC%20BY--NC--ND%204.0-yellow.svg)](https://highassurance.rs/license.html) 52 | [![Code License: MIT](https://img.shields.io/badge/Code%20License-MIT-yellowgreen.svg)](https://highassurance.rs/license.html) 53 | [![Assurance](https://img.shields.io/badge/Assurance-High-brightgreen.svg)](https://highassurance.rs) 54 | 55 |
56 |
57 |
58 | 59 | This book is an introduction to building performant software we can **justifiably trust**. 60 | That means having sufficient data to support confidence in our code's functionality and security. 61 | Trustworthiness is a hallmark of **high assurance** software. 62 | 63 | With assurance as our driving concept, we'll take a hands-on, project-based approach to two fundamental but often inaccessible topics in software development: **systems programming** and **low-level software security**. 64 | 65 | You'll learn Rust - a modern, multi-paradigm language that emphasizes speed and correctness. 66 | Most programming books teach a new language by presenting a dozen small, unrealistic programs. 67 | Not this one. 68 | 69 | We'll design, write, and validate a fully-featured alternative to the ordered map and set implementations in Rust's standard library. 70 | You'll gain a deep understanding of the Rust language by re-implementing one of its major dynamic collections, one idiomatic API at a time. 71 | 72 | Unlike the standard version, our implementation will be: 73 | 74 | * **Maximally Safe.** Upholds Rust's strongest memory safety guarantees, for all possible executions. 75 | * To test properties the compiler can't prove, we'll learn advanced program analysis techniques, including *differential fuzzing* and *deductive verification**. 76 | 77 | * **Extremely Portable.** Capable of running on every operating system, or even without one (e.g. "bare metal"). 78 | * Our library is a *hardened component*. To integrate it within larger codebases, we'll add *CFFI bindings* to make the Rust functions callable from other languages - including C and Python. 79 | 80 | * **Highly Available.** Offers *fallible* APIs for handling cases that could otherwise result in a crash. 81 | * E.g. *Out-of-Memory (OOM) error* - when all pre-allocated memory has been exhausted. 82 | 83 | ## The State-of-the-Art in Practical Software Assurance 84 | 85 | We'll use cutting-edge, open-source software assurance tools to validate the code we write in this book. 86 | Some of these tools are mature and used in commercial industry: 87 | 88 | * `rustc` (modern compiler) 89 | * `libFuzzer` (fuzz testing framework) 90 | * `rr` ("time-travel" debugger) 91 | * `qemu` (whole-system emulator) 92 | 93 | Other tools are experimental and under active research. 94 | A full inventory is available in [the appendix](../chp16_appendix/tools.md). 95 | 96 | Visually, this book covers the below topics (contrasted roughly on tradeoff of **development speed** and **formal rigor**). 97 | Don't worry, we'll provide clear explanations and context for each. 98 | 99 | Notice the bias toward development speed. 100 | We're interested in **lightweight processes** that, in the long run, enable us to **ship quality code faster** and spend **less time patching** security and reliability failures. 101 | Techniques you can apply to real-world code. 102 | Today. 103 | 104 |
105 |

Assurance Techniques

106 | 107 | Unlike other Rust books, you won't just learn the language. 108 | You'll learn how to *reason* about software security at the leading edge. 109 | To think like an attacker. 110 | And to write code resistant to attack. 111 | That mental model is valuable no matter what programming language you primarily use. 112 | 113 | ## Sponsors Supporting this Book 114 | 115 | The development of this book (research, writing, and coding) is made possible through the generous support of: 116 | 117 | 124 | 125 | 137 | 138 | > *You need to build a data structure library to serve a mission-critical application. 139 | > It must run on nearly any device, operate in the field for years on end without error, and tolerate attacker-controlled input. 140 | > There will be no patches and there can be no failures. 141 | > Your code must survive. 142 | > **Ship strong.*** 143 | 144 | --- 145 | 146 | > \* == may be subject to change! This book is a [work in progress](./faq.md#8-is-this-book-free). If you'd like to be notified when it's finished and a physical print is available, please [sign up here](https://forms.gle/ESYgXgswCjEoCSHT9). 147 | -------------------------------------------------------------------------------- /src/license.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # License 16 | --- 17 | 18 | ## Book's Text 19 | 20 | All text in this book is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)](https://creativecommons.org/licenses/by-nc-nd/4.0/) license. 21 | 22 | Creative Commons License 23 | 24 | ## Book's Code 25 | 26 | All code in this book (and the [open-source library](https://github.com/tnballo/scapegoat) it's based on) is licensed under the [MIT License](https://opensource.org/licenses/MIT). 27 | 28 | ```ignore 29 | MIT License 30 | 31 | Copyright (c) 2022 Tiemoko Ballo, Moumine Ballo, Alex James 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a copy 34 | of this software and associated documentation files (the "Software"), to deal 35 | in the Software without restriction, including without limitation the rights 36 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 37 | copies of the Software, and to permit persons to whom the Software is 38 | furnished to do so, subject to the following conditions: 39 | 40 | The above copyright notice and this permission notice shall be included in all 41 | copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 48 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 49 | SOFTWARE. 50 | ``` 51 | 52 | --- 53 | -------------------------------------------------------------------------------- /src/templates/_hands_on.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Hands-on Challenge: TITLE HERE 16 | --- 17 | 18 | ## Idea 1 19 | 20 | TODO 21 | 22 | ## Idea 2 23 | 24 | TODO[^Footnote] 25 | 26 | 27 | 28 | --- 29 | 30 | [^Footnote]: [*Article Title*](https://tiemoko.com). Author One, Author Two (YEAR, Domain) 31 | -------------------------------------------------------------------------------- /src/templates/_index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | # Chapter Title 19 | --- 20 | 21 | TODO[^Footnote] 22 | 23 | ## Learning Outcomes 24 | 25 | * TODO 26 | * TODO 27 | * TODO 28 | 29 | --- 30 | 31 | [^Footnote]: [*Article Title*](https://tiemoko.com). Author One, Author Two (YEAR, Domain) 32 | -------------------------------------------------------------------------------- /src/templates/placeholder_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnballo/high-assurance-rust/51ae47d5612c94dddb8c86414be5cf95bc68498e/src/templates/placeholder_img.png -------------------------------------------------------------------------------- /src/templates/section.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Section Title 16 | --- 17 | 18 | TODO[^Footnote] 19 | 20 | ## Subtitle 21 | 22 | TODO 23 | 24 | --- 25 | 26 | [^Footnote]: [*Article Title*](https://tiemoko.com). Author One, Author Two (YEAR, Domain) 27 | -------------------------------------------------------------------------------- /theme/css/variables.css: -------------------------------------------------------------------------------- 1 | 2 | /* Globals */ 3 | 4 | :root { 5 | --sidebar-width: 400px; 6 | --page-padding: 15px; 7 | --content-max-width: 800px; 8 | --menu-bar-height: 50px; 9 | } 10 | 11 | /* Themes */ 12 | 13 | .ayu { 14 | --bg: hsl(210, 25%, 8%); 15 | --fg: #c5c5c5; 16 | 17 | --sidebar-bg: #14191f; 18 | --sidebar-fg: #c8c9db; 19 | --sidebar-non-existant: #5c6773; 20 | --sidebar-active: #ffb454; 21 | --sidebar-spacer: #2d334f; 22 | 23 | --scrollbar: var(--sidebar-fg); 24 | 25 | --icons: #737480; 26 | --icons-hover: #b7b9cc; 27 | 28 | --links: #0096cf; 29 | 30 | --inline-code-color: #ffb454; 31 | 32 | --theme-popup-bg: #14191f; 33 | --theme-popup-border: #5c6773; 34 | --theme-hover: #191f26; 35 | 36 | --quote-bg: hsl(226, 15%, 17%); 37 | --quote-border: hsl(226, 15%, 22%); 38 | 39 | --table-border-color: hsl(210, 25%, 13%); 40 | --table-header-bg: hsl(210, 25%, 28%); 41 | --table-alternate-bg: hsl(210, 25%, 11%); 42 | 43 | --searchbar-border-color: #848484; 44 | --searchbar-bg: #424242; 45 | --searchbar-fg: #fff; 46 | --searchbar-shadow-color: #d4c89f; 47 | --searchresults-header-fg: #666; 48 | --searchresults-border-color: #888; 49 | --searchresults-li-bg: #252932; 50 | --search-mark-bg: #e3b171; 51 | } 52 | 53 | .coal { 54 | --bg: hsl(200, 7%, 8%); 55 | --fg: #98a3ad; 56 | 57 | --sidebar-bg: #292c2f; 58 | --sidebar-fg: #a1adb8; 59 | --sidebar-non-existant: #505254; 60 | --sidebar-active: #3473ad; 61 | --sidebar-spacer: #393939; 62 | 63 | --scrollbar: var(--sidebar-fg); 64 | 65 | --icons: #43484d; 66 | --icons-hover: #b3c0cc; 67 | 68 | --links: #2b79a2; 69 | 70 | --inline-code-color: #c5c8c6; 71 | 72 | --theme-popup-bg: #141617; 73 | --theme-popup-border: #43484d; 74 | --theme-hover: #1f2124; 75 | 76 | --quote-bg: hsl(234, 21%, 18%); 77 | --quote-border: hsl(234, 21%, 23%); 78 | 79 | --table-border-color: hsl(200, 7%, 13%); 80 | --table-header-bg: hsl(200, 7%, 28%); 81 | --table-alternate-bg: hsl(200, 7%, 11%); 82 | 83 | --searchbar-border-color: #aaa; 84 | --searchbar-bg: #b7b7b7; 85 | --searchbar-fg: #000; 86 | --searchbar-shadow-color: #aaa; 87 | --searchresults-header-fg: #666; 88 | --searchresults-border-color: #98a3ad; 89 | --searchresults-li-bg: #2b2b2f; 90 | --search-mark-bg: #355c7d; 91 | } 92 | 93 | .light { 94 | --bg: hsl(0, 0%, 100%); 95 | --fg: hsl(0, 0%, 0%); 96 | 97 | --sidebar-bg: #fafafa; 98 | --sidebar-fg: hsl(0, 0%, 0%); 99 | --sidebar-non-existant: #aaaaaa; 100 | --sidebar-active: #1f1fff; 101 | --sidebar-spacer: #f4f4f4; 102 | 103 | --scrollbar: #8F8F8F; 104 | 105 | --icons: #747474; 106 | --icons-hover: #000000; 107 | 108 | --links: #20609f; 109 | 110 | --inline-code-color: #301900; 111 | 112 | --theme-popup-bg: #fafafa; 113 | --theme-popup-border: #cccccc; 114 | --theme-hover: #e6e6e6; 115 | 116 | --quote-bg: hsl(197, 37%, 96%); 117 | --quote-border: hsl(197, 37%, 91%); 118 | 119 | --table-border-color: hsl(0, 0%, 95%); 120 | --table-header-bg: hsl(0, 0%, 80%); 121 | --table-alternate-bg: hsl(0, 0%, 97%); 122 | 123 | --searchbar-border-color: #aaa; 124 | --searchbar-bg: #fafafa; 125 | --searchbar-fg: #000; 126 | --searchbar-shadow-color: #aaa; 127 | --searchresults-header-fg: #666; 128 | --searchresults-border-color: #888; 129 | --searchresults-li-bg: #e4f2fe; 130 | --search-mark-bg: #a2cff5; 131 | } 132 | 133 | .navy { 134 | --bg: hsl(226, 23%, 11%); 135 | --fg: #bcbdd0; 136 | 137 | --sidebar-bg: #282d3f; 138 | --sidebar-fg: #c8c9db; 139 | --sidebar-non-existant: #505274; 140 | --sidebar-active: #2b79a2; 141 | --sidebar-spacer: #2d334f; 142 | 143 | --scrollbar: var(--sidebar-fg); 144 | 145 | --icons: #737480; 146 | --icons-hover: #b7b9cc; 147 | 148 | --links: #2b79a2; 149 | 150 | --inline-code-color: #c5c8c6; 151 | 152 | --theme-popup-bg: #161923; 153 | --theme-popup-border: #737480; 154 | --theme-hover: #282e40; 155 | 156 | --quote-bg: hsl(226, 15%, 17%); 157 | --quote-border: hsl(226, 15%, 22%); 158 | 159 | --table-border-color: hsl(226, 23%, 16%); 160 | --table-header-bg: hsl(226, 23%, 31%); 161 | --table-alternate-bg: hsl(226, 23%, 14%); 162 | 163 | --searchbar-border-color: #aaa; 164 | --searchbar-bg: #aeaec6; 165 | --searchbar-fg: #000; 166 | --searchbar-shadow-color: #aaa; 167 | --searchresults-header-fg: #5f5f71; 168 | --searchresults-border-color: #5c5c68; 169 | --searchresults-li-bg: #242430; 170 | --search-mark-bg: #a2cff5; 171 | } 172 | 173 | .rust { 174 | --bg: hsl(60, 9%, 87%); 175 | --fg: #262625; 176 | 177 | --sidebar-bg: #3b2e2a; 178 | --sidebar-fg: #c8c9db; 179 | --sidebar-non-existant: #505254; 180 | --sidebar-active: #e69f67; 181 | --sidebar-spacer: #45373a; 182 | 183 | --scrollbar: var(--sidebar-fg); 184 | 185 | --icons: #737480; 186 | --icons-hover: #262625; 187 | 188 | --links: #2b79a2; 189 | 190 | --inline-code-color: #6e6b5e; 191 | 192 | --theme-popup-bg: #e1e1db; 193 | --theme-popup-border: #b38f6b; 194 | --theme-hover: #99908a; 195 | 196 | --quote-bg: hsl(60, 5%, 75%); 197 | --quote-border: hsl(60, 5%, 70%); 198 | 199 | --table-border-color: hsl(60, 9%, 82%); 200 | --table-header-bg: #b3a497; 201 | --table-alternate-bg: hsl(60, 9%, 84%); 202 | 203 | --searchbar-border-color: #aaa; 204 | --searchbar-bg: #fafafa; 205 | --searchbar-fg: #000; 206 | --searchbar-shadow-color: #aaa; 207 | --searchresults-header-fg: #666; 208 | --searchresults-border-color: #888; 209 | --searchresults-li-bg: #dec2a2; 210 | --search-mark-bg: #e69f67; 211 | } 212 | 213 | @media (prefers-color-scheme: dark) { 214 | .light.no-js { 215 | --bg: hsl(200, 7%, 8%); 216 | --fg: #98a3ad; 217 | 218 | --sidebar-bg: #292c2f; 219 | --sidebar-fg: #a1adb8; 220 | --sidebar-non-existant: #505254; 221 | --sidebar-active: #3473ad; 222 | --sidebar-spacer: #393939; 223 | 224 | --scrollbar: var(--sidebar-fg); 225 | 226 | --icons: #43484d; 227 | --icons-hover: #b3c0cc; 228 | 229 | --links: #2b79a2; 230 | 231 | --inline-code-color: #c5c8c6; 232 | 233 | --theme-popup-bg: #141617; 234 | --theme-popup-border: #43484d; 235 | --theme-hover: #1f2124; 236 | 237 | --quote-bg: hsl(234, 21%, 18%); 238 | --quote-border: hsl(234, 21%, 23%); 239 | 240 | --table-border-color: hsl(200, 7%, 13%); 241 | --table-header-bg: hsl(200, 7%, 28%); 242 | --table-alternate-bg: hsl(200, 7%, 11%); 243 | 244 | --searchbar-border-color: #aaa; 245 | --searchbar-bg: #b7b7b7; 246 | --searchbar-fg: #000; 247 | --searchbar-shadow-color: #aaa; 248 | --searchresults-header-fg: #666; 249 | --searchresults-border-color: #98a3ad; 250 | --searchresults-li-bg: #2b2b2f; 251 | --search-mark-bg: #355c7d; 252 | } 253 | } 254 | --------------------------------------------------------------------------------