From f4dddea4c375dd0dc472d8879cc4fc506dd77d8c Mon Sep 17 00:00:00 2001 From: zseri Date: Sat, 25 Dec 2021 03:17:06 +0100 Subject: fix(zseri/store-ref-scanner): no_std support and runtime panics This also changes the fuzzing infrastructure from proptest to cargo-fuzz, and this lead to the discovery of two mishandlings of edge-cases: * when a "path_to_store" is at the end of the input, it tried to access the input slice out-of-bounds (the `just_store` test covers that now) * non-ASCII characters lead to an out-of-bounds access in HalfBytesMask (the `non_ascii` test covers that now) Change-Id: Icaa2518dcd93e1789a2c0da4cf0fec46016d3bad Reviewed-on: https://cl.tvl.fyi/c/depot/+/4604 Tested-by: BuildkiteCI Reviewed-by: zseri --- users/zseri/store-ref-scanner/Cargo.lock | 151 -------- users/zseri/store-ref-scanner/Cargo.nix | 396 --------------------- users/zseri/store-ref-scanner/Cargo.toml | 9 - users/zseri/store-ref-scanner/fuzz/.gitignore | 2 + users/zseri/store-ref-scanner/fuzz/Cargo.lock | 124 +++++++ users/zseri/store-ref-scanner/fuzz/Cargo.toml | 31 ++ .../fuzz/fuzz_targets/hbm-roundtrip.rs | 13 + .../store-ref-scanner/fuzz/fuzz_targets/nocrash.rs | 9 + users/zseri/store-ref-scanner/src/hbm.rs | 35 +- users/zseri/store-ref-scanner/src/lib.rs | 38 +- users/zseri/store-ref-scanner/src/spec.rs | 38 +- 11 files changed, 238 insertions(+), 608 deletions(-) create mode 100644 users/zseri/store-ref-scanner/fuzz/.gitignore create mode 100644 users/zseri/store-ref-scanner/fuzz/Cargo.lock create mode 100644 users/zseri/store-ref-scanner/fuzz/Cargo.toml create mode 100644 users/zseri/store-ref-scanner/fuzz/fuzz_targets/hbm-roundtrip.rs create mode 100644 users/zseri/store-ref-scanner/fuzz/fuzz_targets/nocrash.rs (limited to 'users') diff --git a/users/zseri/store-ref-scanner/Cargo.lock b/users/zseri/store-ref-scanner/Cargo.lock index 85b9798b3a8a..f6c466b04e29 100644 --- a/users/zseri/store-ref-scanner/Cargo.lock +++ b/users/zseri/store-ref-scanner/Cargo.lock @@ -2,80 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "camino" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d74260d9bf6944e2208aa46841b4b8f0d7ffc0849a06837b2f510337f86b2b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.112" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" - -[[package]] -name = "ppv-lite86" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -121,29 +47,6 @@ dependencies = [ "syn", ] -[[package]] -name = "proptest" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" -dependencies = [ - "bitflags", - "byteorder", - "lazy_static", - "num-traits", - "quick-error", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", -] - -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - [[package]] name = "quote" version = "1.0.10" @@ -153,59 +56,11 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - [[package]] name = "store-ref-scanner" version = "0.1.0" dependencies = [ - "camino", - "once_cell", "proc_unroll", - "proptest", ] [[package]] @@ -230,9 +85,3 @@ name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/users/zseri/store-ref-scanner/Cargo.nix b/users/zseri/store-ref-scanner/Cargo.nix index d250065d12a5..efe6306eccb7 100644 --- a/users/zseri/store-ref-scanner/Cargo.nix +++ b/users/zseri/store-ref-scanner/Cargo.nix @@ -87,173 +87,6 @@ rec { # inject test dependencies into the build crates = { - "autocfg" = rec { - crateName = "autocfg"; - version = "1.0.1"; - edition = "2015"; - sha256 = "0jj6i9zn4gjl03kjvziqdji6rwx8ykz8zk2ngpc331z2g3fk3c6d"; - authors = [ - "Josh Stone " - ]; - - }; - "bitflags" = rec { - crateName = "bitflags"; - version = "1.3.2"; - edition = "2018"; - sha256 = "12ki6w8gn1ldq7yz9y680llwk5gmrhrzszaa17g1sbrw2r2qvwxy"; - authors = [ - "The Rust Project Developers" - ]; - features = { - "rustc-dep-of-std" = [ "core" "compiler_builtins" ]; - }; - resolvedDefaultFeatures = [ "default" ]; - }; - "byteorder" = rec { - crateName = "byteorder"; - version = "1.4.3"; - edition = "2018"; - sha256 = "0456lv9xi1a5bcm32arknf33ikv76p3fr9yzki4lb2897p2qkh8l"; - authors = [ - "Andrew Gallant " - ]; - features = { - "default" = [ "std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; - "camino" = rec { - crateName = "camino"; - version = "1.0.5"; - edition = "2018"; - sha256 = "0avbz0vh6l9ggf1hd6l4q3zxgw5qni0ni94a43i48sdzv5h45msj"; - authors = [ - "Without Boats " - "Ashley Williams " - "Steve Klabnik " - "Rain " - ]; - features = { - "serde1" = [ "serde" ]; - }; - }; - "cfg-if" = rec { - crateName = "cfg-if"; - version = "1.0.0"; - edition = "2018"; - sha256 = "1za0vb97n4brpzpv8lsbnzmq5r8f2b0cpqqr0sy8h5bn751xxwds"; - authors = [ - "Alex Crichton " - ]; - features = { - "rustc-dep-of-std" = [ "core" "compiler_builtins" ]; - }; - }; - "getrandom" = rec { - crateName = "getrandom"; - version = "0.2.3"; - edition = "2018"; - sha256 = "0lr7mnkvnzdh1xxmwmhhbm4gwg29k3m2rzhpjmjm4k2jcfa9kkbz"; - authors = [ - "The Rand Project Developers" - ]; - dependencies = [ - { - name = "cfg-if"; - packageId = "cfg-if"; - } - { - name = "libc"; - packageId = "libc"; - usesDefaultFeatures = false; - target = { target, features }: (target."unix" or false); - } - { - name = "wasi"; - packageId = "wasi"; - target = { target, features }: (target."os" == "wasi"); - } - ]; - features = { - "js" = [ "wasm-bindgen" "js-sys" ]; - "rustc-dep-of-std" = [ "compiler_builtins" "core" "libc/rustc-dep-of-std" "wasi/rustc-dep-of-std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; - "lazy_static" = rec { - crateName = "lazy_static"; - version = "1.4.0"; - edition = "2015"; - sha256 = "0in6ikhw8mgl33wjv6q6xfrb5b9jr16q8ygjy803fay4zcisvaz2"; - authors = [ - "Marvin Löbel " - ]; - features = { - "spin_no_std" = [ "spin" ]; - }; - }; - "libc" = rec { - crateName = "libc"; - version = "0.2.112"; - edition = "2015"; - sha256 = "09bik7pcck869kfr5i9hjhnck0mzpd9v0ijxbqnh8fja6rzx20qv"; - authors = [ - "The Rust Project Developers" - ]; - features = { - "default" = [ "std" ]; - "rustc-dep-of-std" = [ "align" "rustc-std-workspace-core" ]; - "use_std" = [ "std" ]; - }; - }; - "num-traits" = rec { - crateName = "num-traits"; - version = "0.2.14"; - edition = "2015"; - sha256 = "144j176s2p76azy2ngk2vkdzgwdc0bc8c93jhki8c9fsbknb2r4s"; - authors = [ - "The Rust Project Developers" - ]; - buildDependencies = [ - { - name = "autocfg"; - packageId = "autocfg"; - } - ]; - features = { - "default" = [ "std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; - "once_cell" = rec { - crateName = "once_cell"; - version = "1.9.0"; - edition = "2018"; - sha256 = "1mfqhrsgi368x92bwnq3vi3p5nv0n1qlrn69gfflhvkfkxfm2cns"; - authors = [ - "Aleksey Kladov " - ]; - features = { - "alloc" = [ "race" ]; - "default" = [ "std" ]; - "std" = [ "alloc" ]; - }; - resolvedDefaultFeatures = [ "alloc" "default" "race" "std" ]; - }; - "ppv-lite86" = rec { - crateName = "ppv-lite86"; - version = "0.2.15"; - edition = "2018"; - sha256 = "1fimwnyyh3wx33r5s77lw5g5vcxhw1p5j60pdvbbwr8l374gn37d"; - authors = [ - "The CryptoCorrosion Contributors" - ]; - features = { - "default" = [ "std" ]; - }; - resolvedDefaultFeatures = [ "simd" "std" ]; - }; "proc-macro-error" = rec { crateName = "proc-macro-error"; version = "1.0.4"; @@ -370,81 +203,6 @@ rec { } ]; - }; - "proptest" = rec { - crateName = "proptest"; - version = "1.0.0"; - edition = "2018"; - sha256 = "1rdhjnf0xma5rmsq04d31n2vq1pgbm42pjc6jn3jsj8qgz09q38y"; - authors = [ - "Jason Lingle" - ]; - dependencies = [ - { - name = "bitflags"; - packageId = "bitflags"; - } - { - name = "byteorder"; - packageId = "byteorder"; - usesDefaultFeatures = false; - } - { - name = "lazy_static"; - packageId = "lazy_static"; - optional = true; - } - { - name = "num-traits"; - packageId = "num-traits"; - usesDefaultFeatures = false; - } - { - name = "quick-error"; - packageId = "quick-error"; - optional = true; - } - { - name = "rand"; - packageId = "rand"; - usesDefaultFeatures = false; - features = [ "alloc" ]; - } - { - name = "rand_chacha"; - packageId = "rand_chacha"; - usesDefaultFeatures = false; - } - { - name = "rand_xorshift"; - packageId = "rand_xorshift"; - } - { - name = "regex-syntax"; - packageId = "regex-syntax"; - optional = true; - } - ]; - features = { - "default" = [ "std" "fork" "timeout" "bit-set" "break-dead-code" ]; - "default-code-coverage" = [ "std" "fork" "timeout" "bit-set" ]; - "fork" = [ "std" "rusty-fork" "tempfile" ]; - "hardware-rng" = [ "x86" ]; - "std" = [ "rand/std" "byteorder/std" "lazy_static" "quick-error" "regex-syntax" "num-traits/std" ]; - "timeout" = [ "fork" "rusty-fork/timeout" ]; - }; - resolvedDefaultFeatures = [ "lazy_static" "quick-error" "regex-syntax" "std" ]; - }; - "quick-error" = rec { - crateName = "quick-error"; - version = "2.0.1"; - edition = "2018"; - sha256 = "18z6r2rcjvvf8cn92xjhm2qc3jpd1ljvcbf12zv0k9p565gmb4x9"; - authors = [ - "Paul Colomiets " - "Colin Kiegel " - ]; - }; "quote" = rec { crateName = "quote"; @@ -467,157 +225,17 @@ rec { }; resolvedDefaultFeatures = [ "default" "proc-macro" ]; }; - "rand" = rec { - crateName = "rand"; - version = "0.8.4"; - edition = "2018"; - sha256 = "1n5wska2fbfj4dsfz8mc0pd0dgjlrb6c9anpk5mwym345rip6x9f"; - authors = [ - "The Rand Project Developers" - "The Rust Project Developers" - ]; - dependencies = [ - { - name = "libc"; - packageId = "libc"; - optional = true; - usesDefaultFeatures = false; - target = { target, features }: (target."unix" or false); - } - { - name = "rand_chacha"; - packageId = "rand_chacha"; - optional = true; - usesDefaultFeatures = false; - target = { target, features }: (!(target."os" == "emscripten")); - } - { - name = "rand_core"; - packageId = "rand_core"; - } - ]; - features = { - "alloc" = [ "rand_core/alloc" ]; - "default" = [ "std" "std_rng" ]; - "getrandom" = [ "rand_core/getrandom" ]; - "serde1" = [ "serde" "rand_core/serde1" ]; - "simd_support" = [ "packed_simd" ]; - "std" = [ "rand_core/std" "rand_chacha/std" "alloc" "getrandom" "libc" ]; - "std_rng" = [ "rand_chacha" "rand_hc" ]; - }; - resolvedDefaultFeatures = [ "alloc" "getrandom" "libc" "rand_chacha" "std" ]; - }; - "rand_chacha" = rec { - crateName = "rand_chacha"; - version = "0.3.1"; - edition = "2018"; - sha256 = "123x2adin558xbhvqb8w4f6syjsdkmqff8cxwhmjacpsl1ihmhg6"; - authors = [ - "The Rand Project Developers" - "The Rust Project Developers" - "The CryptoCorrosion Contributors" - ]; - dependencies = [ - { - name = "ppv-lite86"; - packageId = "ppv-lite86"; - usesDefaultFeatures = false; - features = [ "simd" ]; - } - { - name = "rand_core"; - packageId = "rand_core"; - } - ]; - features = { - "default" = [ "std" ]; - "serde1" = [ "serde" ]; - "std" = [ "ppv-lite86/std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; - "rand_core" = rec { - crateName = "rand_core"; - version = "0.6.3"; - edition = "2018"; - sha256 = "1rxlxc3bpzgwphcg9c9yasvv9idipcg2z2y4j0vlb52jyl418kyk"; - authors = [ - "The Rand Project Developers" - "The Rust Project Developers" - ]; - dependencies = [ - { - name = "getrandom"; - packageId = "getrandom"; - optional = true; - } - ]; - features = { - "serde1" = [ "serde" ]; - "std" = [ "alloc" "getrandom" "getrandom/std" ]; - }; - resolvedDefaultFeatures = [ "alloc" "getrandom" "std" ]; - }; - "rand_xorshift" = rec { - crateName = "rand_xorshift"; - version = "0.3.0"; - edition = "2018"; - sha256 = "13vcag7gmqspzyabfl1gr9ykvxd2142q2agrj8dkyjmfqmgg4nyj"; - authors = [ - "The Rand Project Developers" - "The Rust Project Developers" - ]; - dependencies = [ - { - name = "rand_core"; - packageId = "rand_core"; - } - ]; - features = { - "serde1" = [ "serde" ]; - }; - }; - "regex-syntax" = rec { - crateName = "regex-syntax"; - version = "0.6.25"; - edition = "2018"; - sha256 = "16y87hz1bxmmz6kk360cxwfm3jnbsxb3x4zw9x1gzz7khic2i5zl"; - authors = [ - "The Rust Project Developers" - ]; - features = { - "default" = [ "unicode" ]; - "unicode" = [ "unicode-age" "unicode-bool" "unicode-case" "unicode-gencat" "unicode-perl" "unicode-script" "unicode-segment" ]; - }; - resolvedDefaultFeatures = [ "default" "unicode" "unicode-age" "unicode-bool" "unicode-case" "unicode-gencat" "unicode-perl" "unicode-script" "unicode-segment" ]; - }; "store-ref-scanner" = rec { crateName = "store-ref-scanner"; version = "0.1.0"; edition = "2021"; src = lib.cleanSourceWith { filter = sourceFilter; src = ./.; }; dependencies = [ - { - name = "camino"; - packageId = "camino"; - } - { - name = "once_cell"; - packageId = "once_cell"; - } { name = "proc_unroll"; packageId = "proc_unroll"; } ]; - devDependencies = [ - { - name = "proptest"; - packageId = "proptest"; - usesDefaultFeatures = false; - features = [ "std" ]; - } - ]; }; "syn" = rec { @@ -677,20 +295,6 @@ rec { ]; }; - "wasi" = rec { - crateName = "wasi"; - version = "0.10.2+wasi-snapshot-preview1"; - edition = "2018"; - sha256 = "1ii7nff4y1mpcrxzzvbpgxm7a1nn3szjf1n21jnx37c2g6dbsvzx"; - authors = [ - "The Cranelift Project Developers" - ]; - features = { - "default" = [ "std" ]; - "rustc-dep-of-std" = [ "compiler_builtins" "core" "rustc-std-workspace-alloc" ]; - }; - resolvedDefaultFeatures = [ "default" "std" ]; - }; }; # diff --git a/users/zseri/store-ref-scanner/Cargo.toml b/users/zseri/store-ref-scanner/Cargo.toml index c73b517374ca..20b055a9083f 100644 --- a/users/zseri/store-ref-scanner/Cargo.toml +++ b/users/zseri/store-ref-scanner/Cargo.toml @@ -4,13 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -camino = "1.0" -once_cell = "1.9.0" proc_unroll = "0.1" - -[dev-dependencies] - -[dev-dependencies.proptest] -version = "1.0" -default-features = false -features = ["std"] diff --git a/users/zseri/store-ref-scanner/fuzz/.gitignore b/users/zseri/store-ref-scanner/fuzz/.gitignore new file mode 100644 index 000000000000..b400c2782601 --- /dev/null +++ b/users/zseri/store-ref-scanner/fuzz/.gitignore @@ -0,0 +1,2 @@ +corpus +artifacts diff --git a/users/zseri/store-ref-scanner/fuzz/Cargo.lock b/users/zseri/store-ref-scanner/fuzz/Cargo.lock new file mode 100644 index 000000000000..8399066b3cdf --- /dev/null +++ b/users/zseri/store-ref-scanner/fuzz/Cargo.lock @@ -0,0 +1,124 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arbitrary" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc_unroll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ab97d993c96374333148bad5043d3c85a572c1ca81d13b9cf92f23f5ef72f54" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "store-ref-scanner" +version = "0.1.0" +dependencies = [ + "proc_unroll", +] + +[[package]] +name = "store-ref-scanner-fuzz" +version = "0.0.0" +dependencies = [ + "libfuzzer-sys", + "store-ref-scanner", +] + +[[package]] +name = "syn" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" diff --git a/users/zseri/store-ref-scanner/fuzz/Cargo.toml b/users/zseri/store-ref-scanner/fuzz/Cargo.toml new file mode 100644 index 000000000000..baa17132756d --- /dev/null +++ b/users/zseri/store-ref-scanner/fuzz/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "store-ref-scanner-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.store-ref-scanner] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "hbm-roundtrip" +path = "fuzz_targets/hbm-roundtrip.rs" +test = false +doc = false + +[[bin]] +name = "nocrash" +path = "fuzz_targets/nocrash.rs" +test = false +doc = false diff --git a/users/zseri/store-ref-scanner/fuzz/fuzz_targets/hbm-roundtrip.rs b/users/zseri/store-ref-scanner/fuzz/fuzz_targets/hbm-roundtrip.rs new file mode 100644 index 000000000000..0738da68b77d --- /dev/null +++ b/users/zseri/store-ref-scanner/fuzz/fuzz_targets/hbm-roundtrip.rs @@ -0,0 +1,13 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + use core::convert::TryInto; + use store_ref_scanner::HalfBytesMask; + for i in data.chunks_exact(16) { + let a = HalfBytesMask(i.try_into().unwrap()); + let b = a.into_expanded(); + let c = HalfBytesMask::from_expanded(b); + assert_eq!(a, c); + } +}); diff --git a/users/zseri/store-ref-scanner/fuzz/fuzz_targets/nocrash.rs b/users/zseri/store-ref-scanner/fuzz/fuzz_targets/nocrash.rs new file mode 100644 index 000000000000..48100a628d7a --- /dev/null +++ b/users/zseri/store-ref-scanner/fuzz/fuzz_targets/nocrash.rs @@ -0,0 +1,9 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + use store_ref_scanner::{StoreRefScanner, StoreSpec}; + + StoreRefScanner::new(&data[..], &StoreSpec::DFL_NIX2).count(); + StoreRefScanner::new(&data[..], &StoreSpec::DFL_YZIX1).count(); +}); diff --git a/users/zseri/store-ref-scanner/src/hbm.rs b/users/zseri/store-ref-scanner/src/hbm.rs index 881f1dfdeb75..c2fd2950d5f1 100644 --- a/users/zseri/store-ref-scanner/src/hbm.rs +++ b/users/zseri/store-ref-scanner/src/hbm.rs @@ -1,8 +1,7 @@ #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct HalfBytesMask(pub [u8; 16]); -// fires erronously -#[allow(clippy::zero_prefixed_literal)] +#[allow(clippy::as_conversions, clippy::zero_prefixed_literal)] impl HalfBytesMask { pub const B32_REVSHA256: HalfBytesMask = HalfBytesMask([0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 0, 0, 222, 127, 207, 7]); @@ -11,6 +10,10 @@ impl HalfBytesMask { 0, 0, 0, 0, 0, 8, 255, 3, 254, 255, 255, 135, 254, 255, 255, 7, ]); + pub const DFL_REST: HalfBytesMask = HalfBytesMask([ + 0, 0, 0, 0, 0, 104, 255, 163, 254, 255, 255, 135, 254, 255, 255, 7, + ]); + #[inline] #[proc_unroll::unroll] pub const fn from_expanded(x: [bool; 128]) -> Self { @@ -51,7 +54,11 @@ impl HalfBytesMask { } pub fn contains(&self, byte: u8) -> bool { - (self.0[usize::from(byte / 8)] >> u32::from(byte % 8)) & 0b1 != 0 + if byte >= 0x80 { + false + } else { + (self.0[usize::from(byte / 8)] >> u32::from(byte % 8)) & 0b1 != 0 + } } pub fn set(&mut self, byte: u8, allow: bool) { @@ -95,6 +102,13 @@ mod tests { assert_eq!(HalfBytesMask::B64_BLAKE2B256.count_ones(), 64); } + #[test] + fn non_ascii() { + for i in 0x80..=0xff { + assert!(!HalfBytesMask::DFL_REST.contains(i)); + } + } + #[test] fn dflmask() { assert_eq!( @@ -138,15 +152,12 @@ mod tests { ), HalfBytesMask::B64_BLAKE2B256, ); - } - proptest::proptest! { - #[test] - fn hbm_roundtrip(s: [u8; 16]) { - let a = HalfBytesMask(s); - let b = a.into_expanded(); - let c = HalfBytesMask::from_expanded(b); - assert_eq!(a, c); - } + assert_eq!( + HalfBytesMask::from_bytes( + b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-._?=" + ), + HalfBytesMask::DFL_REST, + ); } } diff --git a/users/zseri/store-ref-scanner/src/lib.rs b/users/zseri/store-ref-scanner/src/lib.rs index 63b3689978ff..ae1912c555c6 100644 --- a/users/zseri/store-ref-scanner/src/lib.rs +++ b/users/zseri/store-ref-scanner/src/lib.rs @@ -1,4 +1,6 @@ -// TODO: make this no_std if possible +#![no_std] +#![forbid(clippy::cast_ptr_alignment, trivial_casts, unconditional_recursion)] +#![deny(clippy::as_conversions)] mod hbm; pub use hbm::HalfBytesMask; @@ -34,7 +36,7 @@ impl ScannerInput for &mut [u8] { fn split_to(&mut self, at: usize) -> Self { // Lifetime dance taken from `impl Write for &mut [u8]`. // Taken from crate `std`. - let (a, b) = std::mem::take(self).split_at_mut(at); + let (a, b) = core::mem::take(self).split_at_mut(at); *self = b; a } @@ -50,14 +52,14 @@ impl ScannerInput for &mut [u8] { /// and implements an iterator interfaces which returns these as byte slices. pub struct StoreRefScanner<'x, Input: 'x> { input: Input, - spec: &'x StoreSpec, + spec: &'x StoreSpec<'x>, } impl<'x, Input> StoreRefScanner<'x, Input> where Input: ScannerInput + 'x, { - pub fn new(input: Input, spec: &'x StoreSpec) -> Self { + pub fn new(input: Input, spec: &'x StoreSpec<'x>) -> Self { for i in [&spec.valid_hashbytes, &spec.valid_restbytes] { for j in [b'\0', b' ', b'\t', b'\n', b'/', b'\\'] { assert!(!i.contains(j)); @@ -74,11 +76,10 @@ where type Item = Input; fn next(&mut self) -> Option { - let empty_path = camino::Utf8Path::new(""); let hbl: usize = self.spec.hashbytes_len.into(); while !self.input.as_ref().is_empty() { - if self.spec.path_to_store != empty_path { - let p2sas = self.spec.path_to_store.as_str(); + if !self.spec.path_to_store.is_empty() { + let p2sas = self.spec.path_to_store; if self.input.as_ref().starts_with(p2sas.as_bytes()) { self.input.split_to(p2sas.len()); } else { @@ -87,6 +88,9 @@ where } } let hsep = matches!(self.input.as_ref().iter().next(), Some(b'/') | Some(b'\\')); + if self.input.as_ref().is_empty() { + break; + } self.input.split_to(1); if hsep && self.spec.check_rest(self.input.as_ref()) { // we have found a valid hash @@ -114,6 +118,8 @@ where #[cfg(test)] mod tests { use super::*; + extern crate alloc; + use alloc::{vec, vec::Vec}; #[test] fn simple_nix2() { @@ -121,7 +127,7 @@ mod tests { Derive([("out","","r:sha256","")],[("/nix/store/2ax7bvjdfkzim69q957i0jlg0nvmapg0-util-linux-2.37.2.drv",["dev"]),("/nix/store/6b55ssmh8pzqsc4q4kw1yl3kqvr4fvqj-bash-5.1-p12.drv",["out"]),("/nix/store/fp2vx24kczlzv84avds28wyzsmrn8kyv-source.drv",["out"]),("/nix/store/s6c2lm5hpsvdwnxq9y1g3ngncghjzc3k-stdenv-linux.drv",["out"]),("/nix/store/xlnzpf4mzghi8vl0krabrgcbnqk5qjf3-pkg-config-wrapper-0.29.2.drv",["out"])],["/nix/store/03sl46khd8gmjpsad7223m32ma965vy9-fix-static.patch","/nix/store/2q3z7587yhlz0i2xvfvvap42zk5carlv-bcache-udev-modern.patch","/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],"x86_64-linux","/0g15yibzzi3rmw29gqlbms05x9dbghbvh61v1qggydvmzh3bginw/bin/bash",["-e","/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],[("buildInputs","/0sdk1r4l43yw4g6lmqdhd92vhdfhlwz3m76jxzvzsqsv63czw2km"),("builder","/0g15yibzzi3rmw29gqlbms05x9dbghbvh61v1qggydvmzh3bginw/bin/bash"),("configureFlags",""),("depsBuildBuild",""),("depsBuildBuildPropagated",""),("depsBuildTarget",""),("depsBuildTargetPropagated",""),("depsHostHost",""),("depsHostHostPropagated",""),("depsTargetTarget",""),("depsTargetTargetPropagated",""),("doCheck",""),("doInstallCheck",""),("makeFlags","PREFIX=/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9 UDEVLIBDIR=/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9/lib/udev/"),("name","bcache-tools-1.0.7"),("nativeBuildInputs","/1kw0rwgdyq9q69wmmsa5d2kap6p52b0yldbzi4w17bhcq5g5cp2f"),("out","/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"),("outputHashAlgo","sha256"),("outputHashMode","recursive"),("outputs","out"),("patches","/nix/store/2q3z7587yhlz0i2xvfvvap42zk5carlv-bcache-udev-modern.patch /nix/store/03sl46khd8gmjpsad7223m32ma965vy9-fix-static.patch"),("pname","bcache-tools"),("preBuild","sed -e \"s|/bin/sh|/0g15yibzzi3rmw29gqlbms05x9dbghbvh61v1qggydvmzh3bginw/bin/sh|\" -i *.rules\n"),("preInstall","mkdir -p \"$out/sbin\" \"$out/lib/udev/rules.d\" \"$out/share/man/man8\"\n"),("prePatch","sed -e \"/INSTALL.*initramfs\\/hook/d\" \\\n -e \"/INSTALL.*initcpio\\/install/d\" \\\n -e \"/INSTALL.*dracut\\/module-setup.sh/d\" \\\n -e \"s/pkg-config/$PKG_CONFIG/\" \\\n -i Makefile\n"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("src","/nix/store/6izcafvfcbz19chi7hl20834g0fa043n-source"),("stdenv","/01ncyv8bxibj0imgfvmxgqy648n697bachil6aw6i46g1jk0bbds"),("strictDeps",""),("system","x86_64-linux"),("version","1.0.7")]) "#; // we convert everything into strings because it is way easier to compare elements in error messages - let refs: Vec<&str> = StoreRefScanner::new(drv, &*SPEC_DFL_NIX2) + let refs: Vec<&str> = StoreRefScanner::new(drv, &StoreSpec::DFL_NIX2) .map(|i| core::str::from_utf8(i).unwrap()) .collect(); let refs_expect: Vec<&[u8]> = vec![ @@ -168,7 +174,7 @@ mod tests { /yzixs/xvwEcXIob_rQynUEtQiQbwaDXEobTVKEGaBMir9oH9k: unified diff output, ASCII text /yzixs/ZPvQbRJrtyeSITvW3FUZvw99hhNOO3CFqGgmWgScxcg: ASCII text "#; - let refs: Vec<&str> = StoreRefScanner::new(fake, &*SPEC_DFL_YZIX1) + let refs: Vec<&str> = StoreRefScanner::new(fake, &StoreSpec::DFL_YZIX1) .map(|i| core::str::from_utf8(i).unwrap()) .collect(); let refs_expect: Vec<&[u8]> = vec![ @@ -198,15 +204,11 @@ mod tests { assert_eq!(refs, refs_expect); } - proptest::proptest! { - #[test] - fn nocrash_nix2(s: Vec) { - let _ = StoreRefScanner::new(&s[..], &*SPEC_DFL_NIX2).count(); - } - - #[test] - fn nocrash_yzix1(s: Vec) { - let _ = StoreRefScanner::new(&s[..], &*SPEC_DFL_YZIX1).count(); + #[test] + fn just_store() { + for i in [&StoreSpec::DFL_NIX2, &StoreSpec::DFL_YZIX1] { + let refs: Vec<&[u8]> = StoreRefScanner::new(i.path_to_store.as_bytes(), i).collect(); + assert!(refs.is_empty()); } } } diff --git a/users/zseri/store-ref-scanner/src/spec.rs b/users/zseri/store-ref-scanner/src/spec.rs index 034779e8e8dc..79da0842c529 100644 --- a/users/zseri/store-ref-scanner/src/spec.rs +++ b/users/zseri/store-ref-scanner/src/spec.rs @@ -1,10 +1,8 @@ use crate::hbm::HalfBytesMask; -use camino::Utf8PathBuf; -use once_cell::sync::Lazy; -pub struct StoreSpec { +pub struct StoreSpec<'path> { /// path to store without trailing slash - pub path_to_store: Utf8PathBuf, + pub path_to_store: &'path str, /// compressed map of allowed ASCII characters in hash part pub valid_hashbytes: HalfBytesMask, @@ -16,7 +14,7 @@ pub struct StoreSpec { pub hashbytes_len: u8, } -impl StoreSpec { +impl StoreSpec<'_> { pub(crate) fn check_rest(&self, rest: &[u8]) -> bool { let hbl = self.hashbytes_len.into(); rest.iter() @@ -25,22 +23,18 @@ impl StoreSpec { .count() == hbl } -} -pub static SPEC_DFL_NIX2: Lazy = Lazy::new(|| StoreSpec { - path_to_store: "/nix/store".into(), - valid_hashbytes: HalfBytesMask::B32_REVSHA256, - valid_restbytes: HalfBytesMask::from_bytes( - b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-._?=", - ), - hashbytes_len: 32, -}); + pub const DFL_NIX2: StoreSpec<'static> = StoreSpec { + path_to_store: "/nix/store", + valid_hashbytes: HalfBytesMask::B32_REVSHA256, + valid_restbytes: HalfBytesMask::DFL_REST, + hashbytes_len: 32, + }; -pub static SPEC_DFL_YZIX1: Lazy = Lazy::new(|| StoreSpec { - path_to_store: "/yzixs".into(), - valid_hashbytes: HalfBytesMask::B64_BLAKE2B256, - valid_restbytes: HalfBytesMask::from_bytes( - b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-._?=", - ), - hashbytes_len: 43, -}); + pub const DFL_YZIX1: StoreSpec<'static> = StoreSpec { + path_to_store: "/yzixs", + valid_hashbytes: HalfBytesMask::B64_BLAKE2B256, + valid_restbytes: HalfBytesMask::DFL_REST, + hashbytes_len: 43, + }; +} -- cgit 1.4.1