{"id":13423246,"url":"https://github.com/knurling-rs/flip-link","last_synced_at":"2026-02-17T21:37:35.537Z","repository":{"id":37805971,"uuid":"293586246","full_name":"knurling-rs/flip-link","owner":"knurling-rs","description":"Adds zero-cost stack overflow protection to your embedded programs","archived":false,"fork":false,"pushed_at":"2025-11-27T16:55:32.000Z","size":277,"stargazers_count":385,"open_issues_count":16,"forks_count":14,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-12-10T02:31:38.981Z","etag":null,"topics":["embedded","embedded-rust","ferrous-systems","linkers","rust","rust-tools","tooling"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knurling-rs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["knurling-rs"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-09-07T17:05:51.000Z","updated_at":"2025-12-08T21:47:51.000Z","dependencies_parsed_at":"2024-04-19T09:26:44.520Z","dependency_job_id":"58ddc1e1-ee4e-471e-b71a-c26c95eed2fd","html_url":"https://github.com/knurling-rs/flip-link","commit_stats":{"total_commits":158,"total_committers":14,"mean_commits":"11.285714285714286","dds":0.3607594936708861,"last_synced_commit":"81c25ee4d5c168c17c5d93200bd1215a29277bf5"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/knurling-rs/flip-link","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knurling-rs%2Fflip-link","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knurling-rs%2Fflip-link/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knurling-rs%2Fflip-link/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knurling-rs%2Fflip-link/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knurling-rs","download_url":"https://codeload.github.com/knurling-rs/flip-link/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knurling-rs%2Fflip-link/sbom","scorecard":{"id":564954,"data":{"date":"2025-08-11","repo":{"name":"github.com/knurling-rs/flip-link","commit":"21aeca3d79da4648c9a44f9656012e4f01b9cce6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Code-Review","score":8,"reason":"Found 8/10 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE-APACHE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE-APACHE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Security-Policy","score":9,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/knurling-rs/.github/SECURITY.md:1","Info: Found linked content: github.com/knurling-rs/.github/SECURITY.md:1","Warn: One or no descriptive hints of disclosure, vulnerability, and/or timelines in security policy","Info: Found text in security policy: github.com/knurling-rs/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.1.10 not signed: https://api.github.com/repos/knurling-rs/flip-link/releases/193688581","Warn: release artifact v0.1.9 not signed: https://api.github.com/repos/knurling-rs/flip-link/releases/170169436","Warn: release artifact v0.1.8 not signed: https://api.github.com/repos/knurling-rs/flip-link/releases/145134678","Warn: release artifact v0.1.10 does not have provenance: https://api.github.com/repos/knurling-rs/flip-link/releases/193688581","Warn: release artifact v0.1.9 does not have provenance: https://api.github.com/repos/knurling-rs/flip-link/releases/170169436","Warn: release artifact v0.1.8 does not have provenance: https://api.github.com/repos/knurling-rs/flip-link/releases/145134678"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: invalid parameter name: .github/workflows/release.yml:78","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/changelog.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/changelog.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/changelog.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/changelog.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-plz.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release-plz.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-plz.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release-plz.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:68: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:84: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:118: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:132: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:159: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:176: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:180: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:187: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:205: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:225: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:229: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:236: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:249: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:256: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:289: update your workflow using https://app.stepsecurity.io/secureworkflow/knurling-rs/flip-link/release.yml/main?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/release.yml:67","Warn: downloadThenRun not pinned by hash: .github/workflows/release.yml:125","Info:   0 out of  20 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   2 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/changelog.yml:1","Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release-plz.yml:10","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:18","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T14:43:36.219Z","repository_id":37805971,"created_at":"2025-08-20T14:43:36.219Z","updated_at":"2025-08-20T14:43:36.219Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29558780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T20:52:40.164Z","status":"ssl_error","status_checked_at":"2026-02-17T20:48:10.325Z","response_time":100,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedded","embedded-rust","ferrous-systems","linkers","rust","rust-tools","tooling"],"created_at":"2024-07-31T00:00:25.995Z","updated_at":"2026-02-17T21:37:30.518Z","avatar_url":"https://github.com/knurling-rs.png","language":"Rust","funding_links":["https://github.com/sponsors/knurling-rs"],"categories":["Tools"],"sub_categories":["Paid and commercially available materials","Community Chat Rooms"],"readme":"# `flip-link`\n\n\u003e adds zero-cost stack overflow protection to your embedded programs\n\n## The problem\n\nBare metal Rust programs may *not* be memory safe in presence of stack overflows.\nFor example, this is the case for Rust programs based on v0.6.x of the `cortex-m-rt` crate.\n\nThe following program, which contains no `unsafe` code block, can run into *undefined behavior* if it reaches a stack overflow condition.\n\n``` rust\n// static variables placed in the .bss / .data sections\nstatic FLAG1: AtomicBool = AtomicU32::new(false); // .bss\nstatic FLAG2: AtomicBool = AtomicU32::new(true);  // .data\n\nfn main() {\n    let _x = fib(100);\n}\n\n#[inline(never)]\nfn fib(n: u32) -\u003e u32 {\n    // allocate and initialize 4 kilobytes of stack memory\n    let _use_stack = [0xAA; 1024];\n\n    if n \u003c 2 {\n        1\n    } else {\n        fib(n - 1) + fib(n - 2) // recursion\n    }\n}\n\n#[interrupt]\nfn interrupt_handler() {\n    // does some operation with `FLAG1` and `FLAG2`\n}\n```\n\nThe default memory layout of ARM Cortex-M programs in RAM is shown below.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/overflow.svg\" alt=\"left: default memory layout of ARM Cortex-M programs; right: stack overflow condition\"\u003e\n\u003c/p\u003e\n\nThe function call stack, also known as the \"stack\", grows downwards on function calls and when local variables (e.g. `let x`) are created (these variables are also placed on the stack).\n\nIf the stack grows too large it collides with the `.bss + .data` region, which contains all the program's static variables. The collision results in the static variables being overwritten with unrelated data. This can result in the program observing the static variables in an invalid state: for example an `AtomicBool` may hold the value `3` -- this is undefined behavior because the Rust ABI expects this single-byte variable to be either `0` or `1`.\n\n## The solution\n\nOne potential solution is to change the memory layout of the program and place the stack *below* the `.bss+.data` region.\n\nWith this flipped memory layout (pictured below) the stack cannot collide with the static variables. Instead it will collide with the boundary of the physical RAM memory region. In the ARM Cortex-M architecture, trying to read or write past the boundaries of the RAM region produces a \"hardware exception\". The `cortex-m-rt` crate provides an API to handle this condition: a `HardFault` exception handler can be defined; this \"handler\" (function) will be executed when the invalid memory operation is attempted.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/flipped.svg\" alt=\"left: flipped memory layout; right: stack overflow condition\"\u003e\n\u003c/p\u003e\n\n`flip-link` implements this stack overflow solution. Linking your program with `flip-link` produces the flipped memory layout, which is memory safe in presence of stack overflows.\n\n## Architecture support\n\n`flip-link` is known to work with ARM Cortex-M programs that link to version `0.6.x` of the [`cortex-m-rt`] crate and are linked using the linker shipped with the Rust toolchain (LLD).\nAt this time, it hasn't been tested with other architectures or runtime crates.\n\n[`cortex-m-rt`]: https://crates.io/crates/cortex-m-rt\n\n## Installation\n\n`flip-link` is available on [crates.io]. To install it, run\n\n[crates.io]: https://crates.io/crates/flip-link\n\n```console\n$ cargo install flip-link\n```\n\n## Usage\n\nChange the linker from `rust-lld` (the default) to `flip-link` in `.cargo/config.toml`\n\n``` toml\n[target.'cfg(all(target_arch = \"arm\", target_os = \"none\"))']\n# (..)\nlinker = \"flip-link\"\n```\n\nIn versions of Cargo \u003c 1.74, use `rustflags` to change the linker\n\n``` toml\n[target.'cfg(all(target_arch = \"arm\", target_os = \"none\"))']\n# (..)\nrustflags = [\n  \"-C\", \"linker=flip-link\", # \u003c- add this\n  # (..)\n]\n```\n\nNOTE that if you were using GNU `ld` or GNU `gcc` to link your program then this won't work. Support for other linkers is being tracked in [issue #1].\n\n[issue #1]: https://github.com/knurling-rs/flip-link/issues/1\n\n## Testing\n\nOur CI enforces various checks. You can run them locally to make sure your PR will pass the CI:\n\n* `cargo fmt --all -- --check`\n* `cargo clippy -- --deny warnings`\n* `cargo xtest`\n  * This installs the current revision of `flip-link` and runs `cargo test`.\n\n## Logging\n\nIf you want to see what `flip-link` is up to, you can set these environment variables:\n\n```bash\nexport RUSTC_LOG=rustc_codegen_ssa::back::link=info\nexport RUST_LOG=info\n```\n\nThis will produce something like:\n\n```console\n$ cargo build\n...\n INFO rustc_codegen_ssa::back::link linker stderr:\n [INFO  flip_link] found MemoryEntry(line=3, origin=0x20000000, length=0x10000) in ./target/thumbv7em-none-eabi/debug/build/lm3s6965-3b7087c63b161e04/out/memory.x\n [INFO  flip_link] used RAM spans: origin=0x20000000, length=12, align=4\n [INFO  flip_link] new RAM region: ORIGIN=0x2000fff0, LENGTH=16\n INFO rustc_codegen_ssa::back::link linker stdout:\n INFO rustc_codegen_ssa::back::link linker stdout:\n    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s\n```\n\nYou can see even more detail about how we parse expressions using `RUST_LOG=debug`.\n\n## Support\n\n`flip-link` is part of the [Knurling] project, [Ferrous Systems]' effort at\nimproving tooling used to develop for embedded systems.\n\nIf you think that our work is useful, consider sponsoring it via [GitHub\nSponsors].\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or\n  http://www.apache.org/licenses/LICENSE-2.0)\n\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\nlicensed as above, without any additional terms or conditions.\n\n[Knurling]: https://knurling.ferrous-systems.com\n[Ferrous Systems]: https://ferrous-systems.com/\n[GitHub Sponsors]: https://github.com/sponsors/knurling-rs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknurling-rs%2Fflip-link","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknurling-rs%2Fflip-link","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknurling-rs%2Fflip-link/lists"}