├── .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 |
2 |
3 | # High Assurance Rust
4 |
5 | [](https://github.com/tnballo/high-assurance-rust)
6 | [](https://github.com/tnballo/high-assurance-rust)
7 | [](https://highassurance.rs/cfp.html)
8 | [](https://highassurance.rs/license.html)
9 | [](https://highassurance.rs/license.html)
10 | [](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... Text is not SVG - cannot display
--------------------------------------------------------------------------------
/docs/chp3/building_blocks.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Module Item Crate (lib or bin)... 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... Data... 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 = "[ 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... 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 Iterative Program ICFG
square 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 Item Crate (lib or bin)... 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... Data... 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 |
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 | [](https://github.com/tnballo/high-assurance-rust)
48 | [](https://github.com/tnballo/high-assurance-rust)
49 | [](https://github.com/tnballo/high-assurance-rust)
50 | [](https://highassurance.rs/cfp.html)
51 | [](https://highassurance.rs/license.html)
52 | [](https://highassurance.rs/license.html)
53 | [](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 |
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 |
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 |
--------------------------------------------------------------------------------