diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2021-01-17 17:21:21 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2021-01-17 18:10:20 +0100 |
commit | ad57fb756b1c2df625790bd9c296ec28daa93740 (patch) | |
tree | 5046596f65379b72d6f563ebe8c95bdf586e1735 | |
parent | 30e664dcce1a9adb9ba9a29e4f0cf809767870dd (diff) |
wallet: Add BerkeleyDB version sanity check at init time
Detect version conflicts between the run-time BerkeleyDB library and the one used during compilation.
This is very unsafe (can result in anything from crashes to corruption) so shut down when one is detected.
-rw-r--r-- | src/wallet/bdb.cpp | 17 | ||||
-rw-r--r-- | src/wallet/bdb.h | 4 | ||||
-rw-r--r-- | src/wallet/init.cpp | 5 |
3 files changed, 26 insertions, 0 deletions
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index 6ed48593fb..c0d107bf39 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -723,6 +723,23 @@ bool BerkeleyBatch::TxnAbort() return (ret == 0); } +bool BerkeleyDatabaseSanityCheck() +{ + int major, minor; + DbEnv::version(&major, &minor, nullptr); + + /* If the major version differs, or the minor version of library is *older* + * than the header that was compiled against, flag an error. + */ + if (major != DB_VERSION_MAJOR || minor < DB_VERSION_MINOR) { + LogPrintf("BerkeleyDB database version conflict: header version is %d.%d, library version is %d.%d\n", + DB_VERSION_MAJOR, DB_VERSION_MINOR, major, minor); + return false; + } + + return true; +} + std::string BerkeleyDatabaseVersion() { return DbEnv::version(nullptr, nullptr, nullptr); diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index bf1617d67f..a8209587d7 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -223,6 +223,10 @@ public: std::string BerkeleyDatabaseVersion(); +/** Perform sanity check of runtime BDB version versus linked BDB version. + */ +bool BerkeleyDatabaseSanityCheck(); + //! Return object giving access to Berkeley database at specified path. std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error); diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 085dde1026..0d2be64dfb 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -86,6 +86,11 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const bool WalletInit::ParameterInteraction() const { +#ifdef USE_BDB + if (!BerkeleyDatabaseSanityCheck()) { + return InitError(Untranslated("A version conflict was detected between the run-time BerkeleyDB library and the one used during compilation.")); + } +#endif if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { for (const std::string& wallet : gArgs.GetArgs("-wallet")) { LogPrintf("%s: parameter interaction: -disablewallet -> ignoring -wallet=%s\n", __func__, wallet); |