diff --git a/flake.nix b/flake.nix index b8d9094..718cd24 100644 --- a/flake.nix +++ b/flake.nix @@ -186,6 +186,25 @@ rustfmt ]; }; + # a devshell to hunt unsafe `unsafe` in the code + devShells.miri = pkgs.mkShell { + # inputsFrom = [ self.packages.${system}.rosenpass ]; + nativeBuildInputs = with pkgs; [ + ((rust-bin.selectLatestNightlyWith (toolchain: toolchain.default)).override { + extensions = [ + "rust-analysis" + "rust-src" + "miri-preview" + ]; + }) + pkgs.cmake + pkgs.rustPlatform.bindgenHook + ]; + # Run this to find unsafe `unsafe`: + # MIRIFLAGS="-Zmiri-disable-isolation" cargo miri test --no-fail-fast --lib --bins --tests + # + # - Some test failure is expected. + }; checks = import ./tests/integration/integration-checks.nix { diff --git a/rosenpass/src/protocol/test.rs b/rosenpass/src/protocol/test.rs index 8bd17f9..b5f5882 100644 --- a/rosenpass/src/protocol/test.rs +++ b/rosenpass/src/protocol/test.rs @@ -55,12 +55,14 @@ fn setup_logging() { #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn handles_incorrect_size_messages_v02() { handles_incorrect_size_messages(ProtocolVersion::V02) } #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn handles_incorrect_size_messages_v03() { handles_incorrect_size_messages(ProtocolVersion::V03) } @@ -163,12 +165,14 @@ fn make_server_pair(protocol_version: ProtocolVersion) -> Result<(CryptoServer, #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn test_regular_exchange_v02() { test_regular_exchange(ProtocolVersion::V02) } #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn test_regular_exchange_v03() { test_regular_exchange(ProtocolVersion::V03) } @@ -234,12 +238,14 @@ fn test_regular_exchange(protocol_version: ProtocolVersion) { #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn test_regular_init_conf_retransmit_v02() { test_regular_init_conf_retransmit(ProtocolVersion::V02) } #[test] #[serial] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn test_regular_init_conf_retransmit_v03() { test_regular_init_conf_retransmit(ProtocolVersion::V03) } @@ -507,11 +513,13 @@ fn cookie_reply_mechanism_initiator_bails_on_message_under_load(protocol_version } #[test] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn init_conf_retransmission_v02() -> Result<()> { init_conf_retransmission(ProtocolVersion::V02) } #[test] +#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn init_conf_retransmission_v03() -> Result<()> { init_conf_retransmission(ProtocolVersion::V03) } diff --git a/rosenpass/tests/app_server_example.rs b/rosenpass/tests/app_server_example.rs index 4b8169a..4835180 100644 --- a/rosenpass/tests/app_server_example.rs +++ b/rosenpass/tests/app_server_example.rs @@ -10,11 +10,13 @@ use rosenpass::protocol::basic_types::{SPk, SSk, SymKey}; use rosenpass::{config::ProtocolVersion, protocol::osk_domain_separator::OskDomainSeparator}; #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn key_exchange_with_app_server_v02() -> anyhow::Result<()> { key_exchange_with_app_server(ProtocolVersion::V02) } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn key_exchange_with_app_server_v03() -> anyhow::Result<()> { key_exchange_with_app_server(ProtocolVersion::V03) } diff --git a/rosenpass/tests/config_Rosenpass_validate.rs b/rosenpass/tests/config_Rosenpass_validate.rs index 48e73fe..a964c8b 100644 --- a/rosenpass/tests/config_Rosenpass_validate.rs +++ b/rosenpass/tests/config_Rosenpass_validate.rs @@ -3,6 +3,7 @@ use std::fs; use rosenpass::{cli::generate_and_save_keypair, config::Rosenpass}; #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn example_config_rosenpass_validate() -> anyhow::Result<()> { rosenpass_secret_memory::policy::secret_policy_use_only_malloc_secrets(); diff --git a/rosenpass/tests/integration_test.rs b/rosenpass/tests/integration_test.rs index 6d16ac9..494a711 100644 --- a/rosenpass/tests/integration_test.rs +++ b/rosenpass/tests/integration_test.rs @@ -182,6 +182,7 @@ fn check_example_config() { // check that we can exchange keys #[test] #[serial] +#[cfg_attr(miri, ignore)] // TODO investigate why this panicks in miri fn check_exchange_under_normal() { setup_tests(); setup_logging(); @@ -255,6 +256,7 @@ fn check_exchange_under_normal() { // This test creates a responder (server) with the feature flag "integration_test_always_under_load" to always be under load condition for the test. #[test] #[serial] +#[cfg_attr(miri, ignore)] // integer-to-pointer cast fn check_exchange_under_dos() { setup_tests(); setup_logging(); diff --git a/rosenpass/tests/poll_example.rs b/rosenpass/tests/poll_example.rs index 10cc875..39c3188 100644 --- a/rosenpass/tests/poll_example.rs +++ b/rosenpass/tests/poll_example.rs @@ -19,16 +19,19 @@ use rosenpass::protocol::{CryptoServer, HostIdentification, PeerPtr, PollResult, // rosenpass::protocol::testutils; #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_with_poll_v02() -> anyhow::Result<()> { test_successful_exchange_with_poll(ProtocolVersion::V02, OskDomainSeparator::default()) } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_with_poll_v03() -> anyhow::Result<()> { test_successful_exchange_with_poll(ProtocolVersion::V03, OskDomainSeparator::default()) } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_with_poll_v02_custom_domain_separator() -> anyhow::Result<()> { test_successful_exchange_with_poll( ProtocolVersion::V02, @@ -37,6 +40,7 @@ fn test_successful_exchange_with_poll_v02_custom_domain_separator() -> anyhow::R } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_with_poll_v03_custom_domain_separator() -> anyhow::Result<()> { test_successful_exchange_with_poll( ProtocolVersion::V03, @@ -108,11 +112,13 @@ fn test_successful_exchange_with_poll( } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_under_packet_loss_v02() -> anyhow::Result<()> { test_successful_exchange_under_packet_loss(ProtocolVersion::V02) } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_successful_exchange_under_packet_loss_v03() -> anyhow::Result<()> { test_successful_exchange_under_packet_loss(ProtocolVersion::V03) } @@ -202,6 +208,7 @@ fn test_successful_exchange_under_packet_loss( } #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: can't call foreign function `mprotect` on OS `linux` fn test_osk_label_mismatch() -> anyhow::Result<()> { // Set security policy for storing secrets; choose the one that is faster for testing rosenpass_secret_memory::policy::secret_policy_use_only_malloc_secrets(); diff --git a/rosenpass/tests/test_vector_crypto_server.rs b/rosenpass/tests/test_vector_crypto_server.rs index 31313b8..791ab7e 100644 --- a/rosenpass/tests/test_vector_crypto_server.rs +++ b/rosenpass/tests/test_vector_crypto_server.rs @@ -82,6 +82,7 @@ struct CryptoServerTestValues { } #[test_vec_case(format = "toml")] +// TODO find a way to make miri ignore these test cases fn crypto_server_test_vector_1() -> anyhow::Result<()> { type TV = TestVectorActive; let test_values: TestCaseValues = TV::initialize_values(); diff --git a/rp/src/key.rs b/rp/src/key.rs index f6089e7..a7ac749 100644 --- a/rp/src/key.rs +++ b/rp/src/key.rs @@ -128,6 +128,7 @@ mod tests { use crate::key::{genkey, pubkey, WG_B64_LEN}; #[test] + #[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE fn test_key_loopback() { secret_policy_try_use_memfd_secrets(); let private_keys_dir = tempdir().unwrap(); diff --git a/rp/tests/smoketest.rs b/rp/tests/smoketest.rs index 9df2bb1..cb8164d 100644 --- a/rp/tests/smoketest.rs +++ b/rp/tests/smoketest.rs @@ -2,6 +2,7 @@ use std::process::Command; #[cfg(any(target_os = "linux", target_os = "freebsd"))] #[test] +#[cfg_attr(miri, ignore)] // unsupported operation: extern static `pidfd_spawnp` is not supported by Miri fn smoketest() -> anyhow::Result<()> { let tmpdir = tempfile::tempdir()?;