From 3b8dcc290d87fd16698b6dca161ded22ee681fdc Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 29 Oct 2019 13:53:07 +0000 Subject: [PATCH] wallet2: make keys unlocker reentrant protects against having your keys mangled --- src/wallet/wallet2.cpp | 24 +++++++++++++++++++++--- src/wallet/wallet2.h | 2 ++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9b3e7e8b4..18fc93fd9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1038,10 +1038,15 @@ uint64_t gamma_picker::pick() 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 &password): w(w), locked(password != boost::none) { + boost::lock_guard lock(lockers_lock); + if (lockers++ > 0) + locked = false; if (!locked || w.is_unattended() || w.ask_password() != tools::wallet2::AskPasswordToDecrypt || w.watch_only()) { locked = false; @@ -1056,6 +1061,9 @@ wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, bool locked, const epee:: w(w), locked(locked) { + boost::lock_guard lock(lockers_lock); + if (lockers++ > 0) + locked = false; if (!locked) return; 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() { - if (!locked) - return; - try { w.encrypt_keys(key); } + try + { + boost::lock_guard 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 (...) { MERROR("Failed to re-encrypt wallet keys"); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 640565a4e..d0c01fd71 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -122,6 +122,8 @@ private: wallet2 &w; bool locked; crypto::chacha_key key; + static boost::mutex lockers_lock; + static unsigned int lockers; }; class i_wallet2_callback