mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 08:03:04 +01:00
Frontported CORE-3443: Races in UDF library lookup
This commit is contained in:
parent
070718bea2
commit
931f1afd51
116
src/jrd/flu.cpp
116
src/jrd/flu.cpp
@ -173,7 +173,7 @@ namespace Jrd
|
|||||||
FPTR_INT Module::lookup(const char* module, const char* name, DatabaseModules& interest)
|
FPTR_INT Module::lookup(const char* module, const char* name, DatabaseModules& interest)
|
||||||
{
|
{
|
||||||
// Try to find loadable module
|
// Try to find loadable module
|
||||||
Module m = lookupModule(module, true);
|
Module m = lookupModule(module);
|
||||||
if (! m)
|
if (! m)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -193,24 +193,11 @@ namespace Jrd
|
|||||||
return (FPTR_INT)rc;
|
return (FPTR_INT)rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
FPTR_INT Module::lookup(const TEXT* module, const TEXT* name)
|
|
||||||
{
|
|
||||||
// Try to find loadable module
|
|
||||||
Module m = lookupModule(module, false);
|
|
||||||
if (! m)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Firebird::string symbol;
|
|
||||||
terminate_at_space(symbol, name);
|
|
||||||
return (FPTR_INT)(m.lookupSymbol(symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
// flag 'udf' means pass name-path through UdfDirectoryList
|
// flag 'udf' means pass name-path through UdfDirectoryList
|
||||||
Module Module::lookupModule(const char* name, bool udf)
|
Module Module::lookupModule(const char* name)
|
||||||
{
|
{
|
||||||
Firebird::MutexLockGuard lg(modulesMutex);
|
Firebird::MutexLockGuard lg(modulesMutex);
|
||||||
|
|
||||||
Firebird::PathName initialModule;
|
Firebird::PathName initialModule;
|
||||||
terminate_at_space(initialModule, name);
|
terminate_at_space(initialModule, name);
|
||||||
|
|
||||||
@ -248,53 +235,37 @@ namespace Jrd
|
|||||||
return Module(im);
|
return Module(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (udf)
|
// UdfAccess verification
|
||||||
|
Firebird::PathName path, relative;
|
||||||
|
|
||||||
|
// Search for module name in UdfAccess restricted
|
||||||
|
// paths list
|
||||||
|
PathUtils::splitLastComponent(path, relative, fixedModule);
|
||||||
|
if (path.length() == 0 && PathUtils::isRelative(fixedModule))
|
||||||
{
|
{
|
||||||
// UdfAccess verification
|
path = fixedModule;
|
||||||
Firebird::PathName path, relative;
|
if (! iUdfDirectoryList().expandFileName(fixedModule, path))
|
||||||
|
|
||||||
// Search for module name in UdfAccess restricted
|
|
||||||
// paths list
|
|
||||||
PathUtils::splitLastComponent(path, relative, fixedModule);
|
|
||||||
if (path.length() == 0 && PathUtils::isRelative(fixedModule))
|
|
||||||
{
|
{
|
||||||
path = fixedModule;
|
// relative path was used, but no appropriate file present
|
||||||
if (! iUdfDirectoryList().expandFileName(fixedModule, path))
|
continue;
|
||||||
{
|
|
||||||
// relative path was used, but no appropriate file present
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The module name, including directory path,
|
|
||||||
// must satisfy UdfAccess entry in config file.
|
|
||||||
if (! iUdfDirectoryList().isPathInList(fixedModule))
|
|
||||||
{
|
|
||||||
ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("UDF/BLOB-filter module") <<
|
|
||||||
Arg::Str(initialModule));
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleLoader::Module* mlm = ModuleLoader::loadModule(fixedModule);
|
|
||||||
if (mlm)
|
|
||||||
{
|
|
||||||
im = FB_NEW(*getDefaultMemoryPool())
|
|
||||||
InternalModule(*getDefaultMemoryPool(), mlm, initialModule, fixedModule);
|
|
||||||
loadedModules().add(im);
|
|
||||||
return Module(im);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// The module name, including directory path,
|
||||||
|
// must satisfy UdfAccess entry in config file.
|
||||||
|
if (! iUdfDirectoryList().isPathInList(fixedModule))
|
||||||
{
|
{
|
||||||
// try to load permanent module
|
ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("UDF/BLOB-filter module") <<
|
||||||
ModuleLoader::Module* mlm = ModuleLoader::loadModule(fixedModule);
|
Arg::Str(initialModule));
|
||||||
if (mlm)
|
}
|
||||||
{
|
|
||||||
im = FB_NEW(*getDefaultMemoryPool())
|
ModuleLoader::Module* mlm = ModuleLoader::loadModule(fixedModule);
|
||||||
InternalModule(*getDefaultMemoryPool(), mlm, initialModule, fixedModule);
|
if (mlm)
|
||||||
loadedModules().add(im);
|
{
|
||||||
im->acquire(); // make permanent
|
im = FB_NEW(*getDefaultMemoryPool())
|
||||||
return Module(im);
|
InternalModule(*getDefaultMemoryPool(), mlm, initialModule, fixedModule);
|
||||||
}
|
loadedModules().add(im);
|
||||||
|
return Module(im);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,29 +273,22 @@ namespace Jrd
|
|||||||
return Module();
|
return Module();
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::~Module()
|
Module::InternalModule::~InternalModule()
|
||||||
{
|
{
|
||||||
if (interMod)
|
delete handle;
|
||||||
|
|
||||||
|
Firebird::MutexLockGuard lg(modulesMutex);
|
||||||
|
|
||||||
|
for (size_t m = 0; m < loadedModules().getCount(); m++)
|
||||||
{
|
{
|
||||||
interMod->release();
|
if (loadedModules()[m] == this)
|
||||||
if (! interMod->inUse())
|
|
||||||
{
|
{
|
||||||
Firebird::MutexLockGuard lg(modulesMutex);
|
loadedModules().remove(m);
|
||||||
for (size_t m = 0; m < loadedModules().getCount(); m++)
|
return;
|
||||||
{
|
|
||||||
if (loadedModules()[m] == interMod)
|
|
||||||
{
|
|
||||||
loadedModules().remove(m);
|
|
||||||
delete interMod;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fb_assert(false);
|
|
||||||
// In production server we delete interMod here
|
|
||||||
// (though this is not normal case)
|
|
||||||
delete interMod;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Jrd
|
} // namespace Jrd
|
||||||
|
@ -31,20 +31,20 @@
|
|||||||
|
|
||||||
#include "../common/classes/objects_array.h"
|
#include "../common/classes/objects_array.h"
|
||||||
#include "../common/os/mod_loader.h"
|
#include "../common/os/mod_loader.h"
|
||||||
|
#include "../common/classes/RefCounted.h"
|
||||||
|
|
||||||
namespace Jrd
|
namespace Jrd
|
||||||
{
|
{
|
||||||
class Module
|
class Module
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
class InternalModule
|
class InternalModule : public Firebird::RefCounted
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
InternalModule(const InternalModule &im);
|
InternalModule(const InternalModule &im);
|
||||||
void operator=(const InternalModule &im);
|
void operator=(const InternalModule &im);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
long useCount;
|
|
||||||
ModuleLoader::Module* handle;
|
ModuleLoader::Module* handle;
|
||||||
Firebird::PathName originalName, loadName;
|
Firebird::PathName originalName, loadName;
|
||||||
|
|
||||||
@ -57,59 +57,30 @@ namespace Jrd
|
|||||||
return handle->findSymbol(name);
|
return handle->findSymbol(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* explicit InternalModule(MemoryPool& p)
|
|
||||||
: useCount(0), handle(0),
|
|
||||||
originalName(p), loadName(p)
|
|
||||||
{ }
|
|
||||||
*/
|
|
||||||
InternalModule(MemoryPool& p,
|
InternalModule(MemoryPool& p,
|
||||||
ModuleLoader::Module* h,
|
ModuleLoader::Module* h,
|
||||||
const Firebird::PathName& on,
|
const Firebird::PathName& on,
|
||||||
const Firebird::PathName& ln)
|
const Firebird::PathName& ln)
|
||||||
: useCount(0), handle(h),
|
: handle(h),
|
||||||
originalName(p, on), loadName(p, ln)
|
originalName(p, on), loadName(p, ln)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~InternalModule()
|
~InternalModule();
|
||||||
{
|
|
||||||
fb_assert(useCount == 0);
|
|
||||||
delete handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Firebird::PathName &pn) const
|
bool operator==(const Firebird::PathName &pn) const
|
||||||
{
|
{
|
||||||
return originalName == pn || loadName == pn;
|
return originalName == pn || loadName == pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inUse() const
|
|
||||||
{
|
|
||||||
return useCount > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void acquire()
|
|
||||||
{
|
|
||||||
fb_assert(handle);
|
|
||||||
++useCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
fb_assert(useCount > 0);
|
|
||||||
--useCount;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
InternalModule* interMod;
|
Firebird::RefPtr<InternalModule> interMod;
|
||||||
|
|
||||||
Module(InternalModule* h) : interMod(h)
|
Module(InternalModule* h)
|
||||||
{
|
: interMod(h)
|
||||||
if (interMod)
|
{ }
|
||||||
{
|
|
||||||
interMod->acquire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Module lookupModule(const char*, bool);
|
static Module lookupModule(const char*);
|
||||||
|
|
||||||
static InternalModule* scanModule(const Firebird::PathName& name);
|
static InternalModule* scanModule(const Firebird::PathName& name);
|
||||||
|
|
||||||
@ -118,32 +89,21 @@ namespace Jrd
|
|||||||
|
|
||||||
Module() : interMod(0) { }
|
Module() : interMod(0) { }
|
||||||
|
|
||||||
explicit Module(MemoryPool&) : interMod(0) { }
|
explicit Module(MemoryPool&)
|
||||||
|
: interMod(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
Module(MemoryPool&, const Module& m) : interMod(m.interMod)
|
Module(MemoryPool&, const Module& m)
|
||||||
{
|
: interMod(m.interMod)
|
||||||
if (interMod)
|
{ }
|
||||||
{
|
|
||||||
interMod->acquire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Module(const Module& m) : interMod(m.interMod)
|
Module(const Module& m)
|
||||||
{
|
: interMod(m.interMod)
|
||||||
if (interMod)
|
{ }
|
||||||
{
|
|
||||||
interMod->acquire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Module();
|
|
||||||
|
|
||||||
// used for UDF/BLOB Filter
|
// used for UDF/BLOB Filter
|
||||||
static FPTR_INT lookup(const char*, const char*, Firebird::SortedObjectsArray<Module>&);
|
static FPTR_INT lookup(const char*, const char*, Firebird::SortedObjectsArray<Module>&);
|
||||||
|
|
||||||
// used in y-valve
|
|
||||||
static FPTR_INT lookup(const char*, const char*);
|
|
||||||
|
|
||||||
bool operator>(const Module &im) const;
|
bool operator>(const Module &im) const;
|
||||||
|
|
||||||
void *lookupSymbol(const Firebird::string& name)
|
void *lookupSymbol(const Firebird::string& name)
|
||||||
|
Loading…
Reference in New Issue
Block a user