diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5e59d5..fe228c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,8 @@ jobs: run: cargo fmt --check - name: Clippy run: cargo clippy --workspace --all-targets -- -D warnings + - name: Clippy LibAFL fuzzer + run: cargo clippy --workspace -F with_libafl -- -D warnings build_and_test: name: Rust project - latest runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index f17d715..c8862a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "afl" version = "0.15.11" @@ -14,11 +29,38 @@ dependencies = [ "xdg", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -31,49 +73,49 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] @@ -86,6 +128,12 @@ dependencies = [ "ziggy", ] +[[package]] +name = "arbitrary-int" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d" + [[package]] name = "asan-fuzz" version = "0.1.0" @@ -93,6 +141,74 @@ dependencies = [ "ziggy", ] +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitbybit" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb157f9753a7cddfcf4a4f5fed928fbf4ce1b7b64b6bcc121d7a9f95d698997b" +dependencies = [ + "arbitrary-int", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "camino" version = "1.1.9" @@ -125,11 +241,54 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -137,9 +296,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -161,15 +320,21 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" + +[[package]] +name = "cobs" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "console" @@ -181,26 +346,104 @@ dependencies = [ "lazy_static", "libc", "unicode-width", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "const_format" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "const_panic" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "013b6c2c3a14d678f38cd23994b02da3a1a1b6a5d1eedddfe63a5a5f11b13a81" +dependencies = [ + "typewit", +] + +[[package]] +name = "ctor" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +dependencies = [ + "quote", + "syn", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "fork" version = "0.1.23" @@ -219,25 +462,69 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "free-cpus" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d075faa40bcd39333046862075f62f1493921c47b15a7b13fc283df0192ad239" +dependencies = [ + "anyhow", + "num_cpus", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "home" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -253,141 +540,737 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.5.0" +name = "hostname" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "cfg-if", + "libc", + "windows 0.52.0", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.1" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "itoa" -version = "1.0.11" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] [[package]] -name = "lazy_static" +name = "icu_locid_transform" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] [[package]] -name = "libc" -version = "0.2.160" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "memchr" -version = "2.7.4" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] [[package]] -name = "memmap2" -version = "0.9.5" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "libc", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "icu_properties_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" [[package]] -name = "proc-macro2" -version = "1.0.88" +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "unicode-ident", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "quote" -version = "1.0.37" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", + "quote", + "syn", ] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "semver", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "semver" -version = "1.0.23" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "serde", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "serde" -version = "1.0.210" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "serde_derive" -version = "1.0.210" +name = "itertools" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ - "proc-macro2", - "quote", - "syn", + "either", ] [[package]] -name = "serde_json" -version = "1.0.128" +name = "itoa" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "strip-ansi-escapes" -version = "0.2.0" +name = "jobserver" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ - "vte", + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libafl" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f389b9fb070347cb0e62fc7c310f6b4ca134a93975d6bb53653b6bb5a4a3ad5d" +dependencies = [ + "ahash", + "arbitrary-int", + "backtrace", + "bincode", + "bitbybit", + "const_format", + "const_panic", + "hashbrown", + "libafl_bolts", + "libafl_derive", + "libc", + "libm", + "log", + "meminterval", + "nix", + "num-traits", + "postcard", + "regex", + "rustversion", + "serde", + "serde_json", + "serial_test", + "tuple_list", + "typed-builder", + "uuid", + "wait-timeout", + "windows 0.58.0", +] + +[[package]] +name = "libafl_bolts" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6273d4640897a2e93802e58977803bc7c6ecc76b337457dd134c4f212b060caf" +dependencies = [ + "ahash", + "backtrace", + "ctor", + "erased-serde", + "hashbrown", + "hostname", + "libafl_derive", + "libc", + "log", + "mach", + "miniz_oxide", + "nix", + "num_enum", + "postcard", + "rand_core", + "rustversion", + "serde", + "serial_test", + "static_assertions", + "tuple_list", + "uds", + "uuid", + "windows 0.58.0", + "windows-result", + "xxhash-rust", +] + +[[package]] +name = "libafl_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2859c499ffb68ebb4e504ac1cb1199c18b2fb2978dfa85b1f60591115cdbfbc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libafl_targets" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "769419bf7549eea365ee7a3ef97977ab54e513c1b53fb15969bc97b446cea868" +dependencies = [ + "bindgen", + "cc", + "hashbrown", + "libafl", + "libafl_bolts", + "libc", + "log", + "once_cell", + "rangemap", + "rustversion", + "serde", +] + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "meminterval" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f8614cf855d251be1c2138d330c04f134923fddec0dcfc8b6f58ac499bf248" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rangemap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scc" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" +dependencies = [ + "sdd", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdd" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strip-ansi-escapes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +dependencies = [ + "vte", ] [[package]] @@ -398,29 +1281,40 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -434,52 +1328,94 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e32d019b4f7c100bcd5494e40a27119d45b71fba2b07a4684153129279a4647" [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "tuple_list" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "141fb9f71ee586d956d7d6e4d5a9ef8e946061188520140f7591b668841d502e" [[package]] -name = "unicode-bidi" -version = "0.3.17" +name = "typed-builder" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "7e14ed59dc8b7b26cacb2a92bad2e8b1f098806063898ab42a3bd121d7d45e75" +dependencies = [ + "typed-builder-macro", +] [[package]] -name = "unicode-ident" -version = "1.0.13" +name = "typed-builder-macro" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "unicode-normalization" -version = "0.1.24" +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + +[[package]] +name = "typewit" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "uds" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "885c31f06fce836457fe3ef09a59f83fe8db95d270b11cd78f40a4666c4d1661" dependencies = [ - "tinyvec", + "libc", ] +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + [[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -494,12 +1430,40 @@ dependencies = [ "ziggy", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "vte" version = "0.11.1" @@ -520,6 +1484,104 @@ dependencies = [ "quote", ] +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -529,6 +1591,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -593,12 +1664,117 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xdg" version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" +[[package]] +name = "xxhash-rust" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ziggy" version = "1.3.0" @@ -609,8 +1785,12 @@ dependencies = [ "clap", "console", "fork", + "free-cpus", "glob", "honggfuzz", + "libafl", + "libafl_bolts", + "libafl_targets", "libc", "semver", "strip-ansi-escapes", diff --git a/Cargo.toml b/Cargo.toml index 6a7d374..dc6e7b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,12 @@ cargo_metadata = { version = "0.18.1", optional = true } clap = { version = "4.5.4", features = ["cargo", "derive", "env"], optional = true } console = { version = "0.15.8", optional = true } fork = { version = "0.1.23", optional = true } +free-cpus = { version = "2.0.0", optional = true } glob = { version = "0.3.1", optional = true } honggfuzz = { version = "0.5.56", optional = true } +libafl = { version = "0.14.0", optional = true } +libafl_bolts = { version = "0.14.0", optional = true } +libafl_targets = { version = "0.14.0", optional = true, features = ["sancov_pcguard_hitcounts"] } libc = { version = "0.2.153", optional = true } semver = { version = "1.0.23", optional = true } strip-ansi-escapes = { version = "0.2.0", optional = true } @@ -41,6 +45,7 @@ cli = [ "time-humanize", "cargo_metadata", ] +with_libafl = ["libafl", "libafl_targets", "libafl_bolts", "free-cpus"] coverage = ["fork", "libc"] [lints.clippy] diff --git a/examples/arbitrary/src/main.rs b/examples/arbitrary/src/main.rs index 1377a89..cc5139f 100644 --- a/examples/arbitrary/src/main.rs +++ b/examples/arbitrary/src/main.rs @@ -11,8 +11,7 @@ impl Rgb { #[must_use] pub fn as_hex(&self) -> Hex { let Rgb { r, g, b } = self; - let panic_u8: u8 = 17; - if r == &panic_u8 { + if r == b && *b == 5 + g && g % 128 == 42 { panic!("let the fuzzer find this"); } Hex(format!("{:02X}{:02X}{:02X}", r, g, b)) diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 7b0ebec..684f8ef 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -12,7 +12,7 @@ impl Build { /// Build the fuzzers pub fn build(&self) -> Result<(), anyhow::Error> { // No fuzzers for you - if self.no_afl && self.no_honggfuzz { + if self.no_afl && self.no_honggfuzz && self.no_libafl { return Err(anyhow!("Pick at least one fuzzer")); } @@ -72,6 +72,30 @@ impl Build { eprintln!(" {} afl", style("Finished").cyan().bold()); } + if !self.no_libafl { + eprintln!(" {} libafl", style("Building").red().bold()); + + // Third fuzzer we build: LibAFL + let run = process::Command::new(&cargo) + .args(["build", "--features=ziggy/with_libafl ", "--target=x86_64-unknown-linux-gnu", "--release"]) + .env("CARGO_TARGET_DIR", "./target/libafl") + .env("RUSTFLAGS", "-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard --cfg fuzzing -Clink-arg=-fuse-ld=gold") + .env("LIBAFL_EDGES_MAP_SIZE", "500000") + .stdout(process::Stdio::piped()) + .spawn()? + .wait() + .context("Error spawning hfuzz build command")?; + + if !run.success() { + return Err(anyhow!( + "Error building libafl fuzzer: Exited with {:?}", + run.code() + )); + } + + eprintln!(" {} libafl", style("Finished").cyan().bold()); + } + if !self.no_honggfuzz { assert!( !self.asan, @@ -108,4 +132,31 @@ impl Build { } Ok(()) } + + /* + + //if !no_libafl { + eprintln!(" {} libafl", style("Building").red().bold()); + + // Third fuzzer we build: Honggfuzz + let run = process::Command::new(cargo) + .args(["build"]) + .env("CARGO_TARGET_DIR", "./target/honggfuzz") + .env("HFUZZ_BUILD_ARGS", "--features=ziggy/honggfuzz") + .stdout(process::Stdio::piped()) + .spawn()? + .wait() + .context("Error spawning hfuzz build command")?; + + if !run.success() { + return Err(anyhow!( + "Error building honggfuzz fuzzer: Exited with {:?}", + run.code() + )); + } + + eprintln!(" {} honggfuzz", style("Finished").cyan().bold()); + //} + + */ } diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index b19ae3b..6ad7248 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -35,6 +35,18 @@ use strip_ansi_escapes::strip_str; /// ``` /// The `all_afl_corpora` directory corresponds to the `output/target_name/afl/**/queue/` directories. +struct FuzzerWeights { + afl: u32, + libafl: u32, + honggfuzz: u32, +} + +const FUZZER_WEIGHTS: FuzzerWeights = FuzzerWeights { + afl: 3, + libafl: 2, + honggfuzz: 1, +}; + impl Fuzz { pub fn corpus(&self) -> String { self.corpus @@ -61,18 +73,24 @@ impl Fuzz { !self.no_afl } + /// Returns true if LibAFL is enabled + pub fn libafl(&self) -> bool { + !self.no_libafl && (self.no_afl || self.jobs > 1) + } + /// Returns true if Honggfuzz is enabled // This definition could be a one-liner but it was expanded for clarity pub fn honggfuzz(&self) -> bool { if self.fuzz_binary() { // We cannot use honggfuzz in binary mode false - } else if self.no_afl { - // If we have "no_afl" set then honggfuzz is always enabled + } else if self.no_afl && self.no_libafl { + // If we have "no_afl" and "no_libafl" set then honggfuzz is always enabled true + } else if self.no_afl || self.no_libafl { + return !self.no_honggfuzz && self.jobs > 1; } else { - // If honggfuzz is not disabled, we use it if there are more than 1 jobs - !self.no_honggfuzz && self.jobs > 1 + return !self.no_honggfuzz && self.jobs > 2; } } @@ -85,6 +103,7 @@ impl Fuzz { if !self.fuzz_binary() { let build = Build { no_afl: !self.afl(), + no_libafl: !self.libafl(), no_honggfuzz: !self.honggfuzz(), release: self.release, asan: self.asan, @@ -282,16 +301,22 @@ impl Fuzz { self.output_target(), self.target ) - .into()]); + .into()]) + .chain(vec![ + format!("{}/libafl/crashes", self.output_target()).into() + ]); for crash_dir in crash_dirs { if let Ok(crashes) = fs::read_dir(crash_dir) { for crash_input in crashes.flatten() { let file_name = crash_input.file_name(); let to_path = crash_path.join(&file_name); + let file_name_str = file_name.to_str().unwrap_or_default(); if to_path.exists() || ["", "README.txt", "HONGGFUZZ.REPORT.TXT", "input"] - .contains(&file_name.to_str().unwrap_or_default()) + .contains(&file_name_str) + || file_name_str.contains(".lafl_lock") + || file_name_str.contains(".metadata") { continue; } @@ -334,10 +359,52 @@ impl Fuzz { } } + pub fn compute_job_repartition(&self) -> (u32, u32, u32) { + let afl_weight = if self.afl() { FUZZER_WEIGHTS.afl } else { 0 }; + let libafl_weight = if self.libafl() { + FUZZER_WEIGHTS.libafl + } else { + 0 + }; + let honggfuzz_weight = if self.honggfuzz() { + FUZZER_WEIGHTS.honggfuzz + } else { + 0 + }; + let total_weights = afl_weight + libafl_weight + honggfuzz_weight; + + let mut honggfuzz_jobs = honggfuzz_weight * self.jobs / total_weights; + let mut afl_jobs = afl_weight * self.jobs / total_weights; + let mut libafl_jobs = libafl_weight * self.jobs / total_weights; + + // We adjust the numbers because of potential rounding errors + while honggfuzz_jobs + afl_jobs + libafl_jobs < self.jobs { + if self.honggfuzz() { + honggfuzz_jobs += 1; + } else if self.libafl() { + libafl_jobs += 1; + } else if self.afl() { + afl_jobs += 1; + } + } + + // If Honggfuzz is not the only fuzzer, we will not allow it to get more than 4 parallel jobs. + if honggfuzz_jobs > 4 && (self.afl() || self.libafl()) { + if self.afl() { + afl_jobs += honggfuzz_jobs - 4; + } else if self.libafl() { + libafl_jobs += honggfuzz_jobs - 4; + } + honggfuzz_jobs = 4; + } + + (afl_jobs, libafl_jobs, honggfuzz_jobs) + } + // Spawns new fuzzers pub fn spawn_new_fuzzers(&self) -> Result, anyhow::Error> { // No fuzzers for you - if self.no_afl && self.no_honggfuzz { + if self.no_afl && self.no_honggfuzz && self.no_libafl { return Err(anyhow!( "Pick at least one fuzzer.\nNote: -b/--binary implies --no-honggfuzz" )); @@ -348,21 +415,8 @@ impl Fuzz { // The cargo executable let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); - let (afl_jobs, honggfuzz_jobs) = { - if self.no_afl { - (0, self.jobs) - } else if self.no_honggfuzz || self.fuzz_binary() { - (self.jobs, 0) - } else { - // we assign roughly 2/3 to AFL++, 1/3 to honggfuzz, however do - // not apply more than 4 jobs to honggfuzz - match self.jobs { - 1 => (1, 0), - 2..=12 => (self.jobs - ((self.jobs + 2) / 3), (self.jobs + 2) / 3), - _ => (self.jobs - 4, 4), - } - } - }; + // We compute the jobs assigned to each fuzzer, according to FUZZER_WEIGHTS + let (afl_jobs, libafl_jobs, honggfuzz_jobs) = self.compute_job_repartition(); if honggfuzz_jobs > 4 { eprintln!("Warning: running more honggfuzz jobs than 4 is not effective"); @@ -516,6 +570,41 @@ impl Fuzz { eprintln!("{} afl ", style(" Launched").green().bold()); } + if libafl_jobs > 0 { + let _ = process::Command::new("mkdir") + .args(["-p", &format!("{}/libafl/logs", self.output_target())]) + .stderr(process::Stdio::piped()) + .spawn()? + .wait()?; + + fuzzer_handles.push( + process::Command::new(format!( + "./target/libafl/x86_64-unknown-linux-gnu/release/{}", + self.target + )) + .env("LIBAFL_TARGET_NAME", &self.target) + .env("LIBAFL_SHARED_CORPUS", self.corpus()) + .env( + "LIBAFL_CRASHES", + format!("{}/libafl/crashes", self.output_target()), + ) + .env("LIBAFL_CORES", format!("{libafl_jobs}")) + .stderr(File::create(format!( + "{}/logs/libafl.log", + self.output_target(), + ))?) + .stdout(File::create(format!( + "{}/logs/libafl.log", + self.output_target() + ))?) + .spawn()?, + ); + eprintln!( + "{} libafl ", + style(" Launched").green().bold() + ); + } + if honggfuzz_jobs > 0 { let hfuzz_help = process::Command::new(&cargo) .args(["hfuzz", "run", &self.target]) @@ -772,7 +861,49 @@ impl Fuzz { } } - // Second step: Get stats from honggfuzz logs + // Second step: Get stats from libafl + let mut libafl_status = format!("{green}running{reset} ─"); + let mut libafl_clients = String::new(); + let mut libafl_speed = String::new(); + let mut libafl_coverage = String::new(); + let mut libafl_crashes = String::new(); + let mut libafl_total_execs = String::new(); + + if !self.libafl() { + libafl_status = format!("{yellow}disabled{reset} "); + } else { + let hf_stats_process = process::Command::new("tail") + .args(["-n10", &format!("{}/logs/libafl.log", self.output_target())]) + .output(); + if let Ok(process) = hf_stats_process { + let s = std::str::from_utf8(&process.stdout).unwrap_or_default(); + for raw_line in s.split('\n') { + let global = raw_line.contains("GLOBAL"); + let stripped_line = strip_str(raw_line); + let line = stripped_line.trim(); + for stat in line.split(", ") { + if global { + if let Some(clients) = stat.strip_prefix("clients: ") { + libafl_clients = format!( + "{}", + clients.parse::().unwrap_or(1).saturating_sub(1) + ) + } else if let Some(objectives) = stat.strip_prefix("objectives: ") { + libafl_crashes = objectives.to_string(); + } else if let Some(executions) = stat.strip_prefix("executions: ") { + libafl_total_execs = executions.to_string(); + } else if let Some(exec_sec) = stat.strip_prefix("exec/sec: ") { + libafl_speed = exec_sec.to_string(); + } + } else if let Some(edges) = stat.strip_prefix("edges: ") { + libafl_coverage = edges.to_string(); + } + } + } + } + } + + // Third step: Get stats from honggfuzz logs let mut hf_status = format!("{green}running{reset} ─"); let mut hf_total_execs = String::new(); let mut hf_threads = String::new(); @@ -849,7 +980,7 @@ impl Fuzz { } } - // Third step: Get global stats + // Fourth step: Get global stats let mut total_run_time = time_humanize::HumanTime::from(self.start_time.elapsed()) .to_text_en( time_humanize::Accuracy::Rough, @@ -881,7 +1012,19 @@ impl Fuzz { screen += &format!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │\n"); } screen += &format!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────────────────────────────────────────┬────┘\n" + "├─ {blue}libafl{reset} {libafl_status:0}──────────────────────────────────────────────────────┬──┘\n" + ); + if !libafl_status.contains("disabled") { + screen += &format!("│ {gray}clients :{reset} {libafl_clients:17.17} │{gray}best coverage :{reset} {libafl_coverage:17.17} │\n"); + if libafl_crashes == "0" { + screen += &format!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {libafl_crashes:17.17} │\n"); + } else { + screen += &format!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {red}{libafl_crashes:17.17}{reset} │\n"); + } + screen += &format!("│ {gray}total execs :{reset} {libafl_total_execs:17.17} │ │\n"); + } + screen += &format!( + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────────────────────────────────────────┬─┘\n" ); if !hf_status.contains("disabled") { screen += &format!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │\n"); @@ -971,3 +1114,50 @@ pub fn extract_file_id(file: &Path) -> Option<(u32, String)> { let file_id = str_id.parse::().ok()?; Some((file_id, String::from(file_name))) } + +#[cfg(test)] +mod tests { + use std::{path::PathBuf, time::Instant}; + #[test] + fn job_repartition_works() { + let mut fuzz = crate::Fuzz { + target: String::new(), + corpus: PathBuf::new(), + initial_corpus: None, + ziggy_output: PathBuf::new(), + jobs: 0, + timeout: None, + minimize: false, + dictionary: None, + max_length: 0, + min_length: 0, + no_afl: false, + no_libafl: false, + no_honggfuzz: false, + start_time: Instant::now(), + afl_flags: vec![], + asan: false, + binary: None, + config: crate::FuzzingConfig::Generic, + coverage_interval: 15, + coverage_worker: false, + foreign_sync_dirs: vec![], + release: false, + }; + for i in 0..1024 { + fuzz.jobs = i; + fuzz.no_afl = i % 7 == 0; + fuzz.no_libafl = i % 11 == 0; + fuzz.no_honggfuzz = i % 5 == 0; + if i % 385 == 0 { + continue; + } + let (afl_jobs, libafl_jobs, honggfuzz_jobs) = fuzz.compute_job_repartition(); + assert_eq!( + afl_jobs + libafl_jobs + honggfuzz_jobs, + fuzz.jobs, + "Jobs total mismatch" + ); + } + } +} diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index c64fa4e..fec5742 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -83,11 +83,15 @@ pub enum Ziggy { #[derive(Args)] pub struct Build { - /// No AFL++ (Fuzz only with honggfuzz) + /// No AFL++ #[clap(long = "no-afl", action)] no_afl: bool, - /// No honggfuzz (Fuzz only with AFL++) + /// No LibAFL + #[clap(long = "no-libafl", action)] + no_libafl: bool, + + /// No honggfuzz #[clap(long = "no-honggfuzz", action)] no_honggfuzz: bool, @@ -148,11 +152,15 @@ pub struct Fuzz { #[clap(short = 'g', long = "minlength", default_value_t = 1)] min_length: u64, - /// No AFL++ (Fuzz only with honggfuzz) + /// No AFL++ #[clap(long = "no-afl", action)] no_afl: bool, - /// No honggfuzz (Fuzz only with AFL++) + /// No LibAFL + #[clap(long = "no-libafl", action)] + no_libafl: bool, + + /// No honggfuzz #[clap(long = "no-honggfuzz", action)] no_honggfuzz: bool, diff --git a/src/bin/cargo-ziggy/minimize.rs b/src/bin/cargo-ziggy/minimize.rs index 6f4595b..1b24b45 100644 --- a/src/bin/cargo-ziggy/minimize.rs +++ b/src/bin/cargo-ziggy/minimize.rs @@ -10,6 +10,7 @@ impl Minimize { pub fn minimize(&mut self) -> Result<(), anyhow::Error> { let build = Build { no_afl: self.engine == FuzzingEngines::Honggfuzz, + no_libafl: true, no_honggfuzz: self.engine == FuzzingEngines::AFLPlusPlus, release: false, asan: false, diff --git a/src/lib.rs b/src/lib.rs index 96cdd9f..0cf7711 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,11 +5,26 @@ pub use afl::fuzz as afl_fuzz; pub use fork; #[cfg(feature = "honggfuzz")] pub use honggfuzz::fuzz as honggfuzz_fuzz; +#[cfg(feature = "with_libafl")] +pub mod libafl_fuzzer; +#[cfg(feature = "with_libafl")] +pub use free_cpus; +#[cfg(feature = "with_libafl")] +pub use libafl; +#[cfg(feature = "with_libafl")] +pub use libafl_bolts; +#[cfg(feature = "with_libafl")] +pub use libafl_targets; // This is our inner harness handler function for the runner. // We open the input file and feed the data to the harness closure. #[doc(hidden)] -#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "coverage")))] +#[cfg(not(any( + feature = "afl", + feature = "honggfuzz", + feature = "with_libafl", + feature = "coverage" +)))] pub fn read_file_and_fuzz(mut closure: F, file: String) where F: FnMut(&[u8]), @@ -85,7 +100,7 @@ where // We read input files and directories from the command line and run the inner harness `fuzz`. #[doc(hidden)] #[macro_export] -#[cfg(not(any(feature = "afl", feature = "honggfuzz")))] +#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "with_libafl")))] macro_rules! read_args_and_fuzz { ( |$buf:ident| $body:block ) => { use std::{env, fs}; @@ -134,7 +149,7 @@ macro_rules! read_args_and_fuzz { /// # } /// ``` #[macro_export] -#[cfg(not(any(feature = "afl", feature = "honggfuzz")))] +#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "with_libafl")))] macro_rules! fuzz { (|$buf:ident| $body:block) => { $crate::read_args_and_fuzz!(|$buf| $body); @@ -174,3 +189,27 @@ macro_rules! fuzz { } }; } + +#[macro_export] +#[cfg(feature = "with_libafl")] +macro_rules! fuzz { + (|$buf:ident| $body:block) => { + $crate::libafl_fuzzer::libafl_fuzz(|$buf| $body); + }; + (|$buf:ident: &[u8]| $body:block) => { + $crate::libafl_fuzzer::libafl_fuzz(|$buf| $body); + }; + (|$buf:ident: $dty: ty| $body:block) => { + $crate::libafl_fuzzer::libafl_fuzz(|$buf| { + let $buf: $dty = { + let mut data = ::arbitrary::Unstructured::new($buf); + if let Ok(d) = ::arbitrary::Arbitrary::arbitrary(&mut data).map_err(|_| "") { + d + } else { + return; + } + }; + $body + }); + }; +} diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs new file mode 100644 index 0000000..3adadb0 --- /dev/null +++ b/src/libafl_fuzzer.rs @@ -0,0 +1,228 @@ +#[cfg(feature = "with_libafl")] +pub fn libafl_fuzz(function: fn(&[u8])) { + use libafl::{ + corpus::{Corpus, OnDiskCorpus}, + events::{launcher::Launcher, EventConfig, LlmpRestartingEventManager}, + executors::{inprocess::InProcessExecutor, ExitKind}, + feedback_or, feedback_or_fast, + feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + inputs::{BytesInput, HasTargetBytes}, + monitors::MultiMonitor, + mutators::{ + havoc_mutations, + scheduled::{tokens_mutations, StdScheduledMutator}, + token_mutations::Tokens, + }, + observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver}, + schedulers::{ + powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, + }, + stages::{ + calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage, + }, + state::{HasCorpus, /*HasMetadata,*/ StdState}, + Error, HasMetadata, + }; + use libafl_bolts::{ + core_affinity::{CoreId, Cores}, + current_nanos, + rands::StdRand, + shmem::{ShMemProvider, StdShMemProvider}, + tuples::{tuple_list, Merge}, + AsSlice, + }; + use libafl_targets::{autotokens, EDGES_MAP, MAX_EDGES_FOUND}; + use std::{env, net::TcpListener, path::PathBuf}; + + // Environement variables are passed from ziggy to LibAFL + let target_name = + env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); + let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS") + .expect("Could not find LIBAFL_SHARED_CORPUS env variable") + .into(); + let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES") + .expect("Could not find LIBAFL_CRASHES env variable") + .into(); + let num_of_cores = env::var("LIBAFL_CORES") + .expect("Could not find LIBAFL_CORES env variable") + .parse::() + .unwrap_or(1); + let dict = env::var("LIBAFL_DICT"); + + let broker_port = TcpListener::bind("127.0.0.1:0") + .map(|sock| sock.local_addr().unwrap().port()) + .expect("Could not bind broker port"); + + let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); + + // The Monitor trait define how the fuzzer stats are displayed to the user + let monitor = MultiMonitor::new(|s| println!("{s}")); + + let maybe_free_cores: Option> = + free_cpus::get().map(|cpus| cpus.into_iter().collect()).ok(); + let mut cores = match maybe_free_cores { + Some(free_cores) => Cores::from(free_cores), + None => Cores::all().expect("Could not get all cores"), + }; + cores + .trim(num_of_cores) + .expect("Not enough free cores for LibAFL"); + + let mut run_client = |state: Option<_>, + mut mgr: LlmpRestartingEventManager<_, _, _>, + core_id: CoreId| { + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = |input: &BytesInput| -> ExitKind { + let target = input.target_bytes(); + let buf = target.as_slice(); + // The closure that we want to fuzz + let inner_harness = function; + inner_harness(buf); + ExitKind::Ok + }; + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( + "edges", + EDGES_MAP.as_mut_ptr(), + MAX_EDGES_FOUND, + )) + .track_indices() + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + // Feedback to rate the interestingness of an input + // let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + let map_feedback = MaxMapFeedback::new(&edges_observer); + + let calibration = CalibrationStage::new(&map_feedback); + + let sync = SyncFromDiskStage::with_from_file( + vec![shared_corpus.clone()], + std::time::Duration::new(60, 0), + ); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + map_feedback, + // Time feedback, this one does not need a feedback state + // TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // create a State from scratch + let mut state = state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved + OnDiskCorpus::new(shared_corpus.clone()).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(&crashes_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .expect("Failed to create state") + }); + + // We derive the strategy from the client identifier (given by ziggy) + let strategy = match core_id.0 % 6 { + 0 => PowerSchedule::explore(), + 1 => PowerSchedule::exploit(), + 2 => PowerSchedule::fast(), + 3 => PowerSchedule::coe(), + 4 => PowerSchedule::lin(), + _ => PowerSchedule::quad(), + }; + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = IndexesLenTimeMinimizerScheduler::new( + &edges_observer, + StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(strategy)), + ); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create the executor for an in-process function with just one observer + let mut executor = InProcessExecutor::new( + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + ) + .expect("Failed to create the Executor"); + + let corpus_dirs = &[shared_corpus.clone()]; + + // In case the corpus is empty (on first run), reset + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) + .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // We load the dictionary + // Attempt to use tokens from libfuzzer dicts + if !state.has_metadata::() { + let mut toks = Tokens::default(); + if let Ok(dictionary) = dict.clone() { + let _ = toks.add_from_file(dictionary); + } + #[cfg(any(target_os = "linux", target_vendor = "apple"))] + { + toks += autotokens()?; + } + + if !toks.is_empty() { + state.add_metadata(toks); + } + } + + // Setup a basic mutator with a mutational stage + let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); + + let mut stages = tuple_list!(calibration, power, sync); + + fuzzer + .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) + .expect("Error in the fuzzing loop"); + + Ok(()) + }; + + match Launcher::builder() + .shmem_provider(shmem_provider) + .configuration(EventConfig::from_name(&target_name)) + .monitor(monitor) + .run_client(&mut run_client) + .cores(&cores) + .broker_port(broker_port) + // TODO Does this ever output anything? I have not seen it yet. + .stdout_file(Some("/tmp/libafl.log")) + .build() + .launch() + { + Ok(()) => (), + Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), + Err(e) => panic!("Error in fuzzer: {e}"), + }; +} diff --git a/tests/arbitrary_fuzz.rs b/tests/arbitrary_fuzz.rs index 9dc8152..da06e92 100644 --- a/tests/arbitrary_fuzz.rs +++ b/tests/arbitrary_fuzz.rs @@ -56,11 +56,11 @@ fn integration() { assert!(build_status.success(), "`cargo ziggy build` failed"); - // cargo ziggy fuzz -j 2 -t 5 -o temp_dir + // cargo ziggy fuzz -j 3 -t 5 -o temp_dir let fuzzer = process::Command::new(cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) @@ -72,6 +72,16 @@ fn integration() { thread::sleep(Duration::from_secs(10)); kill_subprocesses_recursively(&format!("{}", fuzzer.id())); + process::Command::new("cat") + .arg( + temp_dir_path + .join("arbitrary-fuzz") + .join("logs") + .join("afl.log"), + ) + .spawn() + .unwrap(); + assert!(temp_dir_path .join("arbitrary-fuzz") .join("afl") diff --git a/tests/url_fuzz.rs b/tests/url_fuzz.rs index b2ee361..8104710 100644 --- a/tests/url_fuzz.rs +++ b/tests/url_fuzz.rs @@ -56,11 +56,11 @@ fn integration() { assert!(build_status.success(), "`cargo ziggy build` failed"); - // cargo ziggy fuzz -j 2 -t 5 + // cargo ziggy fuzz -j 3 -t 5 let fuzzer = process::Command::new(&cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) @@ -86,11 +86,11 @@ fn integration() { .is_dir()); // We resume fuzzing - // cargo ziggy fuzz -j 2 -t 5 + // cargo ziggy fuzz -j 3 -t 5 let fuzzer = process::Command::new(&cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display()))