From d022cf4de9a6e4c93ae2b5d14461f708f42fe330 Mon Sep 17 00:00:00 2001 From: Juan-M-V <102986292+Juan-M-V@users.noreply.github.com> Date: Tue, 1 Aug 2023 19:02:01 -0300 Subject: [PATCH] Stabilize fuzz program & json (#1344) * Generate program with * Simplify fuzz_json * Fuzz config * Test more args * Declare STEPS_LIMIT; derive Clone * Implement location arbitrary by hand * Implement arbitrary by hand * Use raw bytes for fuzz_json * Specify arbitrary for CairoConfig * Use and for json programs * Add words to dict * Run carg fix * Remove unused crates * Remove unused crates * Remove comments * Remove unused crates * Improve data generation * Typo * Allow for Imm errors on final instructions --------- Co-authored-by: Juanma Co-authored-by: Pedro Fontana Co-authored-by: Mario Rugiero --- fuzzer/Cargo.lock | 514 ++-------------------------- fuzzer/Cargo.toml | 14 - fuzzer/json.dict | 77 ++++- fuzzer/src/fuzz_json.rs | 174 +--------- fuzzer/src/fuzz_program.rs | 6 +- vm/src/cairo_run.rs | 21 +- vm/src/serde/deserialize_program.rs | 46 ++- vm/src/types/program.rs | 37 +- 8 files changed, 230 insertions(+), 659 deletions(-) diff --git a/fuzzer/Cargo.lock b/fuzzer/Cargo.lock index a5b6aca576..046bb7e15a 100644 --- a/fuzzer/Cargo.lock +++ b/fuzzer/Cargo.lock @@ -26,15 +26,15 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "arbitrary" @@ -109,12 +109,6 @@ dependencies = [ "rand", ] -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - [[package]] name = "autocfg" version = "1.1.0" @@ -126,45 +120,9 @@ name = "bincode" version = "2.0.0-rc.3" source = "git+https://github.com/bincode-org/bincode.git?tag=v2.0.0-rc.3#aada4bb4cb457677a4b8e47572ae7ca8dd44927c" dependencies = [ - "bincode_derive", "serde", ] -[[package]] -name = "bincode_derive" -version = "2.0.0-rc.3" -source = "git+https://github.com/bincode-org/bincode.git?tag=v2.0.0-rc.3#aada4bb4cb457677a4b8e47572ae7ca8dd44927c" -dependencies = [ - "virtue", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" - [[package]] name = "bitvec" version = "1.0.1" @@ -192,15 +150,9 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "cairo-felt" -version = "0.8.2" +version = "0.8.5" dependencies = [ "arbitrary", "lazy_static", @@ -212,7 +164,7 @@ dependencies = [ [[package]] name = "cairo-vm" -version = "0.8.2" +version = "0.8.5" dependencies = [ "anyhow", "arbitrary", @@ -303,7 +255,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -319,42 +271,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "funty" @@ -362,117 +281,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.23", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "fuzzer" version = "0.1.0" dependencies = [ "arbitrary", - "assert_matches", - "bincode", "cairo-felt", "cairo-vm", "honggfuzz", "libfuzzer-sys", - "mimalloc", - "nom", - "proptest", - "rstest", - "thiserror", ] [[package]] @@ -556,9 +373,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" @@ -613,12 +430,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "libm" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" - [[package]] name = "libmimalloc-sys" version = "0.1.33" @@ -629,12 +440,6 @@ dependencies = [ "libc", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" - [[package]] name = "log" version = "0.4.19" @@ -743,12 +548,11 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -759,21 +563,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "paste" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" - -[[package]] -name = "pin-project-lite" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "ppv-lite86" @@ -783,44 +575,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] -[[package]] -name = "proptest" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" -dependencies = [ - "bit-set", - "bitflags 1.3.2", - "byteorder", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -861,30 +627,6 @@ 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 = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "rfc6979" version = "0.4.0" @@ -895,32 +637,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "rstest" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" -dependencies = [ - "futures", - "futures-timer", - "rstest_macros", - "rustc_version", -] - -[[package]] -name = "rstest_macros" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", - "unicode-ident", -] - [[package]] name = "rustc_version" version = "0.4.0" @@ -930,68 +646,43 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" -dependencies = [ - "bitflags 2.3.3", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.167" +version = "1.0.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -1019,15 +710,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - [[package]] name = "spin" version = "0.5.2" @@ -1062,7 +744,7 @@ checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ "starknet-curve 0.4.0", "starknet-ff", - "syn 2.0.23", + "syn 2.0.28", ] [[package]] @@ -1114,9 +796,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -1129,39 +811,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "tempfile" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys", -] - -[[package]] -name = "thiserror" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.23", -] - [[package]] name = "thiserror-impl-no-std" version = "2.0.2" @@ -1188,17 +837,11 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "version_check" @@ -1206,21 +849,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "virtue" -version = "0.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" - -[[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" @@ -1248,7 +876,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -1270,7 +898,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1281,72 +909,6 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - [[package]] name = "wyz" version = "0.5.1" @@ -1373,5 +935,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.28", ] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 7bf52c4251..5f9b815329 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -15,22 +15,8 @@ members = ["."] arbitrary = { version = "1.3.0", features = ["derive"] } honggfuzz = "0.5.55" libfuzzer-sys = "0.4" -bincode = { version = "2.0.0-rc.3", tag = "v2.0.0-rc.3", git = "https://github.com/bincode-org/bincode.git" } cairo-vm = { path = "../vm", features = ["arbitrary"] } -mimalloc = { version = "0.1.29", default-features = false, optional = true } -nom = "7" -thiserror = { version = "1.0.32" } cairo-felt = { path = "../felt", features = ["arbitrary"] } -proptest = "1.2.0" - -[dev-dependencies] -assert_matches = "1.5.0" -rstest = "0.17.0" - - -[features] -default = ["with_mimalloc"] -with_mimalloc = ["cairo-vm/with_mimalloc", "mimalloc"] [[bin]] name = "fuzz_json" diff --git a/fuzzer/json.dict b/fuzzer/json.dict index d2e5252576..9c68aa0339 100644 --- a/fuzzer/json.dict +++ b/fuzzer/json.dict @@ -8,6 +8,36 @@ # "0" +"\"0\"" +"\"1\"" +"\"2\"" +"\"3\"" +"\"4\"" +"\"5\"" +"\"6\"" +"\"7\"" +"\"8\"" +"\"9\"" +"\"0" +"\"1" +"\"2" +"\"3" +"\"4" +"\"5" +"\"6" +"\"7" +"\"8" +"\"9" +"0\"" +"1\"" +"2\"" +"3\"" +"4\"" +"5\"" +"6\"" +"7\"" +"8\"" +"9\"" ",0" ":0" "0:" @@ -43,6 +73,7 @@ "\\t" "\\u0000" "\\x00" +"\\x0" "\\0" "\\uD800\\uDC00" "\\uDBFF\\uDFFF" @@ -58,4 +89,48 @@ "@id" "," -":" \ No newline at end of file +":" + +# Common cairo words +"\"attributes\"" +"\"builtins\"" +"\"compiler_version\": \"0.11.0\"," +"\"data\"" +"\"debug_info\"" +"\"file_contents\"" +"\"instruction_locations\"" +"\"accessible_scopes\"" +"\"__main__\"" +"\"__main__.main\"" +"\"flow_tracking_data\"" +"\"ap_tracking\"" +"\"group\"" +"\"offset\"" +"\"reference_ids\"" +"\"hints\"" +"\"inst\"" +"\"end_col\"" +"\"end_line\"" +"\"start_col\"" +"\"start_line\"" +"\"input_file\"" +"\"filename\"" +"\"identifiers\"" +"\"decorators\"" +"\"pc\"" +"\"type\"" +"\"value\"" +"\"full_name\"" +"\"members\"" +"\"first_element\"" +"\"second_element\"" +"\"cairo_type\"" +"\"size\"" +"Return\"" +"SIZEOF_LOCALS\"" +"\"main_scope\"" +"\"prime\"" +"\"reference_manager\"" +"\"references\"" +"cast" + diff --git a/fuzzer/src/fuzz_json.rs b/fuzzer/src/fuzz_json.rs index 00366cd5d1..021e92cdd8 100644 --- a/fuzzer/src/fuzz_json.rs +++ b/fuzzer/src/fuzz_json.rs @@ -1,165 +1,23 @@ -use arbitrary::Arbitrary; -use bincode::enc::write::Writer; -use cairo_vm::cairo_run::{self, EncodeTraceError}; -use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; -use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; -use cairo_vm::vm::errors::trace_errors::TraceError; -use cairo_vm::vm::errors::vm_errors::VirtualMachineError; +use cairo_vm::{ + cairo_run::{cairo_run, CairoRunConfig}, + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, +}; use honggfuzz::fuzz; -use std::fmt; -use std::io::{self, Write}; -use std::path::PathBuf; -use thiserror::Error; - -#[cfg(feature = "with_mimalloc")] -use mimalloc::MiMalloc; - -#[cfg(feature = "with_mimalloc")] -#[global_allocator] -static ALLOC: MiMalloc = MiMalloc; - -#[derive(Debug, Arbitrary)] -struct Args { - program_content: Vec, - trace_file: Option, - print_output: bool, - entrypoint: String, - memory_file: Option, - layout: Layout, - proof_mode: bool, - secure_run: Option, -} - -#[derive(Debug, Arbitrary)] -enum Layout { - Plain, - Small, - Dex, - Starknet, - StarknetWithKeccak, - RecursiveLargeOutput, - AllCairo, - AllSolidity, - Dynamic, -} - -impl fmt::Display for Layout { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Layout::Plain => write!(f, "plain"), - Layout::Small => write!(f, "small"), - Layout::Dex => write!(f, "dex"), - Layout::Starknet => write!(f, "starknet"), - Layout::StarknetWithKeccak => write!(f, "starknet_with_keccak"), - Layout::RecursiveLargeOutput => write!(f, "recursive_large_output"), - Layout::AllCairo => write!(f, "all_cairo"), - Layout::AllSolidity => write!(f, "all_solidity"), - Layout::Dynamic => write!(f, "dynamic"), - } - } -} - -#[derive(Debug, Error)] -enum Error { - #[error("Failed to interact with the file system")] - IO(#[from] std::io::Error), - #[error("The cairo program execution failed")] - Runner(#[from] CairoRunError), - #[error(transparent)] - EncodeTrace(#[from] EncodeTraceError), - #[error(transparent)] - VirtualMachine(#[from] VirtualMachineError), - #[error(transparent)] - Trace(#[from] TraceError), -} - -struct FileWriter { - buf_writer: io::BufWriter, - bytes_written: usize, -} - -impl Writer for FileWriter { - fn write(&mut self, bytes: &[u8]) -> Result<(), bincode::error::EncodeError> { - self.buf_writer - .write_all(bytes) - .map_err(|e| bincode::error::EncodeError::Io { - inner: e, - index: self.bytes_written, - })?; - - self.bytes_written += bytes.len(); - - Ok(()) - } -} - -impl FileWriter { - fn new(buf_writer: io::BufWriter) -> Self { - Self { - buf_writer, - bytes_written: 0, - } - } - - fn flush(&mut self) -> io::Result<()> { - self.buf_writer.flush() - } -} - -fn run(args: Args) -> Result<(), Error> { - let trace_enabled = args.trace_file.is_some(); - let mut hint_executor = BuiltinHintProcessor::new_empty(); - let cairo_run_config = cairo_run::CairoRunConfig { - entrypoint: &args.entrypoint, - trace_enabled, - relocate_mem: args.memory_file.is_some(), - layout: &args.layout.to_string(), - proof_mode: args.proof_mode, - secure_run: args.secure_run, - }; - - let (cairo_runner, mut vm) = - match cairo_run::cairo_run(&args.program_content, &cairo_run_config, &mut hint_executor) { - Ok(runner) => runner, - Err(error) => { - eprintln!("{error}"); - return Err(Error::Runner(error)); - } - }; - - if args.print_output { - let mut output_buffer = "Program Output:\n".to_string(); - vm.write_output(&mut output_buffer)?; - print!("{output_buffer}"); - } - - if let Some(trace_path) = args.trace_file { - let relocated_trace = vm.get_relocated_trace()?; - - let trace_file = std::fs::File::create(trace_path)?; - let mut trace_writer = - FileWriter::new(io::BufWriter::with_capacity(3 * 1024 * 1024, trace_file)); - - cairo_run::write_encoded_trace(relocated_trace, &mut trace_writer)?; - trace_writer.flush()?; - } - - if let Some(memory_path) = args.memory_file { - let memory_file = std::fs::File::create(memory_path)?; - let mut memory_writer = - FileWriter::new(io::BufWriter::with_capacity(5 * 1024 * 1024, memory_file)); - - cairo_run::write_encoded_memory(&cairo_runner.relocated_memory, &mut memory_writer)?; - memory_writer.flush()?; - } - - Ok(()) -} fn main() { loop { - fuzz!(|args: Args| { - let _ = run(args); + fuzz!(|data: (CairoRunConfig, &[u8])| { + let (cairo_run_config, program_json) = data; + let _ = cairo_run( + program_json, + &CairoRunConfig::default(), + &mut BuiltinHintProcessor::new_empty(), + ); + let _ = cairo_run( + program_json, + &cairo_run_config, + &mut BuiltinHintProcessor::new_empty(), + ); }); } } diff --git a/fuzzer/src/fuzz_program.rs b/fuzzer/src/fuzz_program.rs index 0358ded6ee..8f3fd19445 100644 --- a/fuzzer/src/fuzz_program.rs +++ b/fuzzer/src/fuzz_program.rs @@ -1,5 +1,5 @@ use cairo_vm::{ - cairo_run::{cairo_run_parsed_program, CairoRunConfig}, + cairo_run::{cairo_run_fuzzed_program, CairoRunConfig}, hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, types::program::Program, }; @@ -10,13 +10,13 @@ fn main() { loop { fuzz!(|data: (CairoRunConfig, Program)| { let (cairo_config, program) = data; - let _ = cairo_run_parsed_program( + let _ = cairo_run_fuzzed_program( program.clone(), &CairoRunConfig::default(), &mut BuiltinHintProcessor::new_empty(), STEPS_LIMIT, ); - let _ = cairo_run_parsed_program( + let _ = cairo_run_fuzzed_program( program, &cairo_config, &mut BuiltinHintProcessor::new_empty(), diff --git a/vm/src/cairo_run.rs b/vm/src/cairo_run.rs index 6a1435a36c..57c0ef5ff2 100644 --- a/vm/src/cairo_run.rs +++ b/vm/src/cairo_run.rs @@ -15,18 +15,35 @@ use felt::Felt252; use thiserror_no_std::Error; #[cfg(feature = "arbitrary")] -use arbitrary::Arbitrary; +use arbitrary::{self, Arbitrary, Unstructured}; #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct CairoRunConfig<'a> { pub entrypoint: &'a str, pub trace_enabled: bool, pub relocate_mem: bool, + #[cfg_attr(feature = "arbitrary", arbitrary(with = arbitrary_layout))] pub layout: &'a str, pub proof_mode: bool, pub secure_run: Option, } +#[cfg(feature = "arbitrary")] +fn arbitrary_layout<'a>(u: &mut Unstructured) -> arbitrary::Result<&'a str> { + let layouts = [ + "plain", + "small", + "dex", + "starknet", + "starknet_with_keccak", + "recursive_large_output", + "all_cairo", + "all_solidity", + "dynamic", + ]; + Ok(u.choose(&layouts)?) +} + impl<'a> Default for CairoRunConfig<'a> { fn default() -> Self { CairoRunConfig { @@ -80,7 +97,7 @@ pub fn cairo_run( } #[cfg(feature = "arbitrary")] -pub fn cairo_run_parsed_program( +pub fn cairo_run_fuzzed_program( program: Program, cairo_run_config: &CairoRunConfig, hint_executor: &mut dyn HintProcessor, diff --git a/vm/src/serde/deserialize_program.rs b/vm/src/serde/deserialize_program.rs index 14410acf7b..e892cf45dc 100644 --- a/vm/src/serde/deserialize_program.rs +++ b/vm/src/serde/deserialize_program.rs @@ -35,7 +35,7 @@ use serde::{de, de::MapAccess, de::SeqAccess, Deserialize, Deserializer, Seriali use serde_json::Number; #[cfg(all(feature = "arbitrary", feature = "std"))] -use arbitrary::Arbitrary; +use arbitrary::{self, Arbitrary, Unstructured}; // This enum is used to deserialize program builtins into &str and catch non-valid names #[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] @@ -69,6 +69,7 @@ impl BuiltinName { } } +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary, Clone))] #[derive(Deserialize, Debug)] pub struct ProgramJson { pub prime: String, @@ -152,7 +153,6 @@ pub struct Attribute { pub flow_tracking_data: Option, } -#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct Location { pub end_line: u32, @@ -163,6 +163,44 @@ pub struct Location { pub start_col: u32, } +#[cfg(all(feature = "arbitrary", feature = "std"))] +impl<'a> Arbitrary<'a> for Location { + fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { + let mut locations = Vec::new(); + + u.arbitrary_loop(Some(0), Some(512), |u| { + locations.push(Location { + end_line: u32::arbitrary(u)?, + end_col: u32::arbitrary(u)?, + input_file: InputFile::arbitrary(u)?, + parent_location: None, + start_line: u32::arbitrary(u)?, + start_col: u32::arbitrary(u)?, + }); + Ok(std::ops::ControlFlow::Continue(())) + })?; + + let mut iter_location = locations.pop().unwrap_or_else(|| Location { + end_line: 0, + end_col: 0, + input_file: InputFile { + filename: "".to_string(), + }, + parent_location: None, + start_line: 0, + start_col: 0, + }); + + while let Some(mut location) = locations.pop() { + location.parent_location = Some((Box::new(iter_location), String::arbitrary(u)?)); + iter_location = location; + } + + Ok(iter_location) + } +} + +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary, Clone))] #[derive(Deserialize, Debug, PartialEq, Eq)] pub struct DebugInfo { instruction_locations: HashMap, @@ -224,11 +262,13 @@ fn deserialize_scientific_notation(n: Number) -> Option { } } +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)] pub struct ReferenceManager { pub references: Vec, } +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Reference { pub ap_tracking_data: ApTracking, @@ -246,8 +286,8 @@ pub enum OffsetValue { Reference(Register, i32, bool), } +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] - pub struct ValueAddress { pub offset1: OffsetValue, pub offset2: OffsetValue, diff --git a/vm/src/types/program.rs b/vm/src/types/program.rs index e24f69afe7..aefd91c7b0 100644 --- a/vm/src/types/program.rs +++ b/vm/src/types/program.rs @@ -25,7 +25,7 @@ use felt::{Felt252, PRIME_STR}; use std::path::Path; #[cfg(all(feature = "arbitrary", feature = "std"))] -use arbitrary::Arbitrary; +use arbitrary::{Arbitrary, Unstructured}; // NOTE: `Program` has been split in two containing some data that will be deep-copied // and some that will be allocated on the heap inside an `Arc<_>`. @@ -48,7 +48,6 @@ use arbitrary::Arbitrary; // exceptional circumstances, such as when reconstructing a backtrace on execution // failures. // Fields in `Program` (other than `SharedProgramData` itself) are used by the main logic. -#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] #[derive(Clone, Default, Debug, PartialEq, Eq)] pub(crate) struct SharedProgramData { pub(crate) data: Vec, @@ -65,6 +64,40 @@ pub(crate) struct SharedProgramData { pub(crate) reference_manager: Vec, } +#[cfg(all(feature = "arbitrary", feature = "std"))] +impl<'a> Arbitrary<'a> for SharedProgramData { + /// Create an arbitary [`SharedProgramData`] using `flatten_hints` to generate `hints` and + /// `hints_ranges` + fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { + let mut data = Vec::new(); + let len = usize::arbitrary(u)?; + for i in 0..len { + let instruction = u64::arbitrary(u)?; + data.push(MaybeRelocatable::from(Felt252::from(instruction))); + // Check if the Imm flag is on and add an immediate value if it is + if instruction & 0x0004000000000000 != 0 && i < len - 1 { + data.push(MaybeRelocatable::from(Felt252::arbitrary(u)?)); + } + } + + let raw_hints = BTreeMap::>::arbitrary(u)?; + let (hints, hints_ranges) = Program::flatten_hints(&raw_hints, data.len()) + .map_err(|_| arbitrary::Error::IncorrectFormat)?; + Ok(SharedProgramData { + data, + hints, + hints_ranges, + main: Option::::arbitrary(u)?, + start: Option::::arbitrary(u)?, + end: Option::::arbitrary(u)?, + error_message_attributes: Vec::::arbitrary(u)?, + instruction_locations: Option::>::arbitrary(u)?, + identifiers: HashMap::::arbitrary(u)?, + reference_manager: Vec::::arbitrary(u)?, + }) + } +} + /// Represents a range of hints corresponding to a PC. /// /// Is [`None`] if the range is empty, and it is [`Some`] tuple `(start, length)` otherwise.