Reported RPC Overflow
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 HackerOneReport Stats
- Report ID: 3240792
- State: Closed
- Substate: resolved