What changed, and why it matters
This commit updates a Monero fuzz test that feeds random or crafted data to the wallet's cold-output import code. It only changes test files and test code; no production wallet or node code is modified. The change makes the fuzzer use the newer, safer import path (import_outputs_from_str) and adds a testnet wallet setup. On its own, this is a test-harness cleanup, not a fix for a live security bug.
No urgent action. Treat as routine test maintenance. If this change was made because the old fuzzer was crashing or finding bugs, review related commits or issues for any actual wallet2 import_outputs fixes that may need separate assessment.
Security signals we found
Fuzz target switched from manual binary_archive deserialization to wallet2::import_outputs_from_str, which may exercise more validation code
New testnet wallet configured with unattended=true and kdf_rounds=1, reducing test-side key-derivation overhead
No changes to production wallet, node, or consensus code
Commit title and message describe only a test/fuzz import fix
Evidence from the diff
The patch modifies tests/fuzz/cold-outputs.cpp and renames/replaces fuzz corpus files. The fuzzer now constructs a testnet wallet2 instance with unattended=true and kdf_rounds=1, then calls wallet->import_outputs_from_str() on the fuzz input instead of manually deserializing a binary archive and calling import_outputs(). The corpus files are renamed to reflect old/unauth/v4 format variants. There is no change to src/wallet or consensus code, so this commit does not itself patch a vulnerability in production code.
Changed components
tests/fuzz/cold-outputs.cpptests/data/fuzz/cold-outputs/*Inspect captured patch +4 / −6
diff --git a/tests/data/fuzz/cold-outputs/out-all-6 b/tests/data/fuzz/cold-outputs/out-all-6
deleted file mode 100644
index 8016928..0000000
--- a/tests/data/fuzz/cold-outputs/out-all-6
+++ /dev/null
@@ -1 +0,0 @@
-Monero output export�ŕ�I��(����Ȣ�?u�S�S����'�}�y?V���%
;�*�Q(�n���ٶF�d�W�Wa+0�3�6�<��!�`37��e4����R�ͫH��&9�g(��-�L�����|��I��ʜ���lQ�������+]&��cK�\�p����/�#U�8�T�����e>~2�$G����MיX���x�3I�n+�-2�Y(�T/���]u��}�V��d�a 8�T��GW�-g�g����V2w���.o�{��w��%7�����Iud^��] !b����A��)%�z�����:���Z��U��?L��MB�D/x��2�k��gGE���g���g;Q�g
\ No newline at end of file
diff --git a/tests/data/fuzz/cold-outputs/out-none-6 b/tests/data/fuzz/cold-outputs/out-none-6
deleted file mode 100644
index c539059..0000000
Binary files a/tests/data/fuzz/cold-outputs/out-none-6 and /dev/null differ
diff --git a/tests/data/fuzz/cold-outputs/out-old-all-0 b/tests/data/fuzz/cold-outputs/out-old-all-0
new file mode 100644
index 0000000..c539059
Binary files /dev/null and b/tests/data/fuzz/cold-outputs/out-old-all-0 differ
diff --git a/tests/data/fuzz/cold-outputs/out-unauth-all-6 b/tests/data/fuzz/cold-outputs/out-unauth-all-6
new file mode 100644
index 0000000..8016928
--- /dev/null
+++ b/tests/data/fuzz/cold-outputs/out-unauth-all-6
@@ -0,0 +1 @@
+Monero output export�ŕ�I��(����Ȣ�?u�S�S����'�}�y?V���%
;�*�Q(�n���ٶF�d�W�Wa+0�3�6�<��!�`37��e4����R�ͫH��&9�g(��-�L�����|��I��ʜ���lQ�������+]&��cK�\�p����/�#U�8�T�����e>~2�$G����MיX���x�3I�n+�-2�Y(�T/���]u��}�V��d�a 8�T��GW�-g�g����V2w���.o�{��w��%7�����Iud^��] !b����A��)%�z�����:���Z��U��?L��MB�D/x��2�k��gGE���g���g;Q�g
\ No newline at end of file
diff --git a/tests/data/fuzz/cold-outputs/out-v4-all-21 b/tests/data/fuzz/cold-outputs/out-v4-all-21
new file mode 100644
index 0000000..992d957
Binary files /dev/null and b/tests/data/fuzz/cold-outputs/out-v4-all-21 differ
diff --git a/tests/fuzz/cold-outputs.cpp b/tests/fuzz/cold-outputs.cpp
index 929500d..777798e 100644
--- a/tests/fuzz/cold-outputs.cpp
+++ b/tests/fuzz/cold-outputs.cpp
@@ -38,9 +38,10 @@
static tools::wallet2 *wallet = NULL;
BEGIN_INIT_SIMPLE_FUZZER()
- static tools::wallet2 local_wallet;
+ static tools::wallet2 local_wallet(cryptonote::TESTNET, /*kdf_rounds=*/1, /*unattended=*/true);
wallet = &local_wallet;
+ // Testnet restore height 3031129
static const char * const spendkey_hex = "f285d4ac9e66271256fc7cde0d3d6b36f66efff6ccd766706c408e86f4997a0d";
crypto::secret_key spendkey;
epee::string_tools::hex_to_pod(spendkey_hex, spendkey);
@@ -51,9 +52,6 @@ BEGIN_INIT_SIMPLE_FUZZER()
END_INIT_SIMPLE_FUZZER()
BEGIN_SIMPLE_FUZZER()
- std::tuple<uint64_t, uint64_t, std::vector<tools::wallet2::transfer_details>> outputs;
- binary_archive<false> ar{{buf, len}};
- ::serialization::serialize(ar, outputs);
- size_t n_outputs = wallet->import_outputs(outputs);
+ const size_t n_outputs = wallet->import_outputs_from_str({reinterpret_cast<const char*>(buf), len});
std::cout << boost::lexical_cast<std::string>(n_outputs) << " outputs imported" << std::endl;
END_SIMPLE_FUZZER()
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.