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:
Jeffrey Altman
2019-02-08 23:47:18 -05:00
committed by Nico Williams
parent 1a65611f61
commit d4c0d34548
5 changed files with 163 additions and 2 deletions

View File

@@ -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
}