@@ -6163,6 +6163,20 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
61636163 error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file);
61646164 }
61656165
6166+ // Wallets used to wipe, but not erase, old unused multisig key info, which lead to huge memory leaks.
6167+ // Here we erase these multisig keys if they're zero'd out to free up space.
6168+ for (auto &td : m_transfers)
6169+ {
6170+ auto mk_it = td.m_multisig_k.begin();
6171+ while (mk_it != td.m_multisig_k.end())
6172+ {
6173+ if (*mk_it == rct::zero())
6174+ mk_it = td.m_multisig_k.erase(mk_it);
6175+ else
6176+ ++mk_it;
6177+ }
6178+ }
6179+
61666180 cryptonote::block genesis;
61676181 generate_genesis(genesis);
61686182 crypto::hash genesis_hash = get_block_hash(genesis);
@@ -7036,7 +7050,10 @@ void wallet2::commit_tx(pending_tx& ptx)
70367050
70377051 // tx generated, get rid of used k values
70387052 for (size_t idx: ptx.selected_transfers)
7053+ {
70397054 memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
7055+ m_transfers[idx].m_multisig_k.clear();
7056+ }
70407057
70417058 //fee includes dust if dust policy specified it.
70427059 LOG_PRINT_L1("Transaction successfully sent. <" << txid << ">" << ENDL
@@ -7540,7 +7557,10 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs)
75407557 // txes generated, get rid of used k values
75417558 for (size_t n = 0; n < txs.m_ptx.size(); ++n)
75427559 for (size_t idx: txs.m_ptx[n].construction_data.selected_transfers)
7560+ {
75437561 memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
7562+ m_transfers[idx].m_multisig_k.clear();
7563+ }
75447564
75457565 // zero out some data we don't want to share
75467566 for (auto &ptx: txs.m_ptx)
@@ -7864,7 +7884,10 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
78647884 // inputs in the transactions worked on here)
78657885 for (size_t n = 0; n < exported_txs.m_ptx.size(); ++n)
78667886 for (size_t idx: exported_txs.m_ptx[n].construction_data.selected_transfers)
7887+ {
78677888 memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
7889+ m_transfers[idx].m_multisig_k.clear();
7890+ }
78687891
78697892 exported_txs.m_signers.insert(get_multisig_signer_public_key());
78707893
@@ -13511,7 +13534,10 @@ cryptonote::blobdata wallet2::export_multisig()
1351113534 transfer_details &td = m_transfers[n];
1351213535 crypto::key_image ki;
1351313536 if (td.m_multisig_k.size())
13537+ {
1351413538 memwipe(td.m_multisig_k.data(), td.m_multisig_k.size() * sizeof(td.m_multisig_k[0]));
13539+ td.m_multisig_k.clear();
13540+ }
1351513541 info[n].m_LR.clear();
1351613542 info[n].m_partial_key_images.clear();
1351713543
0 commit comments