From a0887afc4fd58d5ae8b7f1853dc3ae7974120398 Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Thu, 7 May 2026 11:43:25 +0000 Subject: [PATCH] Add fuzing for AdminApiToken CRDT (#1443) Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1443 Reviewed-by: Alex --- fuzz/Cargo.toml | 7 +++++ fuzz/fuzz_targets/admin_api_token_crdt.rs | 37 +++++++++++++++++++++++ src/model/admin_token_table.rs | 8 +++++ 3 files changed, 52 insertions(+) create mode 100644 fuzz/fuzz_targets/admin_api_token_crdt.rs diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 03ecf3be..3a6f4973 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -43,3 +43,10 @@ path = "fuzz_targets/block_ref_crdt.rs" test = false doc = false bench = false + +[[bin]] +name = "admin_api_token_crdt" +path = "fuzz_targets/admin_api_token_crdt.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzz_targets/admin_api_token_crdt.rs b/fuzz/fuzz_targets/admin_api_token_crdt.rs new file mode 100644 index 00000000..a69ee735 --- /dev/null +++ b/fuzz/fuzz_targets/admin_api_token_crdt.rs @@ -0,0 +1,37 @@ +#![no_main] + +use garage_fuzz::check_crdt_laws; +use garage_model::admin_token_table::{AdminApiToken, AdminApiTokenParams, AdminApiTokenScope}; +use garage_util::crdt; +use libfuzzer_sys::fuzz_target; + +type Input = ( + bool, + crdt::Lww, + crdt::Lww>, + crdt::Lww, +); + +fn make(input: Input) -> AdminApiToken { + let (deleted, name, expiration, scope) = input; + let state = if deleted { + crdt::Deletable::Deleted + } else { + crdt::Deletable::present(AdminApiTokenParams { + created: 0, + token_hash: String::new(), + name, + expiration, + scope, + }) + }; + AdminApiToken { + prefix: String::new(), + state, + } +} + +fuzz_target!(|inputs: (Input, Input, Input)| { + let (a, b, c) = inputs; + check_crdt_laws(make(a), make(b), make(c)); +}); diff --git a/src/model/admin_token_table.rs b/src/model/admin_token_table.rs index 25c7bd62..97159651 100644 --- a/src/model/admin_token_table.rs +++ b/src/model/admin_token_table.rs @@ -51,6 +51,14 @@ mod v2 { pub use v2::*; +#[cfg(feature = "arbitrary")] +impl<'a> arbitrary::Arbitrary<'a> for AdminApiTokenScope { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let set: std::collections::BTreeSet = arbitrary::Arbitrary::arbitrary(u)?; + Ok(AdminApiTokenScope(set.into_iter().collect())) + } +} + impl Crdt for AdminApiTokenParams { fn merge(&mut self, o: &Self) { self.name.merge(&o.name);