lib/krb5: krb5_get_instance does not work on Windows 7
krb5_get_instance() is meant to ensure that the shared library instance of heimdal loaded by a plugin matches the instance that loaded the plugin. It works by declaring a static C string whose memory address will be used as an instance identifier. If the instance returned from the plugin matches the instance obtain by the code that loads the plugin, then we can conclude the two instances are the same. This doesn't work on Windows 7. When heimdal.dll loads a plugin that is linked to heimdal.dll, the plugin's heimdal.dll is always a new instance. However, the requirement for plugin safety is not that the plugin be the same instance in memory but that they be the same instance on disk. This change loads the path name and version string for the module and generates a hash of those strings as an instance identifier. Change-Id: I1c0651969e9738c5feecb0b323969d13efd4704d
This commit is contained in:

committed by
Nico Williams

parent
1a65611f61
commit
d4c0d34548
@@ -170,13 +170,39 @@ _krb5_plugin_run_f(krb5_context context,
|
||||
* @ingroup krb5_support
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
static uintptr_t
|
||||
djb2(uintptr_t hash, unsigned char *str)
|
||||
{
|
||||
int c;
|
||||
|
||||
while (c = *str++)
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
|
||||
return hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
KRB5_LIB_FUNCTION uintptr_t KRB5_LIB_CALL
|
||||
krb5_get_instance(const char *libname)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *version;
|
||||
char *name;
|
||||
uintptr_t instance;
|
||||
|
||||
if (win32_getLibraryVersion("heimdal", &name, &version))
|
||||
return 0;
|
||||
instance = djb2(5381, name);
|
||||
instance = djb2(instance, version);
|
||||
free(name);
|
||||
free(version);
|
||||
return instance;
|
||||
#else
|
||||
static const char *instance = "libkrb5";
|
||||
|
||||
if (strcmp(libname, "krb5") == 0)
|
||||
return (uintptr_t)instance;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user