aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/ipc-windows.h
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-06-24 01:52:06 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-07-20 13:24:18 +0200
commitc70bea7a314fa71c8ff44581079c6dd2d090ad63 (patch)
treecc296de274752b88e05d35c8adfb5599f1d52820 /src/ipc-windows.h
parentipc: cache windows lookups to avoid O(n^2) with nested lookups (diff)
downloadwireguard-tools-c70bea7a314fa71c8ff44581079c6dd2d090ad63.tar.xz
wireguard-tools-c70bea7a314fa71c8ff44581079c6dd2d090ad63.zip
ipc: remove windows elevation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r--src/ipc-windows.h85
1 files changed, 18 insertions, 67 deletions
diff --git a/src/ipc-windows.h b/src/ipc-windows.h
index 2382847..9c72a62 100644
--- a/src/ipc-windows.h
+++ b/src/ipc-windows.h
@@ -311,66 +311,6 @@ skip:;
return handle;
}
-static BOOL elevated_ioctl(HANDLE handle, DWORD code, void *in_buf, DWORD in_buf_len, void *out_buf, DWORD out_buf_len, DWORD *bytes_returned)
-{
- HANDLE thread_token, process_snapshot, winlogon_process, winlogon_token, duplicated_token;
- PROCESSENTRY32 entry = { .dwSize = sizeof(PROCESSENTRY32) };
- TOKEN_PRIVILEGES privileges = {
- .PrivilegeCount = 1,
- .Privileges = {{ .Attributes = SE_PRIVILEGE_ENABLED }}
- };
- SID expected_sid;
- DWORD bytes = sizeof(expected_sid);
- BOOL ret;
-
- if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid))
- return FALSE;
- if (!CreateWellKnownSid(WinLocalSystemSid, NULL, &expected_sid, &bytes))
- return FALSE;
-
- process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (process_snapshot == INVALID_HANDLE_VALUE)
- return FALSE;
- for (ret = Process32First(process_snapshot, &entry); ret; ret = Process32Next(process_snapshot, &entry)) {
- if (strcasecmp(entry.szExeFile, "winlogon.exe"))
- continue;
-
- RevertToSelf();
- if (!ImpersonateSelf(SecurityImpersonation))
- continue;
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &thread_token))
- continue;
- if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL)) {
- CloseHandle(thread_token);
- continue;
- }
- CloseHandle(thread_token);
-
- winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID);
- if (!winlogon_process)
- continue;
- if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &winlogon_token))
- continue;
- CloseHandle(winlogon_process);
- if (!DuplicateToken(winlogon_token, SecurityImpersonation, &duplicated_token)) {
- RevertToSelf();
- continue;
- }
- CloseHandle(winlogon_token);
- if (!SetThreadToken(NULL, duplicated_token)) {
- CloseHandle(duplicated_token);
- continue;
- }
- CloseHandle(duplicated_token);
- ret = DeviceIoControl(handle, code, in_buf, in_buf_len, out_buf, out_buf_len, bytes_returned, NULL);
- break;
- }
-
- RevertToSelf();
- CloseHandle(process_snapshot);
- return ret;
-}
-
static int kernel_get_device(struct wgdevice **device, const char *iface)
{
WG_IOCTL_INTERFACE *wg_iface;
@@ -389,10 +329,10 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
if (!handle)
return -errno;
- while (!elevated_ioctl(handle, WG_IOCTL_GET, NULL, 0, buf, buf_len, &buf_len)) {
+ while (!DeviceIoControl(handle, WG_IOCTL_GET, NULL, 0, buf, buf_len, &buf_len, NULL)) {
free(buf);
if (GetLastError() != ERROR_MORE_DATA) {
- errno = EIO;
+ errno = EACCES;
return -errno;
}
buf = malloc(buf_len);
@@ -500,10 +440,10 @@ out:
static int kernel_set_device(struct wgdevice *dev)
{
- WG_IOCTL_INTERFACE *wg_iface;
+ WG_IOCTL_INTERFACE *wg_iface = NULL;
WG_IOCTL_PEER *wg_peer;
WG_IOCTL_ALLOWED_IP *wg_aip;
- size_t buf_len = sizeof(WG_IOCTL_INTERFACE);
+ DWORD buf_len = sizeof(WG_IOCTL_INTERFACE);
HANDLE handle = kernel_interface_handle(dev->name);
struct wgpeer *peer;
struct wgallowedip *aip;
@@ -514,13 +454,22 @@ static int kernel_set_device(struct wgdevice *dev)
return -errno;
for_each_wgpeer(dev, peer) {
+ if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_PEER)) {
+ errno = EOVERFLOW;
+ goto out;
+ }
buf_len += sizeof(WG_IOCTL_PEER);
- for_each_wgallowedip(peer, aip)
+ for_each_wgallowedip(peer, aip) {
+ if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_ALLOWED_IP)) {
+ errno = EOVERFLOW;
+ goto out;
+ }
buf_len += sizeof(WG_IOCTL_ALLOWED_IP);
+ }
}
wg_iface = calloc(1, buf_len);
if (!wg_iface)
- return -errno;
+ goto out;
if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
memcpy(wg_iface->PrivateKey, dev->private_key, sizeof(wg_iface->PrivateKey));
@@ -586,8 +535,10 @@ static int kernel_set_device(struct wgdevice *dev)
}
wg_iface->PeersCount = peer_count;
- if (!elevated_ioctl(handle, WG_IOCTL_SET, NULL, 0, wg_iface, buf_len, &buf_len))
+ if (!DeviceIoControl(handle, WG_IOCTL_SET, NULL, 0, wg_iface, buf_len, &buf_len, NULL)) {
+ errno = EACCES;
goto out;
+ }
errno = 0;
out: