From 007db8bd94b2dd4ded9ceeb8a248ea2ba8d5ab06 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 2 Nov 2020 12:07:05 +0100 Subject: [PATCH] api: serialize driver installation Signed-off-by: Jason A. Donenfeld --- api/adapter.c | 18 +++++++++++++----- api/namespace.c | 26 +++++++++++++++++++++++++- api/namespace.h | 6 +++++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/api/adapter.c b/api/adapter.c index 7db8023..d996d99 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -621,7 +621,7 @@ WintunGetAdapter(_In_z_ const WCHAR *Pool, _In_z_ const WCHAR *Name, _Out_ WINTU return LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user"), ERROR_ACCESS_DENIED; DWORD Result; - HANDLE Mutex = NamespaceTakeMutex(Pool); + HANDLE Mutex = NamespaceTakePoolMutex(Pool); if (!Mutex) { Result = ERROR_INVALID_HANDLE; @@ -1029,7 +1029,7 @@ CreateAdapter( LOG(WINTUN_LOG_INFO, L"Creating adapter"); DWORD Result; - HANDLE Mutex = NamespaceTakeMutex(Pool); + HANDLE Mutex = NamespaceTakePoolMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; @@ -1428,10 +1428,16 @@ static BOOL EnsureWintunUnloaded(VOID) static WINTUN_STATUS InstallDriver(_Out_writes_z_(MAX_PATH) WCHAR InfStorePath[MAX_PATH], _Inout_ BOOL *RebootRequired) { + HANDLE DriverInstallationLock = NamespaceTakeDriverInstallationMutex(); + if (!DriverInstallationLock) + return LOG_LAST_ERROR(L"Failed to take driver installation mutex"); DWORD Result; WCHAR RandomTempSubDirectory[MAX_PATH]; if ((Result = CreateTemporaryDirectory(RandomTempSubDirectory)) != ERROR_SUCCESS) - return LOG(WINTUN_LOG_ERR, L"Failed to create temporary folder"), Result; + { + LOG(WINTUN_LOG_ERR, L"Failed to create temporary folder"); + goto cleanupDriverInstallationLock; + } WCHAR CatPath[MAX_PATH] = { 0 }; WCHAR SysPath[MAX_PATH] = { 0 }; @@ -1518,6 +1524,8 @@ cleanupDelete: DeleteFileW(InfPath); cleanupDirectory: RemoveDirectoryW(RandomTempSubDirectory); +cleanupDriverInstallationLock: + NamespaceReleaseMutex(DriverInstallationLock); return Result; } @@ -1730,7 +1738,7 @@ cleanupDirectory: static WINTUN_STATUS GetAdapter(_In_z_ const WCHAR *Pool, _In_ const GUID *CfgInstanceID, _Out_ WINTUN_ADAPTER **Adapter) { - HANDLE Mutex = NamespaceTakeMutex(Pool); + HANDLE Mutex = NamespaceTakePoolMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; HDEVINFO DevInfo; @@ -1940,7 +1948,7 @@ cleanupToken: WINTUN_STATUS WINAPI WintunEnumAdapters(_In_z_ const WCHAR *Pool, _In_ WINTUN_ENUM_CALLBACK_FUNC Func, _In_ LPARAM Param) { - HANDLE Mutex = NamespaceTakeMutex(Pool); + HANDLE Mutex = NamespaceTakePoolMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; DWORD Result = ERROR_SUCCESS; diff --git a/api/namespace.c b/api/namespace.c index 9258b53..7f6959b 100644 --- a/api/namespace.c +++ b/api/namespace.c @@ -102,7 +102,7 @@ cleanupLeaveCriticalSection: _Check_return_ HANDLE -NamespaceTakeMutex(_In_z_ const WCHAR *Pool) +NamespaceTakePoolMutex(_In_z_ const WCHAR *Pool) { HANDLE Mutex = NULL; @@ -147,6 +147,30 @@ cleanupSha256: return Mutex; } +_Check_return_ +HANDLE +NamespaceTakeDriverInstallationMutex(void) +{ + HANDLE Mutex = NULL; + + if (NamespaceRuntimeInit() != ERROR_SUCCESS) + return NULL; + Mutex = CreateMutexW(&SecurityAttributes, FALSE, L"Wintun\\Wintun-Driver-Installation-Mutex"); + if (!Mutex) + return NULL; + switch (WaitForSingleObject(Mutex, INFINITE)) + { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + goto out; + } + + CloseHandle(Mutex); + Mutex = NULL; +out: + return Mutex; +} + void NamespaceReleaseMutex(_In_ HANDLE Mutex) { diff --git a/api/namespace.h b/api/namespace.h index 753068d..0f2598a 100644 --- a/api/namespace.h +++ b/api/namespace.h @@ -9,7 +9,11 @@ _Check_return_ HANDLE -NamespaceTakeMutex(_In_z_ const WCHAR *Pool); +NamespaceTakePoolMutex(_In_z_ const WCHAR *Pool); + +_Check_return_ +HANDLE +NamespaceTakeDriverInstallationMutex(void); void NamespaceReleaseMutex(_In_ HANDLE Mutex);