8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:40:38 +01:00

Fixed bug GH-6843 : Crash when UDR is used by system attachment, for ex. Garbage Collector

This commit is contained in:
hvlad 2021-06-04 14:51:49 +03:00
parent fda403bfdd
commit 2b0dc05f52
4 changed files with 34 additions and 8 deletions

View File

@ -385,11 +385,7 @@ public:
JAttachment* getInterface() throw();
JProvider* getProvider()
{
fb_assert(att_provider);
return att_provider;
}
JProvider* getProvider();
private:
Attachment(MemoryPool* pool, Database* dbb, JProvider* provider);
@ -461,6 +457,12 @@ inline bool Attachment::isUtility() const
return (att_utility != UTIL_NONE);
}
inline JProvider* Attachment::getProvider()
{
fb_assert(att_provider || (att_flags & ATT_system));
return att_provider;
}
// This class holds references to all attachments it contains
class AttachmentsRefHolder

View File

@ -603,8 +603,13 @@ ExtEngineManager::ExternalContextImpl::ExternalContextImpl(thread_db* tdbb,
internalAttachment->getStable()->addRef();
externalAttachment = MasterInterfacePtr()->registerAttachment
(internalAttachment->getProvider(), internalAttachment->getInterface());
Jrd::JProvider* jProv = internalAttachment->getProvider();
Jrd::JAttachment* jAtt = internalAttachment->getInterface();
// System attachments (such as garbage collector) have no external interface
// and should not be used by UDR's
if (jProv && jAtt)
externalAttachment = MasterInterfacePtr()->registerAttachment(jProv, jAtt);
}
ExtEngineManager::ExternalContextImpl::~ExternalContextImpl()
@ -616,6 +621,8 @@ ExtEngineManager::ExternalContextImpl::~ExternalContextImpl()
externalAttachment->release();
externalAttachment = NULL;
}
else
internalAttachment->getStable()->release();
}
void ExtEngineManager::ExternalContextImpl::releaseTransaction()
@ -640,8 +647,11 @@ void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
fb_assert(!externalTransaction && !internalTransaction);
if ((internalTransaction = newTransaction))
{
if (externalAttachment)
externalTransaction = MasterInterfacePtr()->registerTransaction(externalAttachment, internalTransaction);
}
}
IMaster* ExtEngineManager::ExternalContextImpl::getMaster()
{
@ -657,6 +667,8 @@ IExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(CheckStatusWra
Firebird::IAttachment* ExtEngineManager::ExternalContextImpl::getAttachment(
CheckStatusWrapper* /*status*/)
{
checkExternalAttachment();
externalAttachment->addRef();
return externalAttachment;
}
@ -664,6 +676,8 @@ Firebird::IAttachment* ExtEngineManager::ExternalContextImpl::getAttachment(
Firebird::ITransaction* ExtEngineManager::ExternalContextImpl::getTransaction(
CheckStatusWrapper* /*status*/)
{
checkExternalAttachment();
externalTransaction->addRef();
return externalTransaction;
}
@ -703,6 +717,13 @@ void* ExtEngineManager::ExternalContextImpl::setInfo(int code, void* value)
return oldValue;
}
void ExtEngineManager::ExternalContextImpl::checkExternalAttachment()
{
if (!externalAttachment)
{
(Arg::Gds(isc_random) << Arg::Str("Use of system attachment in UDR is not allowed")).raise();
}
}
//---------------------

View File

@ -167,6 +167,8 @@ private:
void* setInfo(int code, void* value);
private:
void checkExternalAttachment();
Firebird::IExternalEngine* engine;
Attachment* internalAttachment;
Firebird::ITransaction* internalTransaction;

View File

@ -5091,6 +5091,7 @@ void Database::garbage_collector(Database* dbb)
TRA_commit(tdbb, transaction, false);
Monitoring::cleanupAttachment(tdbb);
dbb->dbb_extManager.closeAttachment(tdbb, attachment);
attachment->releaseLocks(tdbb);
LCK_fini(tdbb, LCK_OWNER_attachment);