diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 262f26579..8d13d2c17 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -668,10 +668,10 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]: protobuf_blobs = env.Command( target=[ - f'rust/{RUST_TARGET}/proto_enums.data', - f'rust/{RUST_TARGET}/proto_msgs.data', - f'rust/{RUST_TARGET}/proto_names.data', - f'rust/{RUST_TARGET}/proto_wire.data', + f'rust/proto_enums.data', + f'rust/proto_msgs.data', + f'rust/proto_names.data', + f'rust/proto_wire.data', ], source=PROTO_SOURCES, action='$PB2PY --bitcoin-only=%s --blob-outdir ${TARGET.dir} $SOURCES --qstr-defs build/firmware/genhdr/qstrdefs.generated.h' % BITCOIN_ONLY, diff --git a/core/embed/rust/Cargo.toml b/core/embed/rust/Cargo.toml index 07d961128..659cad4aa 100644 --- a/core/embed/rust/Cargo.toml +++ b/core/embed/rust/Cargo.toml @@ -25,8 +25,13 @@ opt-level = "z" lto = true codegen-units = 1 -[dependencies] -cty = "0.2.1" +[profile.test] +split-debuginfo = "unpacked" + +# Runtime dependencies + +[dependencies.cty] +version = "0.2.1" [dependencies.heapless] version = "0.7.3" @@ -36,11 +41,15 @@ default_features = false version = "0.2.4" default_features = false +# Build dependencies + [build-dependencies.bindgen] version = "0.59.1" default_features = false features = ["runtime"] +# Build dependencies used for linking the test binary + [build-dependencies.cc] optional = true version = "1.0.69" diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 8f21e222c..6b261f6e2 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -190,8 +190,12 @@ fn link_core_objects() { let crate_path = env::var("CARGO_MANIFEST_DIR").unwrap(); let build_path = format!("{}/../../build/unix", crate_path); + // List of object filenames to ignore in the `embed` directory. let embed_blocklist = [OsStr::new("main_main.o")]; + // Collect all objects that the `core` library uses, and link it in. We have to + // make sure to avoid the object with the `_main` symbol, so we don't get any + // duplicates. let mut cc = cc::Build::new(); for obj in glob::glob(&format!("{}/embed/**/*.o", build_path)).unwrap() { let obj = obj.unwrap(); @@ -204,6 +208,8 @@ fn link_core_objects() { for obj in glob::glob(&format!("{}/vendor/**/*.o", build_path)).unwrap() { cc.object(obj.unwrap()); } + + // Compile all the objects into a static library and link it in automatically. cc.compile("core_lib"); println!("cargo:rustc-link-lib=SDL2"); diff --git a/core/embed/rust/fuzz/.gitignore b/core/embed/rust/fuzz/.gitignore new file mode 100644 index 000000000..a0925114d --- /dev/null +++ b/core/embed/rust/fuzz/.gitignore @@ -0,0 +1,3 @@ +target +corpus +artifacts diff --git a/core/embed/rust/fuzz/Cargo.lock b/core/embed/rust/fuzz/Cargo.lock new file mode 100644 index 000000000..e9bb29b3f --- /dev/null +++ b/core/embed/rust/fuzz/Cargo.lock @@ -0,0 +1,392 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arbitrary" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" + +[[package]] +name = "atomic-polyfill" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" +dependencies = [ + "cortex-m", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bindgen" +version = "0.58.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", +] + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" + +[[package]] +name = "cexpr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cortex-m" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" +dependencies = [ + "bare-metal", + "bitfield", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "cstr_core" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2807c5e92588b6bf1c8c0354af2a4f079d0586c683df322aea719d5dc9b8d5bb" +dependencies = [ + "cty", + "memchr", +] + +[[package]] +name = "cty" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7313c0d620d0cb4dbd9d019e461a4beb501071ff46ec0ab933efb4daa76d73e3" + +[[package]] +name = "embedded-hal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ee8a997d259962217f40279f34201fdf06e669bafa69d7c1f4c7ff1893b5f6" +dependencies = [ + "atomic-polyfill", + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[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.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "shlex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "trezor_lib" +version = "0.1.0" +dependencies = [ + "bindgen", + "cc", + "cstr_core", + "cty", + "glob", + "heapless", +] + +[[package]] +name = "trezor_lib-fuzz" +version = "0.0.0" +dependencies = [ + "libfuzzer-sys", + "trezor_lib", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" +dependencies = [ + "vcell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/core/embed/rust/fuzz/Cargo.toml b/core/embed/rust/fuzz/Cargo.toml new file mode 100644 index 000000000..a5c3e3e83 --- /dev/null +++ b/core/embed/rust/fuzz/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "trezor_lib-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.trezor_lib] +path = ".." +features = ["test"] + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "protobuf" +path = "fuzz_targets/protobuf.rs" +test = false +doc = false diff --git a/core/embed/rust/fuzz/fuzz_targets/protobuf.rs b/core/embed/rust/fuzz/fuzz_targets/protobuf.rs new file mode 100644 index 000000000..43a88c14f --- /dev/null +++ b/core/embed/rust/fuzz/fuzz_targets/protobuf.rs @@ -0,0 +1,7 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + // fuzzed code goes here +}); diff --git a/core/embed/rust/src/lib.rs b/core/embed/rust/src/lib.rs index 9707427af..2ad40b7b8 100644 --- a/core/embed/rust/src/lib.rs +++ b/core/embed/rust/src/lib.rs @@ -16,12 +16,12 @@ mod trezorhal; mod ui; mod util; -#[cfg(not(test))] +#[cfg(not(feature = "test"))] use core::panic::PanicInfo; -#[cfg(not(test))] +#[cfg(not(feature = "test"))] use cstr_core::CStr; -#[cfg(not(test))] +#[cfg(not(feature = "test"))] #[panic_handler] fn panic(_info: &PanicInfo) -> ! { // Although it would be ideal to use the original error message, ignoring it diff --git a/core/embed/rust/src/protobuf/defs.rs b/core/embed/rust/src/protobuf/defs.rs index 2179cec3f..f48e4fd74 100644 --- a/core/embed/rust/src/protobuf/defs.rs +++ b/core/embed/rust/src/protobuf/defs.rs @@ -109,10 +109,31 @@ struct NameDef { msg_offset: u16, } -static ENUM_DEFS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/../../../../proto_enums.data")); -static MSG_DEFS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/../../../../proto_msgs.data")); -static NAME_DEFS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/../../../../proto_names.data")); -static WIRE_DEFS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/../../../../proto_wire.data")); +#[cfg(target_arch = "arm")] +macro_rules! proto_def_path { + ($filename:expr) => { + concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../build/firmware/rust/", + $filename + ) + }; +} +#[cfg(not(target_arch = "arm"))] +macro_rules! proto_def_path { + ($filename:expr) => { + concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../build/unix/rust/", + $filename + ) + }; +} + +static ENUM_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_enums.data")); +static MSG_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_msgs.data")); +static NAME_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_names.data")); +static WIRE_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_wire.data")); pub fn find_name_by_msg_offset(msg_offset: u16) -> Result { let name_defs: &[NameDef] = unsafe {