Reported RPC Overflow

Disclosed: 2026-04-06 17:23:22 By jehrenhofermagicgrants To monero
Unknown
Vulnerability Details
*This submission is being made by [MAGIC Grants](https://magicgrants.org), a public charity that supports critical infrastructure. The MAGIC Monero Fund, one of our committees, [recently contracted](https://donate.magicgrants.org/monero/projects/fuzzing-monero-rpc) [Ada Logics](https://adalogics.com/) to perform fuzzing work on Monero's RPC endpoints. This submission has been forwarded from Ada Logics to the Monero team. We waive the opportunity for a monetary reward. If you prefer that we submit the findings from this engagement a different way, please let us know by emailing me at [email protected].* --- The issue happens specifically on these lines: https://github.com/monero-project/monero/blob/17f6fb871c09507cd13c23fdecd9cbcca3f01326/src/rpc/core_rpc_server.cpp#L1278-L1292 Specifically, on line 1291 there will be an overflow on 1291 if the size of b.data() does not match the size of crypto::key_image. There is a missing return statement following line 1289. ASAN Stack trace from fuzzer: ``` ==9082==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fa31d153228 at pc 0x56045cd8cc32 bp 0x7ffd3ad28590 sp 0x7ffd3ad27d50 READ of size 32 at 0x7fa31d153228 thread T0 #0 0x56045cd8cc31 in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3 #1 0x56045d97ee5a in construct<crypto::key_image, const crypto::key_image &> /usr/local/bin/../include/c++/v1/__memory/allocator.h:173:24 #2 0x56045d97ee5a in construct<crypto::key_image, const crypto::key_image &, void> /usr/local/bin/../include/c++/v1/__memory/allocator_traits.h:296:9 #3 0x56045d97ee5a in crypto::key_image* std::__1::vector<crypto::key_image, std::__1::allocator<crypto::key_image>>::__push_back_slow_path<crypto::key_image const&>(crypto::key_image const&) /usr/local/bin/../include/c++/v1/vector:1 453:3 #4 0x56045d6919ee in push_back /usr/local/bin/../include/c++/v1/vector:1467:13 #5 0x56045d6919ee in cryptonote::core_rpc_server::on_is_key_image_spent(epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::request_t> const&, epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_ SPENT::response_t>&, epee::net_utils::connection_context_base const*) /src/monero/monero/src/rpc/core_rpc_server.cpp:1291:18 #6 0x56045d16ffd2 in fuzz_is_key_image_spent(cryptonote::core_rpc_server&, unsigned char const*, unsigned long&, unsigned long) /src/fuzz_base.cpp:191:7 #7 0x56045cdcead0 in operator() /usr/local/bin/../include/c++/v1/__functional/function.h:428:12 #8 0x56045cdcead0 in operator() /usr/local/bin/../include/c++/v1/__functional/function.h:981:10 #9 0x56045cdcead0 in LLVMFuzzerTestOneInput /src/fuzz_rpc.cpp:20:5 #10 0x56045cc82f70 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13 #11 0x56045cc82795 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:516:7 #12 0x56045cc83f75 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:760:19 #13 0x56045cc84d05 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:905:5 #14 0x56045cc73b4b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:914:6 #15 0x56045cc9ef22 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 #16 0x7fa31f359082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 5792732f783158c66fb4f3756458ca24e46e827d) #17 0x56045cc663cd in _start (/out/fuzz_rpc+0x7b03cd) Address 0x7fa31d153228 is located in stack of thread T0 at offset 552 in frame #0 0x56045d690f2f in cryptonote::core_rpc_server::on_is_key_image_spent(epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::request_t> const&, epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_ SPENT::response_t>&, epee::net_utils::connection_context_base const*) /src/monero/monero/src/rpc/core_rpc_server.cpp:1261 This frame has 16 object(s): [32, 48) 'lock.i' (line 108) [64, 144) 'pt_is_key_image_spent' (line 1262) [176, 200) 'ref.tmp' (line 1262) [240, 264) 'ref.tmp2' (line 1262) [304, 336) 'tracker' (line 1262) [368, 369) 'ok' (line 1263) [384, 388) 'ref.tmp9' (line 1264) [400, 424) 'ref.tmp10' (line 1264) [464, 488) 'key_images52' (line 1278) [528, 552) 'b' (line 1281) <== Memory access at offset 552 overflows this variable [592, 616) 'spent_status' (line 1293) [656, 660) 'ref.tmp112' (line 1302) [672, 696) 'txs' (line 1305) [736, 760) 'ki' (line 1306) [800, 832) 'hash' (line 1315) [864, 896) 'spent_key_image' (line 1316) HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /src/monero/monero/src/rpc/core_rpc_server.cpp:1291:18 in cryptonote::core_rpc_server::on_is_key_image_spent(epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::requ est_t> const&, epee::misc_utils::struct_init<cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::response_t>&, epee::net_utils::connection_context_base const*) Shadow bytes around the buggy address: 0x7fa31d152f80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 0x7fa31d153000: f1 f1 f1 f1 f8 f8 f2 f2 00 00 00 00 00 00 00 00 0x7fa31d153080: 00 00 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 0x7fa31d153180: f8 f2 f8 f8 f8 f2 f2 f2 f2 f2 00 00 00 f2 f2 f2 =>0x7fa31d153200: f2 f2 00 00 00[f2]f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 0x7fa31d153280: f2 f2 f8 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2 0x7fa31d153300: f2 f2 f2 f2 f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 0x7fa31d153380: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 0x7fa31d153400: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 0x7fa31d153480: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==9082==ABORTING MS: 5 CopyPart-CopyPart-ChangeByte-ShuffleBytes-EraseBytes-; base unit: f64317d83d7d96e23d2ca5976ca263cb6c35a5c2 0x0,0x8,0x23, \000\010# artifact_prefix='./'; Test unit written to ./crash-6133c92848a171509d0711f60b758025242bb03d Base64: AAg ``` ## Impact Potential denial of service
Actions
View on HackerOne
Report Stats
  • Report ID: 3240792
  • State: Closed
  • Substate: resolved
Share this report