8000 fix: crash caused by GetHostNameW on Windows 7 by trop[bot] · Pull Request #31814 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: crash caused by GetHostNameW on Windows 7 #31814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions patches/node/.patches
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ fix_crash_creating_private_key_with_unsupported_algorithm.patch
fix_event_with_invalid_timestamp_in_trace_log.patch
test_fix_test-datetime-change-notify_after_daylight_change.patch
test_add_fixture_trim_option.patch
fix_crash_caused_by_gethostnamew_on_windows_7.patch
234 changes: 234 additions & 0 deletions patches/node/fix_crash_caused_by_gethostnamew_on_windows_7.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Fri, 12 Nov 2021 17:25:37 +0900
Subject: fix: crash caused by GetHostNameW on Windows 7

Backported from https://github.com/libuv/libuv/pull/3285.

diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 88602c7ee8623f16f87398cf3ffd1f71555fc1a0..5ffde08e1aed041c4da679156ed10f7e54bfc386 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -37,6 +37,7 @@
#include <psapi.h>
#include <tlhelp32.h>
#include <windows.h>
+#include <svcguid.h>
/* clang-format on */
#include <userenv.h>
#include <math.h>
@@ -56,6 +57,10 @@
/* The number of nanoseconds in one second. */
#define UV__NANOSEC 1000000000

+/* Local buffer size for WSAQUERYSETW data inside uv__gethostnamew_nt60
+ sizeof(WSAQUERYSETW) + 512 = 632 bytes to match GetHostNameW behavior */
+#define WSAQ_LOCAL_BUF_LEN (sizeof(WSAQUERYSETW) + 512)
+
/* Max user name length, from iphlpapi.h */
#ifndef UNLEN
# define UNLEN 256
@@ -72,6 +77,11 @@ static CRITICAL_SECTION process_title_lock;
/* Frequency of the high-resolution clock. */
static uint64_t hrtime_frequency_ = 0;

+/* Parameters for WSAQUERYSETW inside uv__gethostnamew_nt60 */
+static GUID guid_host_name = SVCID_HOSTNAME;
+static AFPROTOCOLS af_protocols[2] = { {AF_INET, IPPROTO_UDP},
+ {AF_INET, IPPROTO_TCP} };
+

/*
* One-time initialization code for functionality defined in util.c.
@@ -1663,6 +1673,125 @@ int uv_os_unsetenv(const char* name) {
}


+static int WSAAPI uv__gethostnamew_nt60(PWSTR name, int name_len) {
+ int result_len;
+ int error_code = NO_ERROR;
+
+ /* WSALookupService stuff
+ * Avoid dynamic memory allocation if possible */
+ CHAR local_buf[WSAQ_LOCAL_BUF_LEN];
+ DWORD dwlen = WSAQ_LOCAL_BUF_LEN;
+ WSAQUERYSETW* pwsaq;
+ /* hostname returned from WSALookupService stage */
+ WCHAR* result_name = NULL;
+ /* WSALookupService handle */
+ HANDLE hlookup;
+ /* Fallback to heap allocation if stack buffer is too small */
+ WSAQUERYSETW* heap_data = NULL;
+
+ /* check input */
+ if (name == NULL) {
+ error_code = WSAEFAULT;
+ goto cleanup;
+ }
+
+ /*
+ * Stage 1: Check environment variable
+ * _CLUSTER_NETWORK_NAME_ len == ComputeName(NETBIOS) len.
+ * i.e 15 characters + null.
+ * It overrides the actual hostname, so application can
+ * work when network name and computer name are different
+ */
+ result_len = GetEnvironmentVariableW(L"_CLUSTER_NETWORK_NAME_",
+ name,
+ name_len);
+ if (result_len != 0) {
+ if (result_len > name_len) {
+ error_code = WSAEFAULT;
+ }
+ goto cleanup;
+ }
+
+ /* Stage 2: Do normal lookup through WSALookupServiceLookup */
+ pwsaq = (WSAQUERYSETW*) local_buf;
+ memset(pwsaq, 0, sizeof(*pwsaq));
+ pwsaq->dwSize = sizeof(*pwsaq);
+ pwsaq->lpszServiceInstanceName = NULL;
+ pwsaq->lpServiceClassId = &guid_host_name;
+ pwsaq->dwNameSpace = NS_ALL;
+ pwsaq->lpafpProtocols = &af_protocols[0];
+ pwsaq->dwNumberOfProtocols = 2;
+
+ error_code = WSALookupServiceBeginW(pwsaq, LUP_RETURN_NAME, &hlookup);
+ if (error_code == NO_ERROR) {
+ /* Try stack allocation first */
+ error_code = WSALookupServiceNextW(hlookup, 0, &dwlen, pwsaq);
+ if (error_code == NO_ERROR) {
+ result_name = pwsaq->lpszServiceInstanceName;
+ } else {
+ error_code = WSAGetLastError();
+
+ if (error_code == WSAEFAULT) {
+ /* Should never happen */
+ assert(sizeof(CHAR) * dwlen >= sizeof(WSAQUERYSETW));
+
+ /* Fallback to the heap allocation */
+ heap_data = uv__malloc(sizeof(CHAR) * (size_t) dwlen);
+ if (heap_data != NULL) {
+ error_code = WSALookupServiceNextW(hlookup, 0, &dwlen, heap_data);
+ if (error_code == NO_ERROR) {
+ result_name = heap_data->lpszServiceInstanceName;
+ } else {
+ error_code = WSAGetLastError();
+ }
+ } else {
+ error_code = WSA_NOT_ENOUGH_MEMORY;
+ }
+ }
+ }
+
+ WSALookupServiceEnd(hlookup);
+
+ if (error_code != NO_ERROR) {
+ WSASetLastError(error_code);
+ }
+ }
+
+ if (result_name != NULL) {
+ size_t wlen = wcslen(result_name) + 1;
+
+ if (wlen <= (size_t) name_len) {
+ wmemcpy(name, result_name, wlen);
+ } else {
+ error_code = WSAEFAULT;
+ }
+ goto cleanup;
+ }
+
+ /* Stage 3: If WSALookupServiceLookup fails, fallback to GetComputerName */
+ result_len = name_len;
+ /* Reset error code */
+ error_code = NO_ERROR;
+
+ if (GetComputerNameW(name, (PDWORD)&result_len) == FALSE) {
+ error_code = WSAENETDOWN;
+ if (result_len >= name_len) {
+ error_code = WSAEFAULT;
+ }
+ }
+
+cleanup:
+ uv__free(heap_data);
+
+ if (error_code == NO_ERROR) {
+ return NO_ERROR;
+ } else {
+ WSASetLastError(error_code);
+ return SOCKET_ERROR;
+ }
+}
+
+
int uv_os_gethostname(char* buffer, size_t* size) {
WCHAR buf[UV_MAXHOSTNAMESIZE];
size_t len;
@@ -1674,7 +1803,9 @@ int uv_os_gethostname(char* buffer, size_t* size) {

uv__once_init(); /* Initialize winsock */

- if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
+ sGetHostNameW gethostnamew =
+ pGetHostNameW == NULL ? uv__gethostnamew_nt60 : pGetHostNameW;
+ if (gethostnamew(buf, UV_MAXHOSTNAMESIZE) != 0)
return uv_translate_sys_error(WSAGetLastError());

convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index bb86ec8ceac8ba3fccd02b292aca7ddfab38e187..9d6effb10ddd1801f7411ee71a70575b7072ab7d 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -45,12 +45,15 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
/* User32.dll function pointer */
sSetWinEventHook pSetWinEventHook;

+/* ws2_32.dll function pointer */
+sGetHostNameW pGetHostNameW;

void uv_winapi_init(void) {
HMODULE ntdll_module;
HMODULE powrprof_module;
HMODULE user32_module;
HMODULE kernel32_module;
+ HMODULE ws2_32_module;;

ntdll_module = GetModuleHandleA("ntdll.dll");
if (ntdll_module == NULL) {
@@ -134,4 +137,10 @@ void uv_winapi_init(void) {
pSetWinEventHook = (sSetWinEventHook)
GetProcAddress(user32_module, "SetWinEventHook");
}
+
+ ws2_32_module = LoadLibraryA("ws2_32.dll");
+ if (ws2_32_module != NULL) {
+ pGetHostNameW = (sGetHostNameW)
+ GetProcAddress(ws2_32_module, "GetHostNameW");
+ }
}
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 0b66b5634bca88cec65b1bf0c0193986f5ddd542..5951717ab9e21db274f956c44410cc03c1617eaf 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4739,6 +4739,11 @@ typedef struct _TCP_INITIAL_RTO_PARAMETERS {
# define SIO_TCP_INITIAL_RTO _WSAIOW(IOC_VENDOR,17)
#endif

+/* From winsock2.h */
+typedef int (WSAAPI *sGetHostNameW)
+ (PWSTR name,
+ int namelen);
+
/* Ntdll function pointers */
extern sRtlGetVersion pRtlGetVersion;
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
@@ -4759,4 +4764,7 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi
/* User32.dll function pointer */
extern sSetWinEventHook pSetWinEventHook;

+/* ws2_32.dll function pointer */
+extern sGetHostNameW pGetHostNameW;
+
#endif /* UV_WIN_WINAPI_H_ */
0