From 759631e9ed168b9693cd41ddf3e5c1e11b3ecba3 Mon Sep 17 00:00:00 2001 From: Vladislav Date: Tue, 23 Jul 2024 11:25:04 +0300 Subject: [PATCH] fix(transaction): Fix namespace access (#3364) Our area of attack during concurrent transaction access is the call to DisarmInShard and DisarmInShardWhen, which only access is_armed - an atomic varible. It is not safe to arbitrarily call GetNamespace() if we write to it in InitBase Solution: Don't write to it post first initialization --- src/server/transaction.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/server/transaction.cc b/src/server/transaction.cc index 1ff6c8045..4d6d2f8a7 100644 --- a/src/server/transaction.cc +++ b/src/server/transaction.cc @@ -176,11 +176,18 @@ Transaction::~Transaction() { void Transaction::InitBase(Namespace* ns, DbIndex dbid, CmdArgList args) { global_ = false; - namespace_ = ns; db_index_ = dbid; full_args_ = args; local_result_ = OpStatus::OK; stats_.coordinator_index = ProactorBase::me() ? ProactorBase::me()->GetPoolIndex() : kInvalidSid; + + // Namespace is read by poll execution, so it can't be changed on the fly + if (IsScheduled()) { + DCHECK_EQ(namespace_, ns); + } else { + DCHECK(namespace_ == nullptr || namespace_ == ns); + namespace_ = ns; + } } void Transaction::InitGlobal() {