diff --git a/Cargo.lock b/Cargo.lock index f0eee42f..46252a3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,6 +53,7 @@ dependencies = [ "num-traits", "parking_lot 0.12.3", "plain", + "redox-driver-sys", "redox-scheme", "redox_event", "redox_syscall 0.9.0+rb0.3.1", @@ -249,6 +250,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" version = "0.10.3" @@ -778,6 +794,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + [[package]] name = "fbbootlogd" version = "0.1.0" @@ -834,6 +856,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -948,6 +976,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if 1.0.4", + "libc", + "r-efi 5.3.0", + "wasip2", +] + [[package]] name = "getrandom" version = "0.4.3" @@ -956,7 +996,7 @@ checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if 1.0.4", "libc", - "r-efi", + "r-efi 6.0.0", "rand_core 0.10.1", ] @@ -1012,9 +1052,9 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heapless" -version = "0.8.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" dependencies = [ "hash32", "stable_deref_trait", @@ -1492,6 +1532,7 @@ dependencies = [ "daemon", "libredox", "log", + "proptest", "redox-log", "redox-scheme", "redox_event", @@ -1717,6 +1758,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.13.0", + "num-traits", + "rand 0.9.5", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "ps2d" version = "0.1.0" @@ -1728,6 +1788,7 @@ dependencies = [ "libredox", "log", "orbclient", + "redox-driver-sys", "redox-scheme", "redox_event", "redox_syscall 0.9.0+rb0.3.1", @@ -1752,6 +1813,12 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bb0fd6580eeed0103c054e3fba2c2618ff476943762f28a645b63b8692b21c9" +[[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.46" @@ -1761,6 +1828,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r-efi" version = "6.0.0" @@ -1804,6 +1877,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + [[package]] name = "rand" version = "0.10.2" @@ -1835,6 +1918,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1865,12 +1958,30 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "rand_core" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + [[package]] name = "randd" version = "0.1.0" @@ -2149,6 +2260,18 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "sb16d" version = "0.1.0" @@ -2328,9 +2451,9 @@ dependencies = [ [[package]] name = "smoltcp" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb" +checksum = "5f73d40463bba65efc9adc6370b56df76d563cc46e2482bba58351b4afb7535e" dependencies = [ "bitflags 1.3.2", "byteorder", @@ -2417,6 +2540,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -2600,6 +2736,12 @@ dependencies = [ "serde", ] +[[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.24" @@ -2809,12 +2951,30 @@ dependencies = [ "utf8parse 0.1.1", ] +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.126" @@ -3038,6 +3198,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "xhcid" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index f145d6a8..0652a7cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,6 +127,7 @@ spin = "0.10" static_assertions = "1.1.0" thiserror = "2" toml = "1" +proptest = "1.11" [workspace.lints.rust] missing_docs = "allow" #TODO: set to deny when all public functions are documented diff --git a/netstack/Cargo.toml b/netstack/Cargo.toml index e2a5c954..ead48cb8 100644 --- a/netstack/Cargo.toml +++ b/netstack/Cargo.toml @@ -37,5 +37,36 @@ features = [ ] #For debugging: "log", "verbose" +[dev-dependencies] +proptest = "1.11" + +[[bin]] +name = "fuzz_ethernet" +path = "fuzz/fuzz_targets/ethernet.rs" + +[[bin]] +name = "fuzz_arp" +path = "fuzz/fuzz_targets/arp.rs" + +[[bin]] +name = "fuzz_icmp" +path = "fuzz/fuzz_targets/icmp.rs" + +[[bin]] +name = "fuzz_tcp" +path = "fuzz/fuzz_targets/tcp.rs" + +[[bin]] +name = "fuzz_udp" +path = "fuzz/fuzz_targets/udp.rs" + +[[bin]] +name = "fuzz_dhcp" +path = "fuzz/fuzz_targets/dhcp.rs" + +[[bin]] +name = "fuzz_dns" +path = "fuzz/fuzz_targets/dns.rs" + [lints] workspace = true diff --git a/netstack/src/filter/table.rs b/netstack/src/filter/table.rs index ebdab4b9..84c4924c 100644 --- a/netstack/src/filter/table.rs +++ b/netstack/src/filter/table.rs @@ -525,6 +525,47 @@ mod tests { assert_eq!(t.chain_counters.get(&Hook::InputLocal).copied().unwrap_or((0, 0)), (0, 0), "reset_counters must clear chain_counters"); assert_eq!(t.rules.len(), 1, - "reset_counters must preserve rules"); - } -} \ No newline at end of file + "reset_counters must preserve rules"); + } + + use proptest::prelude::*; + + proptest! { + #[test] + fn prop_filter_add_remove_roundtrip( + _id_seed in 0u32..1000u32, + hook_idx in 0usize..5, + verdict_idx in 0usize..4, + ) { + use crate::filter::rule::{Protocol, StateMatch}; + use crate::filter::{Hook, Verdict}; + let hook = [Hook::PreRouting, Hook::InputLocal, Hook::Forward, Hook::OutputLocal, Hook::PostRouting][hook_idx]; + let verdict = [Verdict::Accept, Verdict::Drop, Verdict::Log, Verdict::Reject][verdict_idx]; + let mut table = FilterTable::new(); + let rule = FilterRule { + id: 0, + hook, + src_addr: None, + src_prefix_len: 0, + dst_addr: None, + dst_prefix_len: 0, + protocol: None, + src_port: None, + dst_port: None, + in_dev: None, + out_dev: None, + state_match: None, + verdict, + match_count: 0, + }; + let _added_id = table.add(rule); + assert_eq!(table.rules.len(), 1, "rule was added"); + // remove the rule by iterating; the id is table-assigned + let id_to_remove = table.rules.iter().next().map(|r| r.id); + if let Some(id) = id_to_remove { + assert!(table.remove(id), "remove returns true for the added id"); + } + assert_eq!(table.rules.len(), 0, "remove clears the slot"); + } + } + } \ No newline at end of file