From 99a6b699cd650f13d7200d344bf5e2d4b45b20ac Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 26 Jan 2022 16:58:32 +0200 Subject: [PATCH] Fix race condition for SetBannedSetDirty() calls Another thread can `SetBannedSetDirty(true)` while `CBanDB::Write()` call being executed. The following `SetBannedSetDirty(false)` effectively makes `m_is_dirty` flag value inconsistent with the actual `m_banned` state. Such behavior can result in data loss, e.g., during shutdown. --- src/banman.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/banman.cpp b/src/banman.cpp index 87c1bbc89e2..b28e3f7f7cc 100644 --- a/src/banman.cpp +++ b/src/banman.cpp @@ -49,11 +49,12 @@ void BanMan::DumpBanlist() SweepBanned(); if (!BannedSetIsDirty()) return; banmap = m_banned; + SetBannedSetDirty(false); } int64_t n_start = GetTimeMillis(); - if (m_ban_db.Write(banmap)) { - SetBannedSetDirty(false); + if (!m_ban_db.Write(banmap)) { + SetBannedSetDirty(true); } LogPrint(BCLog::NET, "Flushed %d banned node addresses/subnets to disk %dms\n", banmap.size(),