wallet2: make keys unlocker reentrant

protects against having your keys mangled
This commit is contained in:
moneromooo-monero 2019-10-29 13:53:07 +00:00
parent 4c9fd8d86d
commit 3b8dcc290d
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
2 changed files with 23 additions and 3 deletions

View file

@ -1038,10 +1038,15 @@ uint64_t gamma_picker::pick()
return first_rct + crypto::rand_idx(n_rct); return first_rct + crypto::rand_idx(n_rct);
}; };
boost::mutex wallet_keys_unlocker::lockers_lock;
unsigned int wallet_keys_unlocker::lockers = 0;
wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, const boost::optional<tools::password_container> &password): wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, const boost::optional<tools::password_container> &password):
w(w), w(w),
locked(password != boost::none) locked(password != boost::none)
{ {
boost::lock_guard<boost::mutex> lock(lockers_lock);
if (lockers++ > 0)
locked = false;
if (!locked || w.is_unattended() || w.ask_password() != tools::wallet2::AskPasswordToDecrypt || w.watch_only()) if (!locked || w.is_unattended() || w.ask_password() != tools::wallet2::AskPasswordToDecrypt || w.watch_only())
{ {
locked = false; locked = false;
@ -1056,6 +1061,9 @@ wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, bool locked, const epee::
w(w), w(w),
locked(locked) locked(locked)
{ {
boost::lock_guard<boost::mutex> lock(lockers_lock);
if (lockers++ > 0)
locked = false;
if (!locked) if (!locked)
return; return;
w.generate_chacha_key_from_password(password, key); w.generate_chacha_key_from_password(password, key);
@ -1064,9 +1072,19 @@ wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, bool locked, const epee::
wallet_keys_unlocker::~wallet_keys_unlocker() wallet_keys_unlocker::~wallet_keys_unlocker()
{ {
if (!locked) try
return; {
try { w.encrypt_keys(key); } boost::lock_guard<boost::mutex> lock(lockers_lock);
if (lockers == 0)
{
MERROR("There are no lockers in wallet_keys_unlocker dtor");
return;
}
--lockers;
if (!locked)
return;
w.encrypt_keys(key);
}
catch (...) catch (...)
{ {
MERROR("Failed to re-encrypt wallet keys"); MERROR("Failed to re-encrypt wallet keys");

View file

@ -122,6 +122,8 @@ private:
wallet2 &w; wallet2 &w;
bool locked; bool locked;
crypto::chacha_key key; crypto::chacha_key key;
static boost::mutex lockers_lock;
static unsigned int lockers;
}; };
class i_wallet2_callback class i_wallet2_callback