aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-12-17 19:00:25 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2020-12-17 19:00:25 +0100
commit7710ff187b5079d9f2573608b6cb33b15262b2b8 (patch)
tree3305e8bd73ab5300aa0467c8b59660b52205fd54 /api
parentversion: bump (diff)
downloadwintun-7710ff187b5079d9f2573608b6cb33b15262b2b8.tar.xz
wintun-7710ff187b5079d9f2573608b6cb33b15262b2b8.zip
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>
Diffstat (limited to 'api')
-rw-r--r--api/namespace.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/api/namespace.c b/api/namespace.c
index 509173c..0a4c775 100644
--- a/api/namespace.c
+++ b/api/namespace.c
@@ -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);