api: close private namespace when unloading DLL
Prior, people making calls to LoadLibrary/FreeLibrary would experience a failure to create or open adapters, because the private namespace was already loaded into the process and not cleaned up on DLL detachment. While this pattern is probably a misuse of the library, we should still support cleaning that up. This commit makes the right calls to free the boundary descriptor and close the private namespace. It does not, however, destroy the private namespace using the flag on the second parameter, in case of races with other processes. Reported-by: Brad Spencer <bspencer@blackberry.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
d440234d6e
commit
7710ff187b
@ -12,7 +12,8 @@
|
||||
#include <bcrypt.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static BOOL HasInitialized = FALSE;
|
||||
static HANDLE PrivateNamespace = NULL;
|
||||
static HANDLE BoundaryDescriptor = NULL;
|
||||
static CRITICAL_SECTION Initializing;
|
||||
static BCRYPT_ALG_HANDLE AlgProvider;
|
||||
|
||||
@ -43,7 +44,7 @@ static _Return_type_success_(return != FALSE) BOOL NamespaceRuntimeInit(void)
|
||||
DWORD LastError;
|
||||
|
||||
EnterCriticalSection(&Initializing);
|
||||
if (HasInitialized)
|
||||
if (PrivateNamespace)
|
||||
{
|
||||
LeaveCriticalSection(&Initializing);
|
||||
return TRUE;
|
||||
@ -65,25 +66,25 @@ static _Return_type_success_(return != FALSE) BOOL NamespaceRuntimeInit(void)
|
||||
goto cleanupBCryptCloseAlgorithmProvider;
|
||||
}
|
||||
|
||||
HANDLE Boundary = CreateBoundaryDescriptorW(L"Wintun", 0);
|
||||
if (!Boundary)
|
||||
BoundaryDescriptor = CreateBoundaryDescriptorW(L"Wintun", 0);
|
||||
if (!BoundaryDescriptor)
|
||||
{
|
||||
LastError = LOG_LAST_ERROR(L"Failed to create boundary descriptor");
|
||||
goto cleanupBCryptCloseAlgorithmProvider;
|
||||
}
|
||||
if (!AddSIDToBoundaryDescriptor(&Boundary, Sid))
|
||||
if (!AddSIDToBoundaryDescriptor(&BoundaryDescriptor, Sid))
|
||||
{
|
||||
LastError = LOG_LAST_ERROR(L"Failed to add SID to boundary descriptor");
|
||||
goto cleanupBCryptCloseAlgorithmProvider;
|
||||
goto cleanupBoundaryDescriptor;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (CreatePrivateNamespaceW(&SecurityAttributes, Boundary, L"Wintun"))
|
||||
if ((PrivateNamespace = CreatePrivateNamespaceW(&SecurityAttributes, BoundaryDescriptor, L"Wintun")) != NULL)
|
||||
break;
|
||||
if ((LastError = GetLastError()) == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
if (OpenPrivateNamespaceW(Boundary, L"Wintun"))
|
||||
if ((PrivateNamespace = OpenPrivateNamespaceW(BoundaryDescriptor, L"Wintun")) != NULL)
|
||||
break;
|
||||
if ((LastError = GetLastError()) == ERROR_PATH_NOT_FOUND)
|
||||
continue;
|
||||
@ -91,13 +92,14 @@ static _Return_type_success_(return != FALSE) BOOL NamespaceRuntimeInit(void)
|
||||
}
|
||||
else
|
||||
LOG_ERROR(L"Failed to create private namespace", LastError);
|
||||
goto cleanupBCryptCloseAlgorithmProvider;
|
||||
goto cleanupBoundaryDescriptor;
|
||||
}
|
||||
|
||||
HasInitialized = TRUE;
|
||||
LeaveCriticalSection(&Initializing);
|
||||
return TRUE;
|
||||
|
||||
cleanupBoundaryDescriptor:
|
||||
DeleteBoundaryDescriptor(BoundaryDescriptor);
|
||||
cleanupBCryptCloseAlgorithmProvider:
|
||||
BCryptCloseAlgorithmProvider(AlgProvider, 0);
|
||||
cleanupLeaveCriticalSection:
|
||||
@ -219,10 +221,12 @@ void
|
||||
NamespaceDone(void)
|
||||
{
|
||||
EnterCriticalSection(&Initializing);
|
||||
if (HasInitialized)
|
||||
if (PrivateNamespace)
|
||||
{
|
||||
BCryptCloseAlgorithmProvider(AlgProvider, 0);
|
||||
HasInitialized = FALSE;
|
||||
ClosePrivateNamespace(PrivateNamespace, 0);
|
||||
DeleteBoundaryDescriptor(BoundaryDescriptor);
|
||||
PrivateNamespace = NULL;
|
||||
}
|
||||
LeaveCriticalSection(&Initializing);
|
||||
DeleteCriticalSection(&Initializing);
|
||||
|
Loading…
Reference in New Issue
Block a user