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

View File

@ -603,8 +603,13 @@ ExtEngineManager::ExternalContextImpl::ExternalContextImpl(thread_db* tdbb,
internalAttachment->getStable()->addRef(); internalAttachment->getStable()->addRef();
externalAttachment = MasterInterfacePtr()->registerAttachment Jrd::JProvider* jProv = internalAttachment->getProvider();
(internalAttachment->getProvider(), internalAttachment->getInterface()); 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() ExtEngineManager::ExternalContextImpl::~ExternalContextImpl()
@ -616,6 +621,8 @@ ExtEngineManager::ExternalContextImpl::~ExternalContextImpl()
externalAttachment->release(); externalAttachment->release();
externalAttachment = NULL; externalAttachment = NULL;
} }
else
internalAttachment->getStable()->release();
} }
void ExtEngineManager::ExternalContextImpl::releaseTransaction() void ExtEngineManager::ExternalContextImpl::releaseTransaction()
@ -640,7 +647,10 @@ void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
fb_assert(!externalTransaction && !internalTransaction); fb_assert(!externalTransaction && !internalTransaction);
if ((internalTransaction = newTransaction)) if ((internalTransaction = newTransaction))
externalTransaction = MasterInterfacePtr()->registerTransaction(externalAttachment, internalTransaction); {
if (externalAttachment)
externalTransaction = MasterInterfacePtr()->registerTransaction(externalAttachment, internalTransaction);
}
} }
IMaster* ExtEngineManager::ExternalContextImpl::getMaster() IMaster* ExtEngineManager::ExternalContextImpl::getMaster()
@ -657,6 +667,8 @@ IExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(CheckStatusWra
Firebird::IAttachment* ExtEngineManager::ExternalContextImpl::getAttachment( Firebird::IAttachment* ExtEngineManager::ExternalContextImpl::getAttachment(
CheckStatusWrapper* /*status*/) CheckStatusWrapper* /*status*/)
{ {
checkExternalAttachment();
externalAttachment->addRef(); externalAttachment->addRef();
return externalAttachment; return externalAttachment;
} }
@ -664,6 +676,8 @@ Firebird::IAttachment* ExtEngineManager::ExternalContextImpl::getAttachment(
Firebird::ITransaction* ExtEngineManager::ExternalContextImpl::getTransaction( Firebird::ITransaction* ExtEngineManager::ExternalContextImpl::getTransaction(
CheckStatusWrapper* /*status*/) CheckStatusWrapper* /*status*/)
{ {
checkExternalAttachment();
externalTransaction->addRef(); externalTransaction->addRef();
return externalTransaction; return externalTransaction;
} }
@ -703,6 +717,13 @@ void* ExtEngineManager::ExternalContextImpl::setInfo(int code, void* value)
return oldValue; 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); void* setInfo(int code, void* value);
private: private:
void checkExternalAttachment();
Firebird::IExternalEngine* engine; Firebird::IExternalEngine* engine;
Attachment* internalAttachment; Attachment* internalAttachment;
Firebird::ITransaction* internalTransaction; Firebird::ITransaction* internalTransaction;

View File

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