diff --git a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Test-updated-NtQueryDirectoryFile-mask-reset-behaviour.patch b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Test-updated-NtQueryDirectoryFile-mask-reset-behaviour.patch new file mode 100644 index 0000000..3ee2a75 --- /dev/null +++ b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Test-updated-NtQueryDirectoryFile-mask-reset-behaviour.patch @@ -0,0 +1,269 @@ +From 58aef4d41bbf3ed4e1335346ed508f1bebf8bca7 Mon Sep 17 00:00:00 2001 +From: Eugene McArdle +Date: Thu, 19 Dec 2024 09:59:53 +1000 +Subject: [PATCH] ntdll: Test updated NtQueryDirectoryFile mask reset behaviour + +--- + dlls/ntdll/tests/directory.c | 240 +++++++++++++++++++++++++++++++++++ + 1 file changed, 240 insertions(+) + +diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c +index 52ff9936560..6aec2ff6408 100644 +--- a/dlls/ntdll/tests/directory.c ++++ b/dlls/ntdll/tests/directory.c +@@ -964,6 +964,245 @@ done: + pRtlFreeUnicodeString(&ntdirname); + } + ++static void set_up_mask_test(const char *testdir) ++{ ++ BOOL ret; ++ char buf[MAX_PATH + 5]; ++ HANDLE h; ++ ++ ret = CreateDirectoryA(testdir, NULL); ++ ok( ret, "couldn't create dir '%s', error %ld\n", testdir, GetLastError() ); ++ ++ sprintf(buf, "%s\\%s", testdir, "a-file.h"); ++ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, ++ FILE_ATTRIBUTE_NORMAL, 0); ++ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf ); ++ CloseHandle(h); ++ ++ sprintf(buf, "%s\\%s", testdir, "another-file.h"); ++ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, ++ FILE_ATTRIBUTE_NORMAL, 0); ++ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf ); ++ CloseHandle(h); ++} ++ ++static void tear_down_mask_test(const char *testdir) ++{ ++ int ret; ++ char buf[MAX_PATH]; ++ ++ sprintf(buf, "%s\\%s", testdir, "a-file.h"); ++ ret = DeleteFileA(buf); ++ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND), ++ "Failed to rm %s, error %ld\n", buf, GetLastError() ); ++ ++ sprintf(buf, "%s\\%s", testdir, "another-file.h"); ++ ret = DeleteFileA(buf); ++ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND), ++ "Failed to rm %s, error %ld\n", buf, GetLastError() ); ++ ++ RemoveDirectoryA(testdir); ++} ++ ++ ++/* Performs a query with NtQueryDirectoryFile() */ ++static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNICODE_STRING *mask, ++ NTSTATUS expected_status, BOOL check_name_and_length, BOOL validate_only) ++{ ++ NTSTATUS status; ++ IO_STATUS_BLOCK io; ++ UINT data_size = sizeof(FILE_DIRECTORY_INFORMATION) + (MAX_PATH * sizeof(wchar_t)); ++ BYTE data[8192]; ++ FILE_DIRECTORY_INFORMATION *dir_info; ++ WCHAR *name; ++ ULONG name_len; ++ WCHAR *mask_value = {0}; ++ ULONG mask_len = 0; ++ ++ if (mask) ++ { ++ mask_len = mask->Length / sizeof(WCHAR); ++ mask_value = mask->Buffer; ++ } ++ ++ /* Perform the query */ ++ status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, data_size, ++ FileDirectoryInformation, TRUE, mask, restart_scan ); ++ ++ if (validate_only && status != expected_status) return FALSE; ++ ++ todo_wine ++ ok( status == expected_status, "unexpected status : 0x%lx Test settings: file mask: '%s', restart: %d, expected status: 0x%lx\n", ++ status, wine_dbgstr_wn(mask_value, mask_len), restart_scan, expected_status ); ++ ++ /* Verify the results if required */ ++ if (status == 0 && check_name_and_length) ++ { ++ dir_info = (FILE_DIRECTORY_INFORMATION *)data; ++ name = dir_info->FileName; ++ name_len = dir_info->FileNameLength / sizeof(WCHAR); ++ ++ todo_wine ++ ok( name_len == mask_len, "unexpected filename length %lu, expected %lu\n", name_len, mask_len ); ++ todo_wine ++ ok( !memcmp(name, mask_value, mask_len), "unexpected filename %s, expected %s\n", ++ wine_dbgstr_wn(name, name_len), wine_dbgstr_wn(mask_value, mask_len) ); ++ } ++ return TRUE; ++} ++ ++static void test_NtQueryDirectoryFile_change_mask(void) ++{ ++ NTSTATUS status; ++ HANDLE dirh; ++ HANDLE dirh_test_multiple_handles; ++ HANDLE dirh_test_fresh_null; ++ HANDLE dirh_test_fresh_empty; ++ char testdir[MAX_PATH]; ++ OBJECT_ATTRIBUTES attr; ++ IO_STATUS_BLOCK io; ++ UNICODE_STRING ntdirname; ++ WCHAR testdir_w[MAX_PATH]; ++ ++ UNICODE_STRING atestfile; ++ UNICODE_STRING anothertestfile; ++ UNICODE_STRING notatestfile; ++ UNICODE_STRING testmask; ++ UNICODE_STRING emptymask; ++ ++ pRtlInitUnicodeString(&atestfile, L"a-file.h"); ++ pRtlInitUnicodeString(&anothertestfile, L"another-file.h"); ++ pRtlInitUnicodeString(¬atestfile, L"not-a-file.h"); ++ pRtlInitUnicodeString(&testmask, L"*.h"); ++ pRtlInitUnicodeString(&emptymask, L""); ++ ++ /* Clean up from prior aborted run, if any, then set up test files */ ++ ok( GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n" ); ++ strcat(testdir, "mask.tmp"); ++ tear_down_mask_test(testdir); ++ set_up_mask_test(testdir); ++ ++ pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1); ++ if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL)) ++ { ++ ok( 0, "RtlDosPathNametoNtPathName_U failed\n" ); ++ goto done; ++ } ++ InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); ++ ++ /* Open a handle for our test directory */ ++ status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, ++ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ++ ok( status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); ++ if (status != STATUS_SUCCESS) ++ { ++ skip("can't test if we can't open the directory\n"); ++ goto done; ++ } ++ ++ /* Open a handle for our test directory to test multiple handles */ ++ status = pNtOpenFile(&dirh_test_multiple_handles, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, ++ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ++ ok( status == STATUS_SUCCESS, "failed to open second handle to dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); ++ if (status != STATUS_SUCCESS) ++ { ++ skip("can't test if we can't open a second handle to the directory\n"); ++ goto done; ++ } ++ ++ /* Open a handle for our test directory to test null masks with a fresh handle */ ++ status = pNtOpenFile(&dirh_test_fresh_null, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, ++ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ++ ok( status == STATUS_SUCCESS, "failed to open handle to dir '%s' for testing NULL masks, ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); ++ if (status != STATUS_SUCCESS) ++ { ++ skip("can't test NULL masks if we can't open an additional handle to the directory\n"); ++ goto done; ++ } ++ ++ /* Open a handle for our test directory to test empty masks with a fresh handle */ ++ status = pNtOpenFile(&dirh_test_fresh_empty, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, ++ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ++ ok( status == STATUS_SUCCESS, "failed to open handle to dir '%s' for testing empty masks, ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); ++ if (status != STATUS_SUCCESS) ++ { ++ skip("can't test empty masks if we can't open an additional handle to the directory\n"); ++ goto done; ++ } ++ ++ /* Verify that NtQueryDirectoryFile mask reset behaviour introduced in Windows 8 is supported */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, TRUE); ++ if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, ¬atestfile, STATUS_NO_MORE_FILES, TRUE, TRUE)) ++ { ++ skip("Win8+ NtQueryDirectoryFile mask reset behaviour not supported\n"); ++ goto done; ++ } ++ ++ /* Test that caches for two handles to a single directory do not interfere with each other*/ ++ /* Search for a non-existent file, putting it into a state with an empty cache */ ++ /* This also confirms that using a non-existent mask with a fresh handle returns a different status*/ ++ test_NtQueryDirectoryFile_mask(dirh_test_multiple_handles, TRUE, ¬atestfile, STATUS_NO_SUCH_FILE, TRUE, FALSE); ++ /* Confirm that handle is in a state where it fails to find atestfile */ ++ test_NtQueryDirectoryFile_mask(dirh_test_multiple_handles, FALSE, &atestfile, STATUS_NO_MORE_FILES, TRUE, FALSE); ++ /* Confirm that another handle is able to find atestfile */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE); ++ ++ /* All searches for `notatestfile` are expected to fail */ ++ /* Tests should also fail if the scan is not reset, and the mask changes to an incompatible one */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &anothertestfile, STATUS_SUCCESS, TRUE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, ¬atestfile, STATUS_NO_MORE_FILES, TRUE, FALSE); ++ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, ¬atestfile, STATUS_NO_MORE_FILES, TRUE, FALSE); ++ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, &anothertestfile, STATUS_NO_MORE_FILES, TRUE, FALSE); ++ ++ /* Test mask that matches multiple files, do not check results against the mask */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, ¬atestfile, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, ¬atestfile, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ ++ /* Test NULL mask with a previously used handle that last returned an error */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ ++ /* Test NULL mask with a previously used handle that last returned STATUS_SUCCESS */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, TRUE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ ++ /* Test NULL mask with a fresh handle */ ++ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, FALSE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE); ++ ++ /* Test empty mask with a previously used handle that last returned an error */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, ¬atestfile, STATUS_NO_MORE_FILES, FALSE, TRUE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &emptymask, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, &emptymask, STATUS_NO_MORE_FILES, FALSE, FALSE); ++ ++ /* Test empty mask with a previously used handle that last returned STATUS_SUCCESS */ ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, TRUE); ++ test_NtQueryDirectoryFile_mask(dirh, TRUE, &emptymask, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh, FALSE, &emptymask, STATUS_SUCCESS, FALSE, FALSE); ++ ++ /* Test empty mask with a fresh handle */ ++ test_NtQueryDirectoryFile_mask(dirh_test_fresh_empty, TRUE, &emptymask, STATUS_SUCCESS, FALSE, FALSE); ++ test_NtQueryDirectoryFile_mask(dirh_test_fresh_empty, FALSE, &emptymask, STATUS_SUCCESS, FALSE, FALSE); ++ ++ /* Cleanup */ ++done: ++ tear_down_mask_test(testdir); ++ pRtlFreeUnicodeString(&ntdirname); ++ pRtlFreeUnicodeString(&atestfile); ++ pRtlFreeUnicodeString(&anothertestfile); ++ pRtlFreeUnicodeString(¬atestfile); ++} ++ + static NTSTATUS get_file_id( FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name ) + { + OBJECT_ATTRIBUTES attr; +@@ -1157,5 +1396,6 @@ START_TEST(directory) + test_directory_sort( sysdir ); + test_NtQueryDirectoryFile(); + test_NtQueryDirectoryFile_case(); ++ test_NtQueryDirectoryFile_change_mask(); + test_redirection(); + } +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Test-updated-NtQueryDirectoryFile-behaviour-if-scan-is-reset-with-a-new-mask.patch b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Test-updated-NtQueryDirectoryFile-behaviour-if-scan-is-reset-with-a-new-mask.patch deleted file mode 100644 index b92ecfe..0000000 --- a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Test-updated-NtQueryDirectoryFile-behaviour-if-scan-is-reset-with-a-new-mask.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 08d3fc4d1f2b81e96dfc0de176926990a451705a Mon Sep 17 00:00:00 2001 -From: Eugene McArdle -Date: Fri, 29 Nov 2024 10:32:31 +1000 -Subject: [PATCH] ntdll: Test updated NtQueryDirectoryFile behaviour if scan is - reset with a new mask - ---- - dlls/ntdll/tests/directory.c | 164 +++++++++++++++++++++++++++++++++++ - 1 file changed, 164 insertions(+) - -diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c -index 52ff9936560..27027d41d9d 100644 ---- a/dlls/ntdll/tests/directory.c -+++ b/dlls/ntdll/tests/directory.c -@@ -964,6 +964,169 @@ done: - pRtlFreeUnicodeString(&ntdirname); - } - -+static void set_up_mask_test(const char *testdir) -+{ -+ BOOL ret; -+ char buf[MAX_PATH + 5]; -+ HANDLE h; -+ -+ ret = CreateDirectoryA(testdir, NULL); -+ ok( ret, "couldn't create dir '%s', error %ld\n", testdir, GetLastError() ); -+ -+ sprintf(buf, "%s\\%s", testdir, "a-file.h"); -+ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, -+ FILE_ATTRIBUTE_NORMAL, 0); -+ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf ); -+ CloseHandle(h); -+ -+ sprintf(buf, "%s\\%s", testdir, "another-file.h"); -+ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, -+ FILE_ATTRIBUTE_NORMAL, 0); -+ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf ); -+ CloseHandle(h); -+} -+ -+static void tear_down_mask_test(const char *testdir) -+{ -+ int ret; -+ char buf[MAX_PATH]; -+ -+ sprintf(buf, "%s\\%s", testdir, "a-file.h"); -+ ret = DeleteFileA(buf); -+ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND), -+ "Failed to rm %s, error %ld\n", buf, GetLastError() ); -+ -+ sprintf(buf, "%s\\%s", testdir, "another-file.h"); -+ ret = DeleteFileA(buf); -+ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND), -+ "Failed to rm %s, error %ld\n", buf, GetLastError() ); -+ -+ RemoveDirectoryA(testdir); -+} -+ -+ -+/* Performs a query with NtQueryDirectoryFile() */ -+static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNICODE_STRING mask, -+ BOOL expect_success, BOOL validate_only) -+{ -+ NTSTATUS status; -+ IO_STATUS_BLOCK io; -+ UINT data_size = sizeof(FILE_DIRECTORY_INFORMATION) + (MAX_PATH * sizeof(wchar_t)); -+ BYTE data[8192]; -+ FILE_DIRECTORY_INFORMATION *dir_info; -+ WCHAR *name; -+ ULONG name_len; -+ ULONG mask_len = mask.Length / sizeof(WCHAR); -+ -+ /* Perform the query */ -+ status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, data_size, -+ FileDirectoryInformation, TRUE, &mask, restart_scan ); -+ if (expect_success) -+ { -+ if (validate_only && status != STATUS_SUCCESS) return FALSE; -+ -+ ok( status == STATUS_SUCCESS, "could not find file mask: '%s', restart: %d, error %ld\n", -+ wine_dbgstr_wn(mask.Buffer, mask_len), restart_scan, GetLastError() ); -+ /* Print the query parameters and the result */ -+ if (status == 0) { -+ dir_info = (FILE_DIRECTORY_INFORMATION *)data; -+ name = dir_info->FileName; -+ name_len = dir_info->FileNameLength / sizeof(WCHAR); -+ -+ ok( name_len == mask_len, "unexpected filename length %lu, expected %lu\n", name_len, mask_len ); -+ ok( !memcmp(name, mask.Buffer, mask_len), "unexpected filename %s, expected %s\n", -+ wine_dbgstr_wn(name, name_len), wine_dbgstr_wn(mask.Buffer, mask_len) ); -+ } -+ } -+ else -+ { -+ if (validate_only && status == STATUS_SUCCESS) return FALSE; -+ /* Print the query parameters and the result */ -+ if (status == 0) { -+ dir_info = (FILE_DIRECTORY_INFORMATION *)data; -+ name = dir_info->FileName; -+ name_len = dir_info->FileNameLength / sizeof(WCHAR); -+ -+ ok ( status != STATUS_SUCCESS, "unexpectedly found file. mask: '%s', found %s\n", -+ wine_dbgstr_wn(mask.Buffer, mask_len), wine_dbgstr_wn(name, name_len) ); -+ } -+ } -+ return TRUE; -+} -+ -+static void test_NtQueryDirectoryFile_change_mask(void) -+{ -+ NTSTATUS status; -+ HANDLE dirh; -+ char testdir[MAX_PATH]; -+ OBJECT_ATTRIBUTES attr; -+ IO_STATUS_BLOCK io; -+ UNICODE_STRING ntdirname; -+ WCHAR testdir_w[MAX_PATH]; -+ -+ UNICODE_STRING atestfile; -+ UNICODE_STRING anothertestfile; -+ UNICODE_STRING notatestfile; -+ -+ BOOL run_updated_tests = TRUE; -+ -+ pRtlInitUnicodeString(&atestfile, L"a-file.h"); -+ pRtlInitUnicodeString(&anothertestfile, L"another-file.h"); -+ pRtlInitUnicodeString(¬atestfile, L"not-a-file.h"); -+ -+ /* Clean up from prior aborted run, if any, then set up test files */ -+ ok( GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n" ); -+ strcat(testdir, "mask.tmp"); -+ tear_down_mask_test(testdir); -+ set_up_mask_test(testdir); -+ -+ pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1); -+ if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL)) -+ { -+ ok( 0, "RtlDosPathNametoNtPathName_U failed\n" ); -+ goto done; -+ } -+ InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); -+ -+ /* Open a handle for our test directory */ -+ status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, -+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); -+ ok( status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); -+ if (status != STATUS_SUCCESS) -+ { -+ skip("can't test if we can't open the directory\n"); -+ goto done; -+ } -+ -+ /* Verify that updated windows 8 and higher behaviour is supported */ -+ if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, TRUE)) -+ run_updated_tests = FALSE; -+ if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, notatestfile, FALSE, TRUE)) -+ run_updated_tests = FALSE; -+ -+ if (!run_updated_tests) -+ { -+ skip("Win8+ NtQueryDirectoryMask behaviour not supported"); -+ goto done; -+ } -+ -+ /* Run tests - all searches for `notatestfile` are expected to fail */ -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, FALSE); -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, anothertestfile, TRUE, FALSE); -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, notatestfile, FALSE, FALSE); -+ -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, FALSE); -+ test_NtQueryDirectoryFile_mask(dirh, FALSE, notatestfile, FALSE, FALSE); -+ -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, FALSE); -+ /* Since we are not resetting the scan, and are using an incompatible mask, this should also fail */ -+ test_NtQueryDirectoryFile_mask(dirh, FALSE, anothertestfile, FALSE, FALSE); -+ -+ /* Cleanup */ -+done: -+ tear_down_mask_test(testdir); -+} -+ - static NTSTATUS get_file_id( FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name ) - { - OBJECT_ATTRIBUTES attr; -@@ -1157,5 +1320,6 @@ START_TEST(directory) - test_directory_sort( sysdir ); - test_NtQueryDirectoryFile(); - test_NtQueryDirectoryFile_case(); -+ test_NtQueryDirectoryFile_change_mask(); - test_redirection(); - } --- -GitLab - diff --git a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch similarity index 71% rename from 0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch rename to 0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch index d98ceb7..67fb3ef 100644 --- a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0001-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch +++ b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0002-ntdll-Update-NtQueryDirectoryFile-to-purge-cache-if-scan-is-reset-with-a-new-mask.patch @@ -1,15 +1,38 @@ -From 2d3ccc3847589c80a0591418b62d2d0677c71a48 Mon Sep 17 00:00:00 2001 +From 71a97a7ac32cc5aec09fac83588038348c80ca20 Mon Sep 17 00:00:00 2001 From: Eugene McArdle -Date: Fri, 29 Nov 2024 10:32:05 +1000 +Date: Thu, 19 Dec 2024 10:06:34 +1000 Subject: [PATCH] ntdll: Update NtQueryDirectoryFile to purge cache if scan is reset with a new mask --- - dlls/ntdll/unix/file.c | 55 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 53 insertions(+), 2 deletions(-) + dlls/ntdll/tests/directory.c | 3 -- + dlls/ntdll/unix/file.c | 57 ++++++++++++++++++++++++++++++++++-- + 2 files changed, 54 insertions(+), 6 deletions(-) +diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c +index 6aec2ff6408..9d7ed2f4841 100644 +--- a/dlls/ntdll/tests/directory.c ++++ b/dlls/ntdll/tests/directory.c +@@ -1031,7 +1031,6 @@ static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNI + + if (validate_only && status != expected_status) return FALSE; + +- todo_wine + ok( status == expected_status, "unexpected status : 0x%lx Test settings: file mask: '%s', restart: %d, expected status: 0x%lx\n", + status, wine_dbgstr_wn(mask_value, mask_len), restart_scan, expected_status ); + +@@ -1042,9 +1041,7 @@ static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNI + name = dir_info->FileName; + name_len = dir_info->FileNameLength / sizeof(WCHAR); + +- todo_wine + ok( name_len == mask_len, "unexpected filename length %lu, expected %lu\n", name_len, mask_len ); +- todo_wine + ok( !memcmp(name, mask_value, mask_len), "unexpected filename %s, expected %s\n", + wine_dbgstr_wn(name, name_len), wine_dbgstr_wn(mask_value, mask_len) ); + } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index 13dc36b42ff..3baa4aa611d 100644 +index 13dc36b42ff..097aaaca4b9 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -225,6 +225,7 @@ struct dir_data @@ -28,6 +51,15 @@ index 13dc36b42ff..3baa4aa611d 100644 free( data ); } +@@ -1595,7 +1597,7 @@ static BOOL append_entry( struct dir_data *data, const char *long_name, + TRACE( "long %s short %s mask %s\n", + debugstr_w( long_nameW ), debugstr_w( short_nameW ), debugstr_us( mask )); + +- if (mask && !match_filename( long_nameW, long_len, mask )) ++ if (mask && mask->Length !=0 && !match_filename( long_nameW, long_len, mask )) + { + if (!short_len) return TRUE; /* no short name to match */ + if (!match_filename( short_nameW, short_len, mask )) return TRUE; @@ -2606,6 +2608,14 @@ static NTSTATUS init_cached_dir_data( struct dir_data **data_ret, int fd, const return status; } @@ -90,7 +122,7 @@ index 13dc36b42ff..3baa4aa611d 100644 + /* If we have an existing cache entry, but restart_scan is true and a new non-empty mask + was specified then we need to invalidate the existing cache entry and create a new one + */ -+ if (dir_data_cache[entry] && restart_scan && mask && ++ if (dir_data_cache[entry] && restart_scan && mask && mask->Length != 0 && + !ustring_equal(&dir_data_cache[entry]->mask, mask)) + { + TRACE( "invalidating existing cache entry for handle %p, old mask: \"%s\", new mask: \"%s\"\n", diff --git a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0003-ntdll-Add-tests-to-confirm-filemasks-are-tied-to-handles-and-not-directories.patch b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0003-ntdll-Add-tests-to-confirm-filemasks-are-tied-to-handles-and-not-directories.patch deleted file mode 100644 index 8829305..0000000 --- a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0003-ntdll-Add-tests-to-confirm-filemasks-are-tied-to-handles-and-not-directories.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0f3b34247974c7dc9c885b9a33cf9302d4c8d1e9 Mon Sep 17 00:00:00 2001 -From: Eugene McArdle -Date: Fri, 6 Dec 2024 10:39:03 +1000 -Subject: [PATCH] ntdll: Add tests to confirm filemasks are tied to handles and - not directories - ---- - dlls/ntdll/tests/directory.c | 41 +++++++++++++++++++++++++----------- - 1 file changed, 29 insertions(+), 12 deletions(-) - -diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c -index 27027d41d9d..b07654ee1ff 100644 ---- a/dlls/ntdll/tests/directory.c -+++ b/dlls/ntdll/tests/directory.c -@@ -1025,8 +1025,8 @@ static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNI - { - if (validate_only && status != STATUS_SUCCESS) return FALSE; - -- ok( status == STATUS_SUCCESS, "could not find file mask: '%s', restart: %d, error %ld\n", -- wine_dbgstr_wn(mask.Buffer, mask_len), restart_scan, GetLastError() ); -+ ok( status == STATUS_SUCCESS, "could not find file mask: '%s', restart: %d, status 0x%lx\n", -+ wine_dbgstr_wn(mask.Buffer, mask_len), restart_scan, status ); - /* Print the query parameters and the result */ - if (status == 0) { - dir_info = (FILE_DIRECTORY_INFORMATION *)data; -@@ -1058,6 +1058,7 @@ static void test_NtQueryDirectoryFile_change_mask(void) - { - NTSTATUS status; - HANDLE dirh; -+ HANDLE dirh_alt; - char testdir[MAX_PATH]; - OBJECT_ATTRIBUTES attr; - IO_STATUS_BLOCK io; -@@ -1068,8 +1069,6 @@ static void test_NtQueryDirectoryFile_change_mask(void) - UNICODE_STRING anothertestfile; - UNICODE_STRING notatestfile; - -- BOOL run_updated_tests = TRUE; -- - pRtlInitUnicodeString(&atestfile, L"a-file.h"); - pRtlInitUnicodeString(&anothertestfile, L"another-file.h"); - pRtlInitUnicodeString(¬atestfile, L"not-a-file.h"); -@@ -1098,19 +1097,34 @@ static void test_NtQueryDirectoryFile_change_mask(void) - goto done; - } - -+ /* Open a second handle for our test directory */ -+ status = pNtOpenFile(&dirh_alt, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, -+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); -+ ok( status == STATUS_SUCCESS, "failed to open second handle to dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() ); -+ if (status != STATUS_SUCCESS) -+ { -+ skip("can't test if we can't open a second handle to the directory\n"); -+ goto done; -+ } -+ - /* Verify that updated windows 8 and higher behaviour is supported */ -- if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, TRUE)) -- run_updated_tests = FALSE; -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, TRUE); - if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, notatestfile, FALSE, TRUE)) -- run_updated_tests = FALSE; -- -- if (!run_updated_tests) - { -- skip("Win8+ NtQueryDirectoryMask behaviour not supported"); -+ skip("Win8+ NtQueryDirectoryMask behaviour not supported\n"); - goto done; - } - -- /* Run tests - all searches for `notatestfile` are expected to fail */ -+ /* Test that caches for two handles to a single directory do not interfere with each other*/ -+ /* Use dirh to search for a non-existent file, putting it into a state with an empty cache */ -+ test_NtQueryDirectoryFile_mask(dirh, TRUE, notatestfile, FALSE, FALSE); -+ /* Confirm that dirh is in a state where it fails to find atestfile */ -+ test_NtQueryDirectoryFile_mask(dirh, FALSE, atestfile, FALSE, FALSE); -+ /* Confirm that dirh_alt is able to find atestfile */ -+ test_NtQueryDirectoryFile_mask(dirh_alt, FALSE, atestfile, TRUE, FALSE); -+ -+ /* All searches for `notatestfile` are expected to fail */ -+ /* Tests should also fail if the scan is not reset, and the mask changes to an incompatible one */ - test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, FALSE); - test_NtQueryDirectoryFile_mask(dirh, TRUE, anothertestfile, TRUE, FALSE); - test_NtQueryDirectoryFile_mask(dirh, TRUE, notatestfile, FALSE, FALSE); -@@ -1119,12 +1133,15 @@ static void test_NtQueryDirectoryFile_change_mask(void) - test_NtQueryDirectoryFile_mask(dirh, FALSE, notatestfile, FALSE, FALSE); - - test_NtQueryDirectoryFile_mask(dirh, TRUE, atestfile, TRUE, FALSE); -- /* Since we are not resetting the scan, and are using an incompatible mask, this should also fail */ - test_NtQueryDirectoryFile_mask(dirh, FALSE, anothertestfile, FALSE, FALSE); - - /* Cleanup */ - done: - tear_down_mask_test(testdir); -+ pRtlFreeUnicodeString(&ntdirname); -+ pRtlFreeUnicodeString(&atestfile); -+ pRtlFreeUnicodeString(&anothertestfile); -+ pRtlFreeUnicodeString(¬atestfile); - } - - static NTSTATUS get_file_id( FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name ) --- -GitLab - diff --git a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0004-ntdll-Simplify-check-that-unexpected-files-were-not-found.patch b/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0004-ntdll-Simplify-check-that-unexpected-files-were-not-found.patch deleted file mode 100644 index 5d7face..0000000 --- a/0003-pending-mrs-and-backports/6904-ntdll-dll-Update-NtQueryDirectoryFile-to-align-with-current-Windows-behaviour/0004-ntdll-Simplify-check-that-unexpected-files-were-not-found.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8be04266fbc0410f50277d7ed1999dab65ee9735 Mon Sep 17 00:00:00 2001 -From: Eugene McArdle -Date: Mon, 9 Dec 2024 09:28:26 +1000 -Subject: [PATCH] ntdll: Simplify check that unexpected files were not found - ---- - dlls/ntdll/tests/directory.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c -index b07654ee1ff..b98d399d7e2 100644 ---- a/dlls/ntdll/tests/directory.c -+++ b/dlls/ntdll/tests/directory.c -@@ -1041,15 +1041,8 @@ static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNI - else - { - if (validate_only && status == STATUS_SUCCESS) return FALSE; -- /* Print the query parameters and the result */ -- if (status == 0) { -- dir_info = (FILE_DIRECTORY_INFORMATION *)data; -- name = dir_info->FileName; -- name_len = dir_info->FileNameLength / sizeof(WCHAR); -- -- ok ( status != STATUS_SUCCESS, "unexpectedly found file. mask: '%s', found %s\n", -- wine_dbgstr_wn(mask.Buffer, mask_len), wine_dbgstr_wn(name, name_len) ); -- } -+ -+ ok ( status == STATUS_NO_MORE_FILES, "unexpectedly found file\n" ); - } - return TRUE; - } --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch deleted file mode 100644 index 85d7e94..0000000 --- a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0001-winex11-Check-HDC-clipping-region-according-to-window-style.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a97f099b192d4ae49987e9b87808c9ccd5cfefad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 13 Dec 2024 19:30:20 +0100 -Subject: [PATCH] winex11: Check HDC clipping region according to window style. - ---- - dlls/winex11.drv/init.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c -index ddb8101a2f7..b8184e59bb1 100644 ---- a/dlls/winex11.drv/init.c -+++ b/dlls/winex11.drv/init.c -@@ -198,7 +198,7 @@ static BOOL needs_client_window_clipping( HWND hwnd ) - { - struct x11drv_win_data *data; - RECT rect, client; -- UINT ret = 0; -+ UINT ret = 0, clip_flags = 0, style; - HRGN region; - HDC hdc; - -@@ -207,7 +207,11 @@ static BOOL needs_client_window_clipping( HWND hwnd ) - release_win_data( data ); - OffsetRect( &client, -client.left, -client.top ); - -- if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_CLIPCHILDREN ))) return FALSE; -+ style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); -+ if (style & WS_CLIPCHILDREN) clip_flags |= DCX_CLIPCHILDREN; -+ if (style & WS_CLIPSIBLINGS) clip_flags |= DCX_CLIPSIBLINGS; -+ -+ if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | clip_flags ))) return FALSE; - if ((region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) - { - ret = NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI ); --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch b/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch deleted file mode 100644 index faabb40..0000000 --- a/0003-pending-mrs-and-backports/7014-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION/0002-winex11-Move-GL-VK-offscreen-if-the-clipping-region-is-NULLREGION.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 84cf4a9f54e71da29f7919f1a1549d941ff67e8d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 13 Dec 2024 19:30:51 +0100 -Subject: [PATCH] winex11: Move GL/VK offscreen if the clipping region is - NULLREGION. - -NULLREGION means that the entire window should be clipped out, and its -children displayed instead. The change broke some offscreening decisions -when both parent and children have a GL drawable created but drawing -actually happens on the child window. - -Fixes: 786d9d1685ac220081b10cc779d4d331ddd2fc52 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57503 ---- - dlls/winex11.drv/init.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c -index b8184e59bb1..274ed51f585 100644 ---- a/dlls/winex11.drv/init.c -+++ b/dlls/winex11.drv/init.c -@@ -215,7 +215,7 @@ static BOOL needs_client_window_clipping( HWND hwnd ) - if ((region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) - { - ret = NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI ); -- if (ret > 0 && (ret = NtGdiGetRgnBox( region, &rect )) <= NULLREGION) ret = 0; -+ if (ret > 0 && (ret = NtGdiGetRgnBox( region, &rect )) < NULLREGION) ret = 0; - if (ret == SIMPLEREGION && EqualRect( &rect, &client )) ret = 0; - NtGdiDeleteObjectApp( region ); - } --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7016-winex11-drv-Use-NtUserReleaseDC-with-hdc-in-X11DRV-vulkan-surface-presented-/0001-winex11-drv-Use-NtUserReleaseDC-with-hdc.patch b/0003-pending-mrs-and-backports/7016-winex11-drv-Use-NtUserReleaseDC-with-hdc-in-X11DRV-vulkan-surface-presented-/0001-winex11-drv-Use-NtUserReleaseDC-with-hdc.patch deleted file mode 100644 index 87efc3d..0000000 --- a/0003-pending-mrs-and-backports/7016-winex11-drv-Use-NtUserReleaseDC-with-hdc-in-X11DRV-vulkan-surface-presented-/0001-winex11-drv-Use-NtUserReleaseDC-with-hdc.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 6a2af9fc9415a13e82155d96eea3a9440d593fcd Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Fri, 13 Dec 2024 19:28:43 -0600 -Subject: [PATCH] winex11.drv: Use NtUserReleaseDC() with hdc. - ---- - dlls/winex11.drv/init.c | 2 +- - dlls/winex11.drv/vulkan.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c -index ddb8101a2f7..fca673fb825 100644 ---- a/dlls/winex11.drv/init.c -+++ b/dlls/winex11.drv/init.c -@@ -215,7 +215,7 @@ static BOOL needs_client_window_clipping( HWND hwnd ) - if (ret == SIMPLEREGION && EqualRect( &rect, &client )) ret = 0; - NtGdiDeleteObjectApp( region ); - } -- NtGdiDeleteObjectApp( hdc ); -+ NtUserReleaseDC( hwnd, hdc ); - - return ret > 0; - } -diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c -index 12f51fdcefd..855dddba440 100644 ---- a/dlls/winex11.drv/vulkan.c -+++ b/dlls/winex11.drv/vulkan.c -@@ -246,7 +246,7 @@ static void X11DRV_vulkan_surface_presented( HWND hwnd, void *private, VkResult - surface->hdc_src, 0, 0, surface->rect.right, surface->rect.bottom, SRCCOPY, 0 ); - - if (region) NtGdiDeleteObjectApp( region ); -- if (hdc) NtGdiDeleteObjectApp( hdc ); -+ if (hdc) NtUserReleaseDC( hwnd, hdc ); - } - - static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7018-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-/0001-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-.patch b/0003-pending-mrs-and-backports/7018-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-/0001-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-.patch deleted file mode 100644 index c0957c0..0000000 --- a/0003-pending-mrs-and-backports/7018-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-/0001-Revert-wined3d-Use-bindless-textures-for-GLSL-shaders-if-possible-.patch +++ /dev/null @@ -1,529 +0,0 @@ -From 77e8366287bac3c607bbc08c6684187d0fa802eb Mon Sep 17 00:00:00 2001 -From: Elizabeth Figura -Date: Sat, 14 Dec 2024 12:35:38 -0600 -Subject: [PATCH] Revert "wined3d: Use bindless textures for GLSL shaders if - possible." - -This reverts commit f6a1844dbed91b441ad69e7b15b5be242d063e87. - -The use of bindless textures results in several bugs. Some appear to be our -bugs; at least some of these would require us to attempt to keep textures -nonresident when not used, and others have not yet been debugged. Some appear to -be driver bugs or at least exacerbations of existing bugs that are not really -fixable. - -At the same time, separate samplers are a d3d10-level feature, and any -d3d10-level GPU should be capable of supporting Vulkan, which does not use -combined samplers. The Vulkan renderer does not suffer from the problem that the -GL renderer does in this case. - -Put another way, any application that is helped by the original commit should -also be helped by the Vulkan renderer, and if the application in question is -capable of running on a given GPU in the first place then the GPU should in -practice support Vulkan. - -The original commit fixed a clear and definite bug, and thus this revert -reintroduces regressions in some applications, while fixing regressions in -others. The long-term fix for these regressions is to finish the Vulkan renderer -and default to it where possible. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56474 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56523 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56605 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56627 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57409 ---- - dlls/d3d11/tests/d3d11.c | 4 +-- - dlls/wined3d/adapter_gl.c | 15 -------- - dlls/wined3d/context_gl.c | 38 ++------------------- - dlls/wined3d/device.c | 24 ------------- - dlls/wined3d/glsl_shader.c | 70 +------------------------------------- - dlls/wined3d/texture.c | 20 ++++------- - dlls/wined3d/view.c | 39 --------------------- - dlls/wined3d/wined3d_gl.h | 22 ------------ - 8 files changed, 12 insertions(+), 220 deletions(-) - -diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c -index 6d9ad491716..9c5b35faafa 100644 ---- a/dlls/d3d11/tests/d3d11.c -+++ b/dlls/d3d11/tests/d3d11.c -@@ -36183,7 +36183,7 @@ static void test_high_resource_count(void) - ID3D11DeviceContext_PSSetSamplers(context, 0, 2, samplers); - draw_quad(&test_context); - -- check_texture_vec4(rt, &expect, 0); -+ todo_wine_if (!damavand) check_texture_vec4(rt, &expect, 0); - - /* Discard the data in one of the buffers and draw again. */ - -@@ -36195,7 +36195,7 @@ static void test_high_resource_count(void) - ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)buffers[1], 0); - draw_quad(&test_context); - -- check_texture_vec4(rt, &expect2, 0); -+ todo_wine_if (!damavand) check_texture_vec4(rt, &expect2, 0); - - ID3D11Texture2D_Release(rt); - ID3D11RenderTargetView_Release(rtv); -diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c -index c2803379347..1bbafc7957e 100644 ---- a/dlls/wined3d/adapter_gl.c -+++ b/dlls/wined3d/adapter_gl.c -@@ -57,7 +57,6 @@ static const struct wined3d_extension_map gl_extension_map[] = - - /* ARB */ - {"GL_ARB_base_instance", ARB_BASE_INSTANCE }, -- {"GL_ARB_bindless_texture", ARB_BINDLESS_TEXTURE }, - {"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED }, - {"GL_ARB_buffer_storage", ARB_BUFFER_STORAGE }, - {"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT }, -@@ -2048,12 +2047,6 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) - /* GL_ARB_base_instance */ - USE_GL_FUNC(glDrawArraysInstancedBaseInstance) - USE_GL_FUNC(glDrawElementsInstancedBaseVertexBaseInstance) -- /* GL_ARB_bindless_texture */ -- USE_GL_FUNC(glGetTextureHandleARB) -- USE_GL_FUNC(glGetTextureSamplerHandleARB) -- USE_GL_FUNC(glIsTextureHandleResidentARB) -- USE_GL_FUNC(glMakeTextureHandleResidentARB) -- USE_GL_FUNC(glUniformHandleui64ARB) - /* GL_ARB_blend_func_extended */ - USE_GL_FUNC(glBindFragDataLocationIndexed) - USE_GL_FUNC(glGetFragDataIndex) -@@ -3540,14 +3533,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter_gl *adapter_gl, - /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */ - gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE; - } -- if (wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) -- { -- /* ARB_bindless_texture does not let us use EXT_texture_sRGB_decode. -- * We could use ARB_texture_view, but the main reason to use bindless -- * textures is to avoid GL_MAX_TEXTURE_IMAGE_UNITS, so there's not much -- * point. */ -- gl_info->supported[ARB_BINDLESS_TEXTURE] = FALSE; -- } - if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - { - /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode -diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c -index 46bb3f9f365..e150e2bdec6 100644 ---- a/dlls/wined3d/context_gl.c -+++ b/dlls/wined3d/context_gl.c -@@ -2552,37 +2552,6 @@ void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl, GLen - checkGLcall("bind texture"); - } - --GLuint64 wined3d_device_gl_get_dummy_bindless_handle(const struct wined3d_device_gl *device_gl, -- enum wined3d_shader_resource_type type) --{ -- switch (type) -- { -- case WINED3D_SHADER_RESOURCE_BUFFER: -- return device_gl->dummy_textures.bindless.tex_buffer; -- case WINED3D_SHADER_RESOURCE_TEXTURE_1D: -- return device_gl->dummy_textures.bindless.tex_1d; -- case WINED3D_SHADER_RESOURCE_TEXTURE_2D: -- return device_gl->dummy_textures.bindless.tex_2d; -- case WINED3D_SHADER_RESOURCE_TEXTURE_3D: -- return device_gl->dummy_textures.bindless.tex_3d; -- case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: -- return device_gl->dummy_textures.bindless.tex_cube; -- case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY: -- return device_gl->dummy_textures.bindless.tex_1d_array; -- case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: -- return device_gl->dummy_textures.bindless.tex_2d_array; -- case WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY: -- return device_gl->dummy_textures.bindless.tex_cube_array; -- case WINED3D_SHADER_RESOURCE_TEXTURE_2DMS: -- return device_gl->dummy_textures.bindless.tex_2d_ms; -- case WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY: -- return device_gl->dummy_textures.bindless.tex_2d_ms_array; -- default: -- FIXME("Unhandled resource type %#x.\n", type); -- return 0; -- } --} -- - static void wined3d_context_gl_poll_fences(struct wined3d_context_gl *context_gl) - { - struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); -@@ -3803,9 +3772,6 @@ static void wined3d_context_gl_bind_shader_resources(struct wined3d_context_gl * - return; - } - -- if (gl_info->supported[ARB_BINDLESS_TEXTURE]) -- return; -- - tex_unit_map = wined3d_context_gl_get_tex_unit_mapping(context_gl, - &shader->reg_maps.shader_version, &base, &count); - -@@ -4167,6 +4133,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, - { - for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) - wined3d_context_gl_bind_shader_resources(context_gl, state, i); -+ context->update_shader_resource_bindings = 0; - if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) - context->update_compute_shader_resource_bindings = 1; - } -@@ -4185,7 +4152,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, - device->shader_backend->shader_apply_draw_state(device->shader_priv, context, state); - context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; - context->constant_update_mask = 0; -- context->update_shader_resource_bindings = 0; - - context->last_was_blit = FALSE; - context->last_was_ffp_blit = FALSE; -@@ -4222,6 +4188,7 @@ static void wined3d_context_gl_apply_compute_state(struct wined3d_context_gl *co - if (context_gl->c.update_compute_shader_resource_bindings) - { - wined3d_context_gl_bind_shader_resources(context_gl, state, WINED3D_SHADER_TYPE_COMPUTE); -+ context_gl->c.update_compute_shader_resource_bindings = 0; - if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) - context_gl->c.update_shader_resource_bindings = 1; - } -@@ -4248,7 +4215,6 @@ static void wined3d_context_gl_apply_compute_state(struct wined3d_context_gl *co - context_gl->c.last_was_blit = FALSE; - context_gl->c.last_was_ffp_blit = FALSE; - context_gl->c.shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE); -- context_gl->c.update_compute_shader_resource_bindings = 0; - } - - void wined3d_context_gl_end_transform_feedback(struct wined3d_context_gl *context_gl) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 7e24de8afb3..503b377662a 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -568,18 +568,6 @@ out: - if (hbm) DeleteObject(hbm); - } - --static GLuint64 create_dummy_bindless_handle(const struct wined3d_gl_info *gl_info, GLuint texture) --{ -- GLuint64 handle; -- -- if (!texture || !gl_info->supported[ARB_BINDLESS_TEXTURE]) -- return 0; -- -- handle = GL_EXTCALL(glGetTextureHandleARB(texture)); -- GL_EXTCALL(glMakeTextureHandleResidentARB(handle)); -- return handle; --} -- - /* Context activation is done by the caller. */ - static void wined3d_device_gl_create_dummy_textures(struct wined3d_device_gl *device_gl, - struct wined3d_context_gl *context_gl) -@@ -701,18 +689,6 @@ static void wined3d_device_gl_create_dummy_textures(struct wined3d_device_gl *de - } - } - -- textures->bindless.tex_1d = create_dummy_bindless_handle(gl_info, textures->tex_1d); -- textures->bindless.tex_2d = create_dummy_bindless_handle(gl_info, textures->tex_2d); -- textures->bindless.tex_rect = create_dummy_bindless_handle(gl_info, textures->tex_rect); -- textures->bindless.tex_3d = create_dummy_bindless_handle(gl_info, textures->tex_3d); -- textures->bindless.tex_cube = create_dummy_bindless_handle(gl_info, textures->tex_cube); -- textures->bindless.tex_cube_array = create_dummy_bindless_handle(gl_info, textures->tex_cube_array); -- textures->bindless.tex_1d_array = create_dummy_bindless_handle(gl_info, textures->tex_1d_array); -- textures->bindless.tex_2d_array = create_dummy_bindless_handle(gl_info, textures->tex_2d_array); -- textures->bindless.tex_buffer = create_dummy_bindless_handle(gl_info, textures->tex_buffer); -- textures->bindless.tex_2d_ms = create_dummy_bindless_handle(gl_info, textures->tex_2d_ms); -- textures->bindless.tex_2d_ms_array = create_dummy_bindless_handle(gl_info, textures->tex_2d_ms_array); -- - checkGLcall("create dummy textures"); - - wined3d_context_gl_bind_dummy_textures(context_gl); -diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index 61b53da540a..5856aae5447 100644 ---- a/dlls/wined3d/glsl_shader.c -+++ b/dlls/wined3d/glsl_shader.c -@@ -2611,9 +2611,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c - break; - } - -- if (gl_info->supported[ARB_BINDLESS_TEXTURE]) -- shader_addline(buffer, "layout(bindless_sampler) "); -- else if (shader_glsl_use_layout_binding_qualifier(gl_info)) -+ if (shader_glsl_use_layout_binding_qualifier(gl_info)) - shader_glsl_append_sampler_binding_qualifier(buffer, &context_gl->c, version, entry->bind_idx); - shader_addline(buffer, "uniform %s%s %s_sampler%u;\n", - sampler_type_prefix, sampler_type, prefix, entry->bind_idx); -@@ -7710,8 +7708,6 @@ static void shader_glsl_generate_colour_key_test(struct wined3d_string_buffer *b - static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, - const struct wined3d_gl_info *gl_info) - { -- if (gl_info->supported[ARB_BINDLESS_TEXTURE]) -- shader_addline(buffer, "#extension GL_ARB_bindless_texture : enable\n"); - if (gl_info->supported[ARB_CULL_DISTANCE]) - shader_addline(buffer, "#extension GL_ARB_cull_distance : enable\n"); - if (gl_info->supported[ARB_GPU_SHADER5]) -@@ -9814,7 +9810,6 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * - } - if (sampler_type) - { -- /* We don't use bindless samplers for FFP shaders. */ - if (shader_glsl_use_layout_binding_qualifier(gl_info)) - shader_glsl_append_sampler_binding_qualifier(buffer, &context_gl->c, NULL, stage); - shader_addline(buffer, "uniform sampler%s ps_sampler%u;\n", sampler_type, stage); -@@ -10884,60 +10879,6 @@ static void shader_glsl_update_graphics_program(struct shader_glsl_priv *priv, - context_gl->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE); - } - --static void shader_glsl_load_bindless_samplers(struct shader_glsl_priv *priv, struct wined3d_context_gl *context_gl, -- const struct wined3d_state *state, enum wined3d_shader_type shader_type) --{ -- const struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); -- const struct glsl_context_data *ctx_data = context_gl->c.shader_backend_data; -- const struct wined3d_shader *shader = state->shader[shader_type]; -- const struct wined3d_gl_info *gl_info = context_gl->gl_info; -- const char *prefix = shader_glsl_get_prefix(shader_type); -- struct wined3d_string_buffer *sampler_name; -- -- /* Note that we don't use bindless samplers for FFP shaders. */ -- if (!shader) -- return; -- -- sampler_name = string_buffer_get(&priv->string_buffers); -- -- for (unsigned int i = 0; i < shader->reg_maps.sampler_map.count; ++i) -- { -- const struct wined3d_shader_sampler_map_entry *entry = &shader->reg_maps.sampler_map.entries[i]; -- struct wined3d_shader_resource_view *view; -- struct wined3d_sampler *sampler; -- GLuint64 handle; -- GLint name_loc; -- -- /* No need to bother with the texture unit map; we're binding directly to uniforms. */ -- -- string_buffer_sprintf(sampler_name, "%s_sampler%u", prefix, entry->bind_idx); -- name_loc = GL_EXTCALL(glGetUniformLocation(ctx_data->glsl_program->id, sampler_name->buffer)); -- if (name_loc == -1) -- continue; -- -- if ((view = state->shader_resource_view[shader_type][entry->resource_idx])) -- { -- if (entry->sampler_idx == WINED3D_SAMPLER_DEFAULT) -- sampler = device_gl->d.default_sampler; -- else if (!(sampler = state->sampler[shader_type][entry->sampler_idx])) -- sampler = device_gl->d.null_sampler; -- -- handle = wined3d_shader_resource_view_gl_get_bindless_handle( -- wined3d_shader_resource_view_gl(view), wined3d_sampler_gl(sampler), context_gl); -- } -- else -- { -- WARN("No resource view bound at index %u, %u.\n", shader_type, entry->resource_idx); -- handle = wined3d_device_gl_get_dummy_bindless_handle(device_gl, -- shader->reg_maps.resource_info[entry->resource_idx].type); -- } -- GL_EXTCALL(glUniformHandleui64ARB(name_loc, handle)); -- checkGLcall("glUniformHandleui64ARB"); -- } -- -- string_buffer_release(&priv->string_buffers, sampler_name); --} -- - static void shader_glsl_apply_draw_state(void *shader_priv, struct wined3d_context *context, - const struct wined3d_state *state) - { -@@ -10949,12 +10890,6 @@ static void shader_glsl_apply_draw_state(void *shader_priv, struct wined3d_conte - - if (context->constant_update_mask) - shader_glsl_load_constants(priv, context, state); -- -- if (context->update_shader_resource_bindings && context_gl->gl_info->supported[ARB_BINDLESS_TEXTURE]) -- { -- for (unsigned int type = 0; type < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++type) -- shader_glsl_load_bindless_samplers(priv, context_gl, state, type); -- } - } - - static void shader_glsl_update_compute_program(struct shader_glsl_priv *priv, -@@ -10991,9 +10926,6 @@ static void shader_glsl_apply_compute_state(void *shader_priv, struct wined3d_co - - if (context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE)) - shader_glsl_update_compute_program(priv, context_gl, state); -- -- if (context->update_compute_shader_resource_bindings && context_gl->gl_info->supported[ARB_BINDLESS_TEXTURE]) -- shader_glsl_load_bindless_samplers(priv, context_gl, state, WINED3D_SHADER_TYPE_COMPUTE); - } - - /* "context" is not necessarily the currently active context. */ -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 27fedf4db67..5061f0033fd 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -1285,8 +1285,8 @@ void wined3d_gl_texture_swizzle_from_color_fixup(GLint swizzle[4], struct color_ - } - - /* Context activation is done by the caller. */ --GLuint wined3d_texture_gl_prepare_gl_texture(struct wined3d_texture_gl *texture_gl, -- struct wined3d_context_gl *context_gl, BOOL srgb) -+void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, -+ struct wined3d_context_gl *context_gl, BOOL srgb) - { - const struct wined3d_format *format = texture_gl->t.resource.format; - const struct wined3d_gl_info *gl_info = context_gl->gl_info; -@@ -1309,7 +1309,10 @@ GLuint wined3d_texture_gl_prepare_gl_texture(struct wined3d_texture_gl *texture_ - target = texture_gl->target; - - if (gl_tex->name) -- return gl_tex->name; -+ { -+ wined3d_context_gl_bind_texture(context_gl, target, gl_tex->name); -+ return; -+ } - - gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name); - checkGLcall("glGenTextures"); -@@ -1318,7 +1321,7 @@ GLuint wined3d_texture_gl_prepare_gl_texture(struct wined3d_texture_gl *texture_ - if (!gl_tex->name) - { - ERR("Failed to generate a texture name.\n"); -- return 0; -+ return; - } - - /* Initialise the state of the texture object to the OpenGL defaults, not -@@ -1396,8 +1399,6 @@ GLuint wined3d_texture_gl_prepare_gl_texture(struct wined3d_texture_gl *texture_ - gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - checkGLcall("set format swizzle"); - } -- -- return gl_tex->name; - } - - /* Context activation is done by the caller. */ -@@ -1412,13 +1413,6 @@ void wined3d_texture_gl_bind_and_dirtify(struct wined3d_texture_gl *texture_gl, - wined3d_texture_gl_bind(texture_gl, context_gl, srgb); - } - --void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, -- struct wined3d_context_gl *context_gl, BOOL srgb) --{ -- wined3d_context_gl_bind_texture(context_gl, texture_gl->target, -- wined3d_texture_gl_prepare_gl_texture(texture_gl, context_gl, srgb)); --} -- - /* Context activation is done by the caller (state handler). */ - /* This function relies on the correct texture being bound and loaded. */ - void wined3d_texture_gl_apply_sampler_desc(struct wined3d_texture_gl *texture_gl, -diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c -index 91b88c2037d..c72e5044d04 100644 ---- a/dlls/wined3d/view.c -+++ b/dlls/wined3d/view.c -@@ -270,14 +270,6 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c - { - gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); - } -- else if (gl_info->supported[ARB_BINDLESS_TEXTURE]) -- { -- /* If we already bound this view to a shader, we acquired a handle to -- * it, and it's now immutable. This means we can't bind a new buffer -- * storage to it, so recreate the texture. */ -- gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->name); -- gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); -- } - - wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name); - if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) -@@ -1317,37 +1309,6 @@ static void shader_resource_view_gl_bind_and_dirtify(struct wined3d_shader_resou - wined3d_context_gl_bind_texture(context_gl, view_gl->gl_view.target, view_gl->gl_view.name); - } - --GLuint64 wined3d_shader_resource_view_gl_get_bindless_handle(struct wined3d_shader_resource_view_gl *view_gl, -- struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl) --{ -- const struct wined3d_gl_info *gl_info = context_gl->gl_info; -- GLuint64 handle; -- GLuint name; -- -- if (view_gl->gl_view.name) -- { -- name = view_gl->gl_view.name; -- } -- else if (view_gl->v.resource->type == WINED3D_RTYPE_BUFFER) -- { -- FIXME("Buffer shader resources not supported.\n"); -- return 0; -- } -- else -- { -- struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(view_gl->v.resource)); -- name = wined3d_texture_gl_prepare_gl_texture(texture_gl, context_gl, FALSE); -- } -- -- handle = GL_EXTCALL(glGetTextureSamplerHandleARB(name, sampler_gl->name)); -- checkGLcall("glGetTextureSamplerHandleARB"); -- /* It is an error to make a handle resident if it is already resident. */ -- if (!GL_EXTCALL(glIsTextureHandleResidentARB(handle))) -- GL_EXTCALL(glMakeTextureHandleResidentARB(handle)); -- checkGLcall("glMakeTextureHandleResidentARB"); -- return handle; --} -- - void wined3d_shader_resource_view_gl_generate_mipmap(struct wined3d_shader_resource_view_gl *view_gl, - struct wined3d_context_gl *context_gl) - { -diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h -index 039f652adb9..24d7ebf663b 100644 ---- a/dlls/wined3d/wined3d_gl.h -+++ b/dlls/wined3d/wined3d_gl.h -@@ -51,7 +51,6 @@ enum wined3d_gl_extension - APPLE_YCBCR_422, - /* ARB */ - ARB_BASE_INSTANCE, -- ARB_BINDLESS_TEXTURE, - ARB_BLEND_FUNC_EXTENDED, - ARB_BUFFER_STORAGE, - ARB_CLEAR_BUFFER_OBJECT, -@@ -841,21 +840,6 @@ struct wined3d_dummy_textures - GLuint tex_buffer; - GLuint tex_2d_ms; - GLuint tex_2d_ms_array; -- -- struct -- { -- GLuint64 tex_1d; -- GLuint64 tex_2d; -- GLuint64 tex_rect; -- GLuint64 tex_3d; -- GLuint64 tex_cube; -- GLuint64 tex_cube_array; -- GLuint64 tex_1d_array; -- GLuint64 tex_2d_array; -- GLuint64 tex_buffer; -- GLuint64 tex_2d_ms; -- GLuint64 tex_2d_ms_array; -- } bindless; - }; - - struct wined3d_device_gl -@@ -919,8 +903,6 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, - void wined3d_device_gl_create_primary_opengl_context_cs(void *object); - void wined3d_device_gl_delete_opengl_contexts_cs(void *object); - HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl); --GLuint64 wined3d_device_gl_get_dummy_bindless_handle(const struct wined3d_device_gl *device_gl, -- enum wined3d_shader_resource_type type); - GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx); - - GLbitfield wined3d_resource_gl_map_flags(const struct wined3d_bo_gl *bo, DWORD d3d_flags); -@@ -1037,8 +1019,6 @@ void wined3d_texture_gl_bind_and_dirtify(struct wined3d_texture_gl *texture_gl, - HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, struct wined3d_device *device, - const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, - uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops); --GLuint wined3d_texture_gl_prepare_gl_texture(struct wined3d_texture_gl *texture_gl, -- struct wined3d_context_gl *context_gl, BOOL srgb); - void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl, - struct wined3d_context_gl *context_gl, BOOL srgb); - void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl, -@@ -1113,8 +1093,6 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl - struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl); - void wined3d_shader_resource_view_gl_generate_mipmap(struct wined3d_shader_resource_view_gl *srv_gl, - struct wined3d_context_gl *context_gl); --GLuint64 wined3d_shader_resource_view_gl_get_bindless_handle(struct wined3d_shader_resource_view_gl *view_gl, -- struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl); - HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl, - const struct wined3d_view_desc *desc, struct wined3d_resource *resource, - void *parent, const struct wined3d_parent_ops *parent_ops); --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7021-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side/0001-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side.patch b/0003-pending-mrs-and-backports/7021-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side/0001-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side.patch deleted file mode 100644 index 5f20e90..0000000 --- a/0003-pending-mrs-and-backports/7021-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side/0001-wined3d-Add-nop-state-entries-for-states-now-invalidated-on-the-client-side.patch +++ /dev/null @@ -1,168 +0,0 @@ -From ba2851966b4f2045f2da7bb354d5a60483b15609 Mon Sep 17 00:00:00 2001 -From: Elizabeth Figura -Date: Sat, 14 Dec 2024 17:18:07 -0600 -Subject: [PATCH] wined3d: Add nop state entries for states now invalidated on - the client side. - -9313c14c63a9b941b66ea367b72f0f928e39c68b and following commits moved invalidation to the client side of the CS, and removed the state table entries since nothing needed to be done. -However, in order to avoid errors, the state table still validates that all states have a representative, and thus complains at the missing representatives for all of these states. -Avoid this by adding state_nop entries, as is done in some other places. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57207 ---- - dlls/wined3d/ffp_gl.c | 11 +++-- - dlls/wined3d/glsl_shader.c | 92 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 99 insertions(+), 4 deletions(-) - -diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c -index 20f9828d0a2..9012ba2215e 100644 ---- a/dlls/wined3d/ffp_gl.c -+++ b/dlls/wined3d/ffp_gl.c -@@ -1653,10 +1653,13 @@ static void validate_state_table(struct wined3d_state_entry *state_table) - { 11, 14}, - { 16, 23}, - { 27, 27}, -- { 29, 33}, -- { 39, 135}, -- {137, 139}, -- {141, 151}, -+ { 30, 33}, -+ { 39, 40}, -+ { 42, 47}, -+ { 49, 135}, -+ {138, 139}, -+ {144, 144}, -+ {149, 150}, - {153, 153}, - {157, 160}, - {162, 165}, -diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index 61b53da540a..b94ba5ac373 100644 ---- a/dlls/wined3d/glsl_shader.c -+++ b/dlls/wined3d/glsl_shader.c -@@ -12005,9 +12005,20 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = - /* Viewport */ - {STATE_VIEWPORT, {STATE_VIEWPORT, glsl_vertex_pipe_viewport}, WINED3D_GL_EXT_NONE }, - /* Fog */ -+ {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, -@@ -12018,6 +12029,14 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = - {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_shademode}, WINED3D_GLSL_130 }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_nop }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE }, - }; - -@@ -12267,6 +12286,7 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa - {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), glsl_fragment_pipe_core_alpha_test_ref }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), glsl_fragment_pipe_alpha_test }, WINED3D_GL_LEGACY_CONTEXT}, - {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), glsl_fragment_pipe_core_alpha_test }, WINED3D_GL_EXT_NONE }, -+ {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, -@@ -12278,6 +12298,78 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa - {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, ARB_POINT_SPRITE }, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, WINED3D_GL_VERSION_2_0}, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, -+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7026-win32u-Always-update-the-surface-region-when-the-surface-changes/0001-win32u-Always-update-the-surface-region-when-the-surface-changes.patch b/0003-pending-mrs-and-backports/7026-win32u-Always-update-the-surface-region-when-the-surface-changes/0001-win32u-Always-update-the-surface-region-when-the-surface-changes.patch deleted file mode 100644 index 5b9a370..0000000 --- a/0003-pending-mrs-and-backports/7026-win32u-Always-update-the-surface-region-when-the-surface-changes/0001-win32u-Always-update-the-surface-region-when-the-surface-changes.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d5f8bedec11d7d72e8312bc1302aad943f0bd054 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 16 Dec 2024 11:19:14 +0100 -Subject: [PATCH] win32u: Always update the surface region when the surface - changes. - -Instead of reapplying the old shape, which not only includes the window -shape but also the old clipping and visible areas that can change -independently. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57551 ---- - dlls/win32u/window.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c -index 4855555d926..d8974501adb 100644 ---- a/dlls/win32u/window.c -+++ b/dlls/win32u/window.c -@@ -2066,7 +2066,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru - old_surface = win->surface; - if (old_surface != new_surface) - { -- if (old_surface && new_surface) window_surface_set_shape( new_surface, old_surface->shape_region ); -+ needs_update = TRUE; /* force refreshing the window surface shape */ - swp_flags |= SWP_FRAMECHANGED; /* force refreshing non-client area */ - } - -@@ -2112,7 +2112,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru - win->rects = *new_rects; - if ((win->surface = new_surface)) window_surface_add_ref( win->surface ); - surface_win = wine_server_ptr_handle( reply->surface_win ); -- needs_update = reply->needs_update; -+ if (!needs_update) needs_update = reply->needs_update; - if (get_window_long( win->parent, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - { - RECT client = {0}; --- -GitLab - diff --git a/0003-pending-mrs-and-backports/7064-Draft-ntdll-Check-for-invalid-GS-base-in-the-64-bit-segv-handler/0001-ntdll-Check-for-invalid-gs-value-in-32-bit-code-on-WoW64.patch b/0003-pending-mrs-and-backports/7064-Draft-ntdll-Check-for-invalid-GS-base-in-the-64-bit-segv-handler/0001-ntdll-Check-for-invalid-gs-value-in-32-bit-code-on-WoW64.patch new file mode 100644 index 0000000..3b79d56 --- /dev/null +++ b/0003-pending-mrs-and-backports/7064-Draft-ntdll-Check-for-invalid-GS-base-in-the-64-bit-segv-handler/0001-ntdll-Check-for-invalid-gs-value-in-32-bit-code-on-WoW64.patch @@ -0,0 +1,151 @@ +From c1b0461f3fdd6281742e7c8880b8ac85ccf6cd0b Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Sun, 22 Dec 2024 04:22:32 -0800 +Subject: [PATCH] ntdll: Check for invalid %gs value in 32-bit code on WoW64. + +Adapted from check_invalid_gs in signal_i386.c. This prevents +crashing when the %gs register is manipulated. An example of this +can be seen in the game "Exertus: Darkness Approaches", which crashes +in 32-bit code when using "new-style" WoW64. + +The SYSCALL_HAVE_WRFSGSBASE fast-path for getting/setting the segment +registers on Linux is already checked in signal_init_process, and +the other platforms' implementations follow existing conventions. + +Also note that we check in the TRAP_x86_PAGEFLT case because +the error occurs when the invalid %gs value is actually used. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57444 +--- + dlls/ntdll/unix/signal_x86_64.c | 108 ++++++++++++++++++++++++++++++++ + 1 file changed, 108 insertions(+) + +diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c +index caa85249896..5a39e4a0fa6 100644 +--- a/dlls/ntdll/unix/signal_x86_64.c ++++ b/dlls/ntdll/unix/signal_x86_64.c +@@ -1967,6 +1967,109 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext, siginfo_t *siginfo ) + } + + ++/*********************************************************************** ++ * check_invalid_gsbase ++ * ++ * Check for fault caused by invalid %gs value (some copy protection schemes mess with it). ++ * ++ */ ++static inline BOOL check_invalid_gsbase( ucontext_t *sigcontext, CONTEXT *context ) ++{ ++ unsigned int prefix_count = 0; ++ const BYTE *instr = (const BYTE *)context->Rip; ++ ULONG_PTR cur_gsbase = 0; ++ TEB *teb; ++ ++ if (CS_sig(sigcontext) != cs64_sel) return FALSE; ++ /* FIXME: breaks on linux 64-bit code and macOS 32- or 64-bit code ++ if (virtual_is_valid_code_address( instr, 1 )) return FALSE; ++ */ ++ ++#ifdef __linux__ ++ if (syscall_flags & SYSCALL_HAVE_WRFSGSBASE) ++ __asm__ volatile ("rdgsbase %0" : "=r" (cur_gsbase)); ++ else ++ arch_prctl( ARCH_GET_GS, &cur_gsbase ); ++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) ++ amd64_get_gsbase( &cur_gsbase ); ++#elif defined(__NetBSD__) ++ sysarch( X86_64_GET_GSBASE, &cur_gsbase ); ++#elif defined(__APPLE__) ++ /* FIXME */ ++#else ++# error Please define getting %gs for your architecture ++#endif ++ ++ teb = NtCurrentTeb(); ++ if (cur_gsbase == (ULONG_PTR)teb) return FALSE; ++ ++ for (;;) ++ { ++ switch(*instr) ++ { ++ /* instruction prefixes */ ++ case 0x2e: /* %cs: */ ++ case 0x36: /* %ss: */ ++ case 0x3e: /* %ds: */ ++ case 0x26: /* %es: */ ++ case 0x40: /* rex */ ++ case 0x41: /* rex */ ++ case 0x42: /* rex */ ++ case 0x43: /* rex */ ++ case 0x44: /* rex */ ++ case 0x45: /* rex */ ++ case 0x46: /* rex */ ++ case 0x47: /* rex */ ++ case 0x48: /* rex */ ++ case 0x49: /* rex */ ++ case 0x4a: /* rex */ ++ case 0x4b: /* rex */ ++ case 0x4c: /* rex */ ++ case 0x4d: /* rex */ ++ case 0x4e: /* rex */ ++ case 0x4f: /* rex */ ++ case 0x64: /* %fs: */ ++ case 0x66: /* opcode size */ ++ case 0x67: /* addr size */ ++ case 0xf0: /* lock */ ++ case 0xf2: /* repne */ ++ case 0xf3: /* repe */ ++ if (++prefix_count >= 15) return FALSE; ++ instr++; ++ continue; ++ case 0x65: /* %gs: */ ++ GS_sig(sigcontext) = ds64_sel; ++ break; ++ default: ++ return FALSE; ++ } ++ break; /* %gs: */ ++ } ++ ++ TRACE( "%016lx/%p at %p, fixing up\n", cur_gsbase, teb, instr ); ++ ++#ifdef __linux__ ++ if (syscall_flags & SYSCALL_HAVE_WRFSGSBASE) ++ __asm__ volatile ("wrgsbase %0" :: "r" (teb)); ++ else ++ arch_prctl( ARCH_SET_GS, teb ); ++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) ++ amd64_set_gsbase( teb ); ++#elif defined(__NetBSD__) ++ sysarch( X86_64_SET_GSBASE, &teb ); ++#elif defined(__APPLE__) ++ __asm__ volatile ("movq %0,%%gs:%c1" :: "r" (teb->Tib.Self), ++ "n" (FIELD_OFFSET(TEB, Tib.Self))); ++ __asm__ volatile ("movq %0,%%gs:%c1" :: "r" (teb->ThreadLocalStoragePointer), ++ "n" (FIELD_OFFSET(TEB, ThreadLocalStoragePointer))); ++#else ++# error Please define setting %gs for your architecture ++#endif ++ ++ return TRUE; ++} ++ ++ + /********************************************************************** + * segv_handler + * +@@ -2025,6 +2128,11 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) + /* send EXCEPTION_EXECUTE_FAULT only if data execution prevention is enabled */ + if (!(flags & MEM_EXECUTE_OPTION_DISABLE)) rec.ExceptionInformation[0] = EXCEPTION_READ_FAULT; + } ++ if (check_invalid_gsbase( ucontext, &context.c )) ++ { ++ leave_handler( ucontext ); ++ return; ++ } + break; + case TRAP_x86_ALIGNFLT: /* Alignment check exception */ + if (EFL_sig(ucontext) & 0x00040000) +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0001-winex11-Improve-GetWindowStateUpdates-traces.patch b/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0001-winex11-Improve-GetWindowStateUpdates-traces.patch new file mode 100644 index 0000000..c9c6345 --- /dev/null +++ b/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0001-winex11-Improve-GetWindowStateUpdates-traces.patch @@ -0,0 +1,34 @@ +From 1550256217df46166321ded756f3043655dbd639 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Tue, 24 Dec 2024 12:58:40 +0100 +Subject: [PATCH] winex11: Improve GetWindowStateUpdates traces. + +--- + dlls/winex11.drv/window.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c +index bf415f19cb9..1d43c4edbdb 100644 +--- a/dlls/winex11.drv/window.c ++++ b/dlls/winex11.drv/window.c +@@ -1622,8 +1622,6 @@ BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, + { + struct x11drv_win_data *data; + +- TRACE( "hwnd %p, state_cmd %p, config_cmd %p, rect %p\n", hwnd, state_cmd, config_cmd, rect ); +- + if (!(data = get_win_data( hwnd ))) return FALSE; + + *state_cmd = window_update_client_state( data ); +@@ -1632,7 +1630,7 @@ BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, + + release_win_data( data ); + +- TRACE( "returning state_cmd %#x, config_cmd %#x, rect %s\n", *state_cmd, *config_cmd, wine_dbgstr_rect(rect) ); ++ TRACE( "hwnd %p, returning state_cmd %#x, config_cmd %#x, rect %s\n", hwnd, *state_cmd, *config_cmd, wine_dbgstr_rect(rect) ); + return *state_cmd || *config_cmd; + } + +-- +GitLab + diff --git a/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0002-win32u-Check-window-state-updates-again-after-applying-new-state.patch b/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0002-win32u-Check-window-state-updates-again-after-applying-new-state.patch new file mode 100644 index 0000000..67ce4ef --- /dev/null +++ b/0003-pending-mrs-and-backports/7072-win32u-Check-window-state-updates-again-after-applying-new-state/0002-win32u-Check-window-state-updates-again-after-applying-new-state.patch @@ -0,0 +1,37 @@ +From 38e78439da525d1cd51e6c94aa424eb2c87c45ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Tue, 24 Dec 2024 12:58:54 +0100 +Subject: [PATCH] win32u: Check window state updates again after applying new + state. + +The state change might have applied the new config already, or might +have triggered some new requests which would override the new config. + +It's also necessary to call again to compute the visible rect from the +window rect after taking the new state into account. Minimized windows +have a different window / visible rect offset than normal windows for +instance. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57577 +--- + dlls/win32u/message.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c +index d8da5a0f48f..2f1e14c82c8 100644 +--- a/dlls/win32u/message.c ++++ b/dlls/win32u/message.c +@@ -2136,6 +2136,10 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR + { + if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); + send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); ++ ++ /* state change might have changed the window config already, check again */ ++ user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &config_cmd, &window_rect ); ++ if (state_cmd) WARN( "window %p state needs another update, ignoring\n", hwnd ); + } + if (config_cmd) + { +-- +GitLab + diff --git a/0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers-and-align-stack.patch b/0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers.patch similarity index 71% rename from 0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers-and-align-stack.patch rename to 0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers.patch index d350e6c..8abab0a 100644 --- a/0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers-and-align-stack.patch +++ b/0004-build-fix-undebug-optimize/2000-configure.ac-Omit-frame-pointers.patch @@ -1,13 +1,6 @@ -From 2303f24ee7fb119d9ab3dad1fb6eff3cf911b1ee Mon Sep 17 00:00:00 2001 From: William Horvath Date: Sat, 5 Oct 2024 06:34:55 -0700 -Subject: [PATCH v2] configure.ac: Omit frame pointers and align stack on clang. - -Align the stack to 4 bytes for PE targets on clang, same as -mpreferred-stack-boundary=2 for gcc. -The previous version of this patch incorrectly used -mstack-alignment=2, but clang interprets this -as "n" bytes, while gcc uses "2^n" bytes. - -https://linux.kernel.narkive.com/y7hAplfS/patch-x86-build-specify-stack-alignment-for-clang +Subject: [PATCH] configure.ac: Omit frame pointers. --- diff --git a/configure.ac b/configure.ac @@ -22,18 +15,17 @@ index 11111111111..11111111111 100644 dnl clang had broken -fms-hotpatch support before version 18 (https://github.com/llvm/llvm-project/pull/77245) WINE_TRY_PE_CFLAGS([-fms-hotpatch -DMIN_CLANG_VERSION=18], -@@ -973,8 +974,8 @@ This is an error since --enable-archs=$wine_arch was requested.])]) +@@ -973,8 +974,7 @@ This is an error since --enable-archs=$wine_arch was requested.])]) WINE_TRY_PE_CFLAGS([-flarge-source-files -Wmisleading-indentation],[AS_VAR_APPEND(${wine_arch}_EXTRACFLAGS,[" -Wno-misleading-indentation"])]) case $wine_arch in - i386) WINE_TRY_PE_CFLAGS([-fno-omit-frame-pointer]) - WINE_TRY_PE_CFLAGS([-mpreferred-stack-boundary=2]) -+ i386) WINE_TRY_PE_CFLAGS([-mstack-alignment=4]) -+ WINE_TRY_PE_CFLAGS([-mpreferred-stack-boundary=2]) ++ i386) WINE_TRY_PE_CFLAGS([-mpreferred-stack-boundary=2]) WINE_TRY_PE_CFLAGS([-Wl,--disable-stdcall-fixup], [AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -Wl,--disable-stdcall-fixup"])]) ;; x86_64) WINE_TRY_PE_CFLAGS([-Wformat-overflow]) -@@ -1968,7 +1969,6 @@ then +@@ -1968,7 +1968,6 @@ then case $HOST_ARCH in dnl gcc-4.6+ omits frame pointers by default, breaking some copy protections @@ -41,7 +33,7 @@ index 11111111111..11111111111 100644 x86_64) case $host_os in dnl Mingw uses Windows 64-bit types, not Unix ones -@@ -1987,6 +1987,7 @@ int a(int b, ...) { __builtin_ms_va_list list; __builtin_ms_va_start(list,b); }] +@@ -1987,6 +1986,7 @@ int a(int b, ...) { __builtin_ms_va_list list; __builtin_ms_va_start(list,b); }] esac ;; arm) WINE_TRY_CFLAGS([-Wincompatible-function-pointer-types],[EXTRACFLAGS="$EXTRACFLAGS -Wno-error=incompatible-function-pointer-types"]) ;; diff --git a/0007-proton-esync-fsync/0100-Revert-ntdll-tests-Add-tests-for-completion-port-sig.patch b/0006-proton-esync-fsync/0100-Revert-ntdll-tests-Add-tests-for-completion-port-sig.patch similarity index 100% rename from 0007-proton-esync-fsync/0100-Revert-ntdll-tests-Add-tests-for-completion-port-sig.patch rename to 0006-proton-esync-fsync/0100-Revert-ntdll-tests-Add-tests-for-completion-port-sig.patch diff --git a/0007-proton-esync-fsync/0101-Revert-kernelbase-Set-the-proper-error-code-in-GetQu.patch b/0006-proton-esync-fsync/0101-Revert-kernelbase-Set-the-proper-error-code-in-GetQu.patch similarity index 100% rename from 0007-proton-esync-fsync/0101-Revert-kernelbase-Set-the-proper-error-code-in-GetQu.patch rename to 0006-proton-esync-fsync/0101-Revert-kernelbase-Set-the-proper-error-code-in-GetQu.patch diff --git a/0007-proton-esync-fsync/0102-Revert-server-Signal-completion-port-waits-on-handle.patch b/0006-proton-esync-fsync/0102-Revert-server-Signal-completion-port-waits-on-handle.patch similarity index 100% rename from 0007-proton-esync-fsync/0102-Revert-server-Signal-completion-port-waits-on-handle.patch rename to 0006-proton-esync-fsync/0102-Revert-server-Signal-completion-port-waits-on-handle.patch diff --git a/0007-proton-esync-fsync/0103-Revert-ntdll-Handle-user-APCs-explicitly-in-NtRemove.patch b/0006-proton-esync-fsync/0103-Revert-ntdll-Handle-user-APCs-explicitly-in-NtRemove.patch similarity index 100% rename from 0007-proton-esync-fsync/0103-Revert-ntdll-Handle-user-APCs-explicitly-in-NtRemove.patch rename to 0006-proton-esync-fsync/0103-Revert-ntdll-Handle-user-APCs-explicitly-in-NtRemove.patch diff --git a/0007-proton-esync-fsync/0104-Revert-ntdll-Assign-completion-to-thread-when-wait-f.patch b/0006-proton-esync-fsync/0104-Revert-ntdll-Assign-completion-to-thread-when-wait-f.patch similarity index 100% rename from 0007-proton-esync-fsync/0104-Revert-ntdll-Assign-completion-to-thread-when-wait-f.patch rename to 0006-proton-esync-fsync/0104-Revert-ntdll-Assign-completion-to-thread-when-wait-f.patch diff --git a/0007-proton-esync-fsync/0105-Revert-ntdll-Introduce-a-separate-per-thread-object-.patch b/0006-proton-esync-fsync/0105-Revert-ntdll-Introduce-a-separate-per-thread-object-.patch similarity index 100% rename from 0007-proton-esync-fsync/0105-Revert-ntdll-Introduce-a-separate-per-thread-object-.patch rename to 0006-proton-esync-fsync/0105-Revert-ntdll-Introduce-a-separate-per-thread-object-.patch diff --git a/0007-proton-esync-fsync/0106-create-hacks-init.patch b/0006-proton-esync-fsync/0106-create-hacks-init.patch similarity index 100% rename from 0007-proton-esync-fsync/0106-create-hacks-init.patch rename to 0006-proton-esync-fsync/0106-create-hacks-init.patch diff --git a/0007-proton-esync-fsync/0107-configure-Check-for-sys-eventfd.h-ppoll-and-shm_open.patch b/0006-proton-esync-fsync/0107-configure-Check-for-sys-eventfd.h-ppoll-and-shm_open.patch similarity index 100% rename from 0007-proton-esync-fsync/0107-configure-Check-for-sys-eventfd.h-ppoll-and-shm_open.patch rename to 0006-proton-esync-fsync/0107-configure-Check-for-sys-eventfd.h-ppoll-and-shm_open.patch diff --git a/0007-proton-esync-fsync/0108-server-Create-server-objects-for-eventfd-based-synch.patch b/0006-proton-esync-fsync/0108-server-Create-server-objects-for-eventfd-based-synch.patch similarity index 100% rename from 0007-proton-esync-fsync/0108-server-Create-server-objects-for-eventfd-based-synch.patch rename to 0006-proton-esync-fsync/0108-server-Create-server-objects-for-eventfd-based-synch.patch diff --git a/0007-proton-esync-fsync/0109-ntdll-Create-eventfd-based-objects-for-semaphores.patch b/0006-proton-esync-fsync/0109-ntdll-Create-eventfd-based-objects-for-semaphores.patch similarity index 100% rename from 0007-proton-esync-fsync/0109-ntdll-Create-eventfd-based-objects-for-semaphores.patch rename to 0006-proton-esync-fsync/0109-ntdll-Create-eventfd-based-objects-for-semaphores.patch diff --git a/0007-proton-esync-fsync/0110-ntdll-Implement-NtReleaseSemaphore.patch b/0006-proton-esync-fsync/0110-ntdll-Implement-NtReleaseSemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0110-ntdll-Implement-NtReleaseSemaphore.patch rename to 0006-proton-esync-fsync/0110-ntdll-Implement-NtReleaseSemaphore.patch diff --git a/0007-proton-esync-fsync/0111-ntdll-Implement-NtClose.patch b/0006-proton-esync-fsync/0111-ntdll-Implement-NtClose.patch similarity index 100% rename from 0007-proton-esync-fsync/0111-ntdll-Implement-NtClose.patch rename to 0006-proton-esync-fsync/0111-ntdll-Implement-NtClose.patch diff --git a/0007-proton-esync-fsync/0112-ntdll-Implement-NtWaitForMultipleObjects.patch b/0006-proton-esync-fsync/0112-ntdll-Implement-NtWaitForMultipleObjects.patch similarity index 100% rename from 0007-proton-esync-fsync/0112-ntdll-Implement-NtWaitForMultipleObjects.patch rename to 0006-proton-esync-fsync/0112-ntdll-Implement-NtWaitForMultipleObjects.patch diff --git a/0007-proton-esync-fsync/0113-ntdll-server-Implement-NtCreateEvent.patch b/0006-proton-esync-fsync/0113-ntdll-server-Implement-NtCreateEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0113-ntdll-server-Implement-NtCreateEvent.patch rename to 0006-proton-esync-fsync/0113-ntdll-server-Implement-NtCreateEvent.patch diff --git a/0007-proton-esync-fsync/0114-ntdll-Implement-NtSetEvent.patch b/0006-proton-esync-fsync/0114-ntdll-Implement-NtSetEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0114-ntdll-Implement-NtSetEvent.patch rename to 0006-proton-esync-fsync/0114-ntdll-Implement-NtSetEvent.patch diff --git a/0007-proton-esync-fsync/0115-ntdll-Implement-NtResetEvent.patch b/0006-proton-esync-fsync/0115-ntdll-Implement-NtResetEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0115-ntdll-Implement-NtResetEvent.patch rename to 0006-proton-esync-fsync/0115-ntdll-Implement-NtResetEvent.patch diff --git a/0007-proton-esync-fsync/0116-ntdll-Implement-waiting-on-manual-reset-events.patch b/0006-proton-esync-fsync/0116-ntdll-Implement-waiting-on-manual-reset-events.patch similarity index 100% rename from 0007-proton-esync-fsync/0116-ntdll-Implement-waiting-on-manual-reset-events.patch rename to 0006-proton-esync-fsync/0116-ntdll-Implement-waiting-on-manual-reset-events.patch diff --git a/0007-proton-esync-fsync/0117-server-Add-an-object-operation-to-grab-the-esync-fil.patch b/0006-proton-esync-fsync/0117-server-Add-an-object-operation-to-grab-the-esync-fil.patch similarity index 100% rename from 0007-proton-esync-fsync/0117-server-Add-an-object-operation-to-grab-the-esync-fil.patch rename to 0006-proton-esync-fsync/0117-server-Add-an-object-operation-to-grab-the-esync-fil.patch diff --git a/0007-proton-esync-fsync/0118-server-Add-a-request-to-get-the-eventfd-file-descrip.patch b/0006-proton-esync-fsync/0118-server-Add-a-request-to-get-the-eventfd-file-descrip.patch similarity index 100% rename from 0007-proton-esync-fsync/0118-server-Add-a-request-to-get-the-eventfd-file-descrip.patch rename to 0006-proton-esync-fsync/0118-server-Add-a-request-to-get-the-eventfd-file-descrip.patch diff --git a/0007-proton-esync-fsync/0119-server-Create-eventfd-file-descriptors-for-process-o.patch b/0006-proton-esync-fsync/0119-server-Create-eventfd-file-descriptors-for-process-o.patch similarity index 100% rename from 0007-proton-esync-fsync/0119-server-Create-eventfd-file-descriptors-for-process-o.patch rename to 0006-proton-esync-fsync/0119-server-Create-eventfd-file-descriptors-for-process-o.patch diff --git a/0007-proton-esync-fsync/0120-ntdll-server-Implement-waiting-on-server-bound-objec.patch b/0006-proton-esync-fsync/0120-ntdll-server-Implement-waiting-on-server-bound-objec.patch similarity index 100% rename from 0007-proton-esync-fsync/0120-ntdll-server-Implement-waiting-on-server-bound-objec.patch rename to 0006-proton-esync-fsync/0120-ntdll-server-Implement-waiting-on-server-bound-objec.patch diff --git a/0007-proton-esync-fsync/0121-server-Create-eventfd-file-descriptors-for-event-obj.patch b/0006-proton-esync-fsync/0121-server-Create-eventfd-file-descriptors-for-event-obj.patch similarity index 100% rename from 0007-proton-esync-fsync/0121-server-Create-eventfd-file-descriptors-for-event-obj.patch rename to 0006-proton-esync-fsync/0121-server-Create-eventfd-file-descriptors-for-event-obj.patch diff --git a/0007-proton-esync-fsync/0122-server-Allow-re-setting-esync-events-on-the-server-s.patch b/0006-proton-esync-fsync/0122-server-Allow-re-setting-esync-events-on-the-server-s.patch similarity index 100% rename from 0007-proton-esync-fsync/0122-server-Allow-re-setting-esync-events-on-the-server-s.patch rename to 0006-proton-esync-fsync/0122-server-Allow-re-setting-esync-events-on-the-server-s.patch diff --git a/0007-proton-esync-fsync/0123-ntdll-Try-again-if-poll-returns-EINTR.patch b/0006-proton-esync-fsync/0123-ntdll-Try-again-if-poll-returns-EINTR.patch similarity index 100% rename from 0007-proton-esync-fsync/0123-ntdll-Try-again-if-poll-returns-EINTR.patch rename to 0006-proton-esync-fsync/0123-ntdll-Try-again-if-poll-returns-EINTR.patch diff --git a/0007-proton-esync-fsync/0124-server-Create-eventfd-file-descriptors-for-thread-ob.patch b/0006-proton-esync-fsync/0124-server-Create-eventfd-file-descriptors-for-thread-ob.patch similarity index 100% rename from 0007-proton-esync-fsync/0124-server-Create-eventfd-file-descriptors-for-thread-ob.patch rename to 0006-proton-esync-fsync/0124-server-Create-eventfd-file-descriptors-for-thread-ob.patch diff --git a/0007-proton-esync-fsync/0125-server-Create-eventfd-file-descriptors-for-message-q.patch b/0006-proton-esync-fsync/0125-server-Create-eventfd-file-descriptors-for-message-q.patch similarity index 100% rename from 0007-proton-esync-fsync/0125-server-Create-eventfd-file-descriptors-for-message-q.patch rename to 0006-proton-esync-fsync/0125-server-Create-eventfd-file-descriptors-for-message-q.patch diff --git a/0007-proton-esync-fsync/0126-server-ntdll-Implement-message-waits.patch b/0006-proton-esync-fsync/0126-server-ntdll-Implement-message-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0126-server-ntdll-Implement-message-waits.patch rename to 0006-proton-esync-fsync/0126-server-ntdll-Implement-message-waits.patch diff --git a/0007-proton-esync-fsync/0127-server-Create-eventfd-descriptors-for-device-manager.patch b/0006-proton-esync-fsync/0127-server-Create-eventfd-descriptors-for-device-manager.patch similarity index 100% rename from 0007-proton-esync-fsync/0127-server-Create-eventfd-descriptors-for-device-manager.patch rename to 0006-proton-esync-fsync/0127-server-Create-eventfd-descriptors-for-device-manager.patch diff --git a/0007-proton-esync-fsync/0128-ntdll-server-Implement-NtCreateMutant.patch b/0006-proton-esync-fsync/0128-ntdll-server-Implement-NtCreateMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0128-ntdll-server-Implement-NtCreateMutant.patch rename to 0006-proton-esync-fsync/0128-ntdll-server-Implement-NtCreateMutant.patch diff --git a/0007-proton-esync-fsync/0129-ntdll-Implement-NtReleaseMutant.patch b/0006-proton-esync-fsync/0129-ntdll-Implement-NtReleaseMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0129-ntdll-Implement-NtReleaseMutant.patch rename to 0006-proton-esync-fsync/0129-ntdll-Implement-NtReleaseMutant.patch diff --git a/0007-proton-esync-fsync/0130-ntdll-Implement-waiting-on-mutexes.patch b/0006-proton-esync-fsync/0130-ntdll-Implement-waiting-on-mutexes.patch similarity index 100% rename from 0007-proton-esync-fsync/0130-ntdll-Implement-waiting-on-mutexes.patch rename to 0006-proton-esync-fsync/0130-ntdll-Implement-waiting-on-mutexes.patch diff --git a/0007-proton-esync-fsync/0131-ntdll-Implement-wait-all.patch b/0006-proton-esync-fsync/0131-ntdll-Implement-wait-all.patch similarity index 100% rename from 0007-proton-esync-fsync/0131-ntdll-Implement-wait-all.patch rename to 0006-proton-esync-fsync/0131-ntdll-Implement-wait-all.patch diff --git a/0007-proton-esync-fsync/0132-esync-Add-a-README.patch b/0006-proton-esync-fsync/0132-esync-Add-a-README.patch similarity index 100% rename from 0007-proton-esync-fsync/0132-esync-Add-a-README.patch rename to 0006-proton-esync-fsync/0132-esync-Add-a-README.patch diff --git a/0007-proton-esync-fsync/0133-ntdll-Implement-NtSignalAndWaitForSingleObject.patch b/0006-proton-esync-fsync/0133-ntdll-Implement-NtSignalAndWaitForSingleObject.patch similarity index 100% rename from 0007-proton-esync-fsync/0133-ntdll-Implement-NtSignalAndWaitForSingleObject.patch rename to 0006-proton-esync-fsync/0133-ntdll-Implement-NtSignalAndWaitForSingleObject.patch diff --git a/0007-proton-esync-fsync/0134-ntdll-Implement-NtOpenSemaphore.patch b/0006-proton-esync-fsync/0134-ntdll-Implement-NtOpenSemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0134-ntdll-Implement-NtOpenSemaphore.patch rename to 0006-proton-esync-fsync/0134-ntdll-Implement-NtOpenSemaphore.patch diff --git a/0007-proton-esync-fsync/0135-ntdll-Implement-NtOpenEvent.patch b/0006-proton-esync-fsync/0135-ntdll-Implement-NtOpenEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0135-ntdll-Implement-NtOpenEvent.patch rename to 0006-proton-esync-fsync/0135-ntdll-Implement-NtOpenEvent.patch diff --git a/0007-proton-esync-fsync/0136-ntdll-Implement-NtOpenMutant.patch b/0006-proton-esync-fsync/0136-ntdll-Implement-NtOpenMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0136-ntdll-Implement-NtOpenMutant.patch rename to 0006-proton-esync-fsync/0136-ntdll-Implement-NtOpenMutant.patch diff --git a/0007-proton-esync-fsync/0137-server-Implement-esync_map_access.patch b/0006-proton-esync-fsync/0137-server-Implement-esync_map_access.patch similarity index 100% rename from 0007-proton-esync-fsync/0137-server-Implement-esync_map_access.patch rename to 0006-proton-esync-fsync/0137-server-Implement-esync_map_access.patch diff --git a/0007-proton-esync-fsync/0138-server-Implement-NtDuplicateObject.patch b/0006-proton-esync-fsync/0138-server-Implement-NtDuplicateObject.patch similarity index 100% rename from 0007-proton-esync-fsync/0138-server-Implement-NtDuplicateObject.patch rename to 0006-proton-esync-fsync/0138-server-Implement-NtDuplicateObject.patch diff --git a/0007-proton-esync-fsync/0139-server-Create-eventfd-descriptors-for-timers.patch b/0006-proton-esync-fsync/0139-server-Create-eventfd-descriptors-for-timers.patch similarity index 100% rename from 0007-proton-esync-fsync/0139-server-Create-eventfd-descriptors-for-timers.patch rename to 0006-proton-esync-fsync/0139-server-Create-eventfd-descriptors-for-timers.patch diff --git a/0007-proton-esync-fsync/0140-ntdll-server-Implement-alertable-waits.patch b/0006-proton-esync-fsync/0140-ntdll-server-Implement-alertable-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0140-ntdll-server-Implement-alertable-waits.patch rename to 0006-proton-esync-fsync/0140-ntdll-server-Implement-alertable-waits.patch diff --git a/0007-proton-esync-fsync/0141-esync-Update-README.patch b/0006-proton-esync-fsync/0141-esync-Update-README.patch similarity index 100% rename from 0007-proton-esync-fsync/0141-esync-Update-README.patch rename to 0006-proton-esync-fsync/0141-esync-Update-README.patch diff --git a/0007-proton-esync-fsync/0142-kernel32-tests-Mark-some-existing-tests-as-failing-u.patch b/0006-proton-esync-fsync/0142-kernel32-tests-Mark-some-existing-tests-as-failing-u.patch similarity index 100% rename from 0007-proton-esync-fsync/0142-kernel32-tests-Mark-some-existing-tests-as-failing-u.patch rename to 0006-proton-esync-fsync/0142-kernel32-tests-Mark-some-existing-tests-as-failing-u.patch diff --git a/0007-proton-esync-fsync/0143-ntdll-Implement-NtQuerySemaphore.patch b/0006-proton-esync-fsync/0143-ntdll-Implement-NtQuerySemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0143-ntdll-Implement-NtQuerySemaphore.patch rename to 0006-proton-esync-fsync/0143-ntdll-Implement-NtQuerySemaphore.patch diff --git a/0007-proton-esync-fsync/0144-ntdll-Implement-NtQueryEvent.patch b/0006-proton-esync-fsync/0144-ntdll-Implement-NtQueryEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0144-ntdll-Implement-NtQueryEvent.patch rename to 0006-proton-esync-fsync/0144-ntdll-Implement-NtQueryEvent.patch diff --git a/0007-proton-esync-fsync/0145-ntdll-Implement-NtQueryMutant.patch b/0006-proton-esync-fsync/0145-ntdll-Implement-NtQueryMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0145-ntdll-Implement-NtQueryMutant.patch rename to 0006-proton-esync-fsync/0145-ntdll-Implement-NtQueryMutant.patch diff --git a/0007-proton-esync-fsync/0146-server-Create-eventfd-descriptors-for-pseudo-fd-obje.patch b/0006-proton-esync-fsync/0146-server-Create-eventfd-descriptors-for-pseudo-fd-obje.patch similarity index 100% rename from 0007-proton-esync-fsync/0146-server-Create-eventfd-descriptors-for-pseudo-fd-obje.patch rename to 0006-proton-esync-fsync/0146-server-Create-eventfd-descriptors-for-pseudo-fd-obje.patch diff --git a/0007-proton-esync-fsync/0147-esync-Update-README.patch b/0006-proton-esync-fsync/0147-esync-Update-README.patch similarity index 100% rename from 0007-proton-esync-fsync/0147-esync-Update-README.patch rename to 0006-proton-esync-fsync/0147-esync-Update-README.patch diff --git a/0007-proton-esync-fsync/0148-esync-Add-note-about-file-limits-not-being-raised-wh.patch b/0006-proton-esync-fsync/0148-esync-Add-note-about-file-limits-not-being-raised-wh.patch similarity index 100% rename from 0007-proton-esync-fsync/0148-esync-Add-note-about-file-limits-not-being-raised-wh.patch rename to 0006-proton-esync-fsync/0148-esync-Add-note-about-file-limits-not-being-raised-wh.patch diff --git a/0007-proton-esync-fsync/0149-ntdll-Try-to-avoid-poll-for-uncontended-objects.patch b/0006-proton-esync-fsync/0149-ntdll-Try-to-avoid-poll-for-uncontended-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0149-ntdll-Try-to-avoid-poll-for-uncontended-objects.patch rename to 0006-proton-esync-fsync/0149-ntdll-Try-to-avoid-poll-for-uncontended-objects.patch diff --git a/0007-proton-esync-fsync/0150-ntdll-server-Try-to-avoid-poll-for-signaled-events.patch b/0006-proton-esync-fsync/0150-ntdll-server-Try-to-avoid-poll-for-signaled-events.patch similarity index 100% rename from 0007-proton-esync-fsync/0150-ntdll-server-Try-to-avoid-poll-for-signaled-events.patch rename to 0006-proton-esync-fsync/0150-ntdll-server-Try-to-avoid-poll-for-signaled-events.patch diff --git a/0007-proton-esync-fsync/0151-esync-Update-README.patch b/0006-proton-esync-fsync/0151-esync-Update-README.patch similarity index 100% rename from 0007-proton-esync-fsync/0151-esync-Update-README.patch rename to 0006-proton-esync-fsync/0151-esync-Update-README.patch diff --git a/0007-proton-esync-fsync/0152-ntdll-Implement-NtPulseEvent.patch b/0006-proton-esync-fsync/0152-ntdll-Implement-NtPulseEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0152-ntdll-Implement-NtPulseEvent.patch rename to 0006-proton-esync-fsync/0152-ntdll-Implement-NtPulseEvent.patch diff --git a/0007-proton-esync-fsync/0153-esync-Update-README.patch b/0006-proton-esync-fsync/0153-esync-Update-README.patch similarity index 100% rename from 0007-proton-esync-fsync/0153-esync-Update-README.patch rename to 0006-proton-esync-fsync/0153-esync-Update-README.patch diff --git a/0007-proton-esync-fsync/0154-server-Create-esync-file-descriptors-for-true-file-o.patch b/0006-proton-esync-fsync/0154-server-Create-esync-file-descriptors-for-true-file-o.patch similarity index 100% rename from 0007-proton-esync-fsync/0154-server-Create-esync-file-descriptors-for-true-file-o.patch rename to 0006-proton-esync-fsync/0154-server-Create-esync-file-descriptors-for-true-file-o.patch diff --git a/0007-proton-esync-fsync/0155-ntdll-server-Abandon-esync-mutexes-on-thread-exit.patch b/0006-proton-esync-fsync/0155-ntdll-server-Abandon-esync-mutexes-on-thread-exit.patch similarity index 100% rename from 0007-proton-esync-fsync/0155-ntdll-server-Abandon-esync-mutexes-on-thread-exit.patch rename to 0006-proton-esync-fsync/0155-ntdll-server-Abandon-esync-mutexes-on-thread-exit.patch diff --git a/0007-proton-esync-fsync/0156-server-Create-esync-file-descriptors-for-console-ser.patch b/0006-proton-esync-fsync/0156-server-Create-esync-file-descriptors-for-console-ser.patch similarity index 100% rename from 0007-proton-esync-fsync/0156-server-Create-esync-file-descriptors-for-console-ser.patch rename to 0006-proton-esync-fsync/0156-server-Create-esync-file-descriptors-for-console-ser.patch diff --git a/0007-proton-esync-fsync/0157-readme-only-adjust-hard-limit-in-systemd-20.patch b/0006-proton-esync-fsync/0157-readme-only-adjust-hard-limit-in-systemd-20.patch similarity index 100% rename from 0007-proton-esync-fsync/0157-readme-only-adjust-hard-limit-in-systemd-20.patch rename to 0006-proton-esync-fsync/0157-readme-only-adjust-hard-limit-in-systemd-20.patch diff --git a/0007-proton-esync-fsync/0158-esync-Fix-restoring-the-objects-state-on-wait-all-ob.patch b/0006-proton-esync-fsync/0158-esync-Fix-restoring-the-objects-state-on-wait-all-ob.patch similarity index 100% rename from 0007-proton-esync-fsync/0158-esync-Fix-restoring-the-objects-state-on-wait-all-ob.patch rename to 0006-proton-esync-fsync/0158-esync-Fix-restoring-the-objects-state-on-wait-all-ob.patch diff --git a/0007-proton-esync-fsync/0159-server-Create-server-objects-for-futex-based-synchro.patch b/0006-proton-esync-fsync/0159-server-Create-server-objects-for-futex-based-synchro.patch similarity index 100% rename from 0007-proton-esync-fsync/0159-server-Create-server-objects-for-futex-based-synchro.patch rename to 0006-proton-esync-fsync/0159-server-Create-server-objects-for-futex-based-synchro.patch diff --git a/0007-proton-esync-fsync/0160-ntdll-Create-futex-based-objects-for-semaphores.patch b/0006-proton-esync-fsync/0160-ntdll-Create-futex-based-objects-for-semaphores.patch similarity index 100% rename from 0007-proton-esync-fsync/0160-ntdll-Create-futex-based-objects-for-semaphores.patch rename to 0006-proton-esync-fsync/0160-ntdll-Create-futex-based-objects-for-semaphores.patch diff --git a/0007-proton-esync-fsync/0161-ntdll-Implement-NtReleaseSemaphore.patch b/0006-proton-esync-fsync/0161-ntdll-Implement-NtReleaseSemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0161-ntdll-Implement-NtReleaseSemaphore.patch rename to 0006-proton-esync-fsync/0161-ntdll-Implement-NtReleaseSemaphore.patch diff --git a/0007-proton-esync-fsync/0162-ntdll-Close-fsync-objects.patch b/0006-proton-esync-fsync/0162-ntdll-Close-fsync-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0162-ntdll-Close-fsync-objects.patch rename to 0006-proton-esync-fsync/0162-ntdll-Close-fsync-objects.patch diff --git a/0007-proton-esync-fsync/0163-ntdll-Implement-waiting-on-fsync-objects.patch b/0006-proton-esync-fsync/0163-ntdll-Implement-waiting-on-fsync-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0163-ntdll-Implement-waiting-on-fsync-objects.patch rename to 0006-proton-esync-fsync/0163-ntdll-Implement-waiting-on-fsync-objects.patch diff --git a/0007-proton-esync-fsync/0164-ntdll-Create-fsync-objects-for-events.patch b/0006-proton-esync-fsync/0164-ntdll-Create-fsync-objects-for-events.patch similarity index 100% rename from 0007-proton-esync-fsync/0164-ntdll-Create-fsync-objects-for-events.patch rename to 0006-proton-esync-fsync/0164-ntdll-Create-fsync-objects-for-events.patch diff --git a/0007-proton-esync-fsync/0165-ntdll-Implement-NtSetEvent.patch b/0006-proton-esync-fsync/0165-ntdll-Implement-NtSetEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0165-ntdll-Implement-NtSetEvent.patch rename to 0006-proton-esync-fsync/0165-ntdll-Implement-NtSetEvent.patch diff --git a/0007-proton-esync-fsync/0166-ntdll-Implement-NtResetEvent.patch b/0006-proton-esync-fsync/0166-ntdll-Implement-NtResetEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0166-ntdll-Implement-NtResetEvent.patch rename to 0006-proton-esync-fsync/0166-ntdll-Implement-NtResetEvent.patch diff --git a/0007-proton-esync-fsync/0167-ntdll-Implement-waiting-on-events.patch b/0006-proton-esync-fsync/0167-ntdll-Implement-waiting-on-events.patch similarity index 100% rename from 0007-proton-esync-fsync/0167-ntdll-Implement-waiting-on-events.patch rename to 0006-proton-esync-fsync/0167-ntdll-Implement-waiting-on-events.patch diff --git a/0007-proton-esync-fsync/0168-server-Add-an-object-operation-to-grab-the-fsync-shm.patch b/0006-proton-esync-fsync/0168-server-Add-an-object-operation-to-grab-the-fsync-shm.patch similarity index 100% rename from 0007-proton-esync-fsync/0168-server-Add-an-object-operation-to-grab-the-fsync-shm.patch rename to 0006-proton-esync-fsync/0168-server-Add-an-object-operation-to-grab-the-fsync-shm.patch diff --git a/0007-proton-esync-fsync/0169-server-Add-a-request-to-get-the-shm-index-associated.patch b/0006-proton-esync-fsync/0169-server-Add-a-request-to-get-the-shm-index-associated.patch similarity index 100% rename from 0007-proton-esync-fsync/0169-server-Add-a-request-to-get-the-shm-index-associated.patch rename to 0006-proton-esync-fsync/0169-server-Add-a-request-to-get-the-shm-index-associated.patch diff --git a/0007-proton-esync-fsync/0170-server-Create-futex-sections-for-process-objects.patch b/0006-proton-esync-fsync/0170-server-Create-futex-sections-for-process-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0170-server-Create-futex-sections-for-process-objects.patch rename to 0006-proton-esync-fsync/0170-server-Create-futex-sections-for-process-objects.patch diff --git a/0007-proton-esync-fsync/0171-ntdll-server-Implement-waiting-on-server-bound-objec.patch b/0006-proton-esync-fsync/0171-ntdll-server-Implement-waiting-on-server-bound-objec.patch similarity index 100% rename from 0007-proton-esync-fsync/0171-ntdll-server-Implement-waiting-on-server-bound-objec.patch rename to 0006-proton-esync-fsync/0171-ntdll-server-Implement-waiting-on-server-bound-objec.patch diff --git a/0007-proton-esync-fsync/0172-server-Create-futexes-for-event-objects.patch b/0006-proton-esync-fsync/0172-server-Create-futexes-for-event-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0172-server-Create-futexes-for-event-objects.patch rename to 0006-proton-esync-fsync/0172-server-Create-futexes-for-event-objects.patch diff --git a/0007-proton-esync-fsync/0173-server-Allow-re-setting-fsync-events-on-the-server-s.patch b/0006-proton-esync-fsync/0173-server-Allow-re-setting-fsync-events-on-the-server-s.patch similarity index 100% rename from 0007-proton-esync-fsync/0173-server-Allow-re-setting-fsync-events-on-the-server-s.patch rename to 0006-proton-esync-fsync/0173-server-Allow-re-setting-fsync-events-on-the-server-s.patch diff --git a/0007-proton-esync-fsync/0174-server-Create-futexes-for-thread-objects.patch b/0006-proton-esync-fsync/0174-server-Create-futexes-for-thread-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0174-server-Create-futexes-for-thread-objects.patch rename to 0006-proton-esync-fsync/0174-server-Create-futexes-for-thread-objects.patch diff --git a/0007-proton-esync-fsync/0175-server-Create-futexes-for-message-queues.patch b/0006-proton-esync-fsync/0175-server-Create-futexes-for-message-queues.patch similarity index 100% rename from 0007-proton-esync-fsync/0175-server-Create-futexes-for-message-queues.patch rename to 0006-proton-esync-fsync/0175-server-Create-futexes-for-message-queues.patch diff --git a/0007-proton-esync-fsync/0176-server-ntdll-Implement-message-waits.patch b/0006-proton-esync-fsync/0176-server-ntdll-Implement-message-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0176-server-ntdll-Implement-message-waits.patch rename to 0006-proton-esync-fsync/0176-server-ntdll-Implement-message-waits.patch diff --git a/0007-proton-esync-fsync/0177-server-Create-futexes-for-device-manager-objects.patch b/0006-proton-esync-fsync/0177-server-Create-futexes-for-device-manager-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0177-server-Create-futexes-for-device-manager-objects.patch rename to 0006-proton-esync-fsync/0177-server-Create-futexes-for-device-manager-objects.patch diff --git a/0007-proton-esync-fsync/0178-ntdll-Implement-NtCreateMutant.patch b/0006-proton-esync-fsync/0178-ntdll-Implement-NtCreateMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0178-ntdll-Implement-NtCreateMutant.patch rename to 0006-proton-esync-fsync/0178-ntdll-Implement-NtCreateMutant.patch diff --git a/0007-proton-esync-fsync/0179-ntdll-Implement-NtReleaseMutant.patch b/0006-proton-esync-fsync/0179-ntdll-Implement-NtReleaseMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0179-ntdll-Implement-NtReleaseMutant.patch rename to 0006-proton-esync-fsync/0179-ntdll-Implement-NtReleaseMutant.patch diff --git a/0007-proton-esync-fsync/0180-ntdll-Implement-waiting-on-mutexes.patch b/0006-proton-esync-fsync/0180-ntdll-Implement-waiting-on-mutexes.patch similarity index 100% rename from 0007-proton-esync-fsync/0180-ntdll-Implement-waiting-on-mutexes.patch rename to 0006-proton-esync-fsync/0180-ntdll-Implement-waiting-on-mutexes.patch diff --git a/0007-proton-esync-fsync/0181-ntdll-Implement-wait-all.patch b/0006-proton-esync-fsync/0181-ntdll-Implement-wait-all.patch similarity index 100% rename from 0007-proton-esync-fsync/0181-ntdll-Implement-wait-all.patch rename to 0006-proton-esync-fsync/0181-ntdll-Implement-wait-all.patch diff --git a/0007-proton-esync-fsync/0182-ntdll-Implement-NtSignalAndWaitForSingleObject.patch b/0006-proton-esync-fsync/0182-ntdll-Implement-NtSignalAndWaitForSingleObject.patch similarity index 100% rename from 0007-proton-esync-fsync/0182-ntdll-Implement-NtSignalAndWaitForSingleObject.patch rename to 0006-proton-esync-fsync/0182-ntdll-Implement-NtSignalAndWaitForSingleObject.patch diff --git a/0007-proton-esync-fsync/0183-server-ntdll-Also-store-the-fsync-type-in-the-server.patch b/0006-proton-esync-fsync/0183-server-ntdll-Also-store-the-fsync-type-in-the-server.patch similarity index 100% rename from 0007-proton-esync-fsync/0183-server-ntdll-Also-store-the-fsync-type-in-the-server.patch rename to 0006-proton-esync-fsync/0183-server-ntdll-Also-store-the-fsync-type-in-the-server.patch diff --git a/0007-proton-esync-fsync/0184-ntdll-server-Implement-NtOpenSemaphore.patch b/0006-proton-esync-fsync/0184-ntdll-server-Implement-NtOpenSemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0184-ntdll-server-Implement-NtOpenSemaphore.patch rename to 0006-proton-esync-fsync/0184-ntdll-server-Implement-NtOpenSemaphore.patch diff --git a/0007-proton-esync-fsync/0185-ntdll-Implement-NtOpenEvent.patch b/0006-proton-esync-fsync/0185-ntdll-Implement-NtOpenEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0185-ntdll-Implement-NtOpenEvent.patch rename to 0006-proton-esync-fsync/0185-ntdll-Implement-NtOpenEvent.patch diff --git a/0007-proton-esync-fsync/0186-ntdll-Implement-NtOpenMutant.patch b/0006-proton-esync-fsync/0186-ntdll-Implement-NtOpenMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0186-ntdll-Implement-NtOpenMutant.patch rename to 0006-proton-esync-fsync/0186-ntdll-Implement-NtOpenMutant.patch diff --git a/0007-proton-esync-fsync/0187-server-Implement-fsync_map_access.patch b/0006-proton-esync-fsync/0187-server-Implement-fsync_map_access.patch similarity index 100% rename from 0007-proton-esync-fsync/0187-server-Implement-fsync_map_access.patch rename to 0006-proton-esync-fsync/0187-server-Implement-fsync_map_access.patch diff --git a/0007-proton-esync-fsync/0188-ntdll-server-Implement-handle-duplication.patch b/0006-proton-esync-fsync/0188-ntdll-server-Implement-handle-duplication.patch similarity index 100% rename from 0007-proton-esync-fsync/0188-ntdll-server-Implement-handle-duplication.patch rename to 0006-proton-esync-fsync/0188-ntdll-server-Implement-handle-duplication.patch diff --git a/0007-proton-esync-fsync/0189-ntdll-server-Implement-alertable-waits.patch b/0006-proton-esync-fsync/0189-ntdll-server-Implement-alertable-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0189-ntdll-server-Implement-alertable-waits.patch rename to 0006-proton-esync-fsync/0189-ntdll-server-Implement-alertable-waits.patch diff --git a/0007-proton-esync-fsync/0190-ntdll-Wake-all-threads-in-futex_wake.patch b/0006-proton-esync-fsync/0190-ntdll-Wake-all-threads-in-futex_wake.patch similarity index 100% rename from 0007-proton-esync-fsync/0190-ntdll-Wake-all-threads-in-futex_wake.patch rename to 0006-proton-esync-fsync/0190-ntdll-Wake-all-threads-in-futex_wake.patch diff --git a/0007-proton-esync-fsync/0191-server-Create-futex-sections-for-timer-objects.patch b/0006-proton-esync-fsync/0191-server-Create-futex-sections-for-timer-objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0191-server-Create-futex-sections-for-timer-objects.patch rename to 0006-proton-esync-fsync/0191-server-Create-futex-sections-for-timer-objects.patch diff --git a/0007-proton-esync-fsync/0192-server-Create-futex-sections-for-console-input-event.patch b/0006-proton-esync-fsync/0192-server-Create-futex-sections-for-console-input-event.patch similarity index 100% rename from 0007-proton-esync-fsync/0192-server-Create-futex-sections-for-console-input-event.patch rename to 0006-proton-esync-fsync/0192-server-Create-futex-sections-for-console-input-event.patch diff --git a/0007-proton-esync-fsync/0193-ntdll-Implement-NtQuerySemaphore.patch b/0006-proton-esync-fsync/0193-ntdll-Implement-NtQuerySemaphore.patch similarity index 100% rename from 0007-proton-esync-fsync/0193-ntdll-Implement-NtQuerySemaphore.patch rename to 0006-proton-esync-fsync/0193-ntdll-Implement-NtQuerySemaphore.patch diff --git a/0007-proton-esync-fsync/0194-ntdll-Implement-NtQueryEvent.patch b/0006-proton-esync-fsync/0194-ntdll-Implement-NtQueryEvent.patch similarity index 100% rename from 0007-proton-esync-fsync/0194-ntdll-Implement-NtQueryEvent.patch rename to 0006-proton-esync-fsync/0194-ntdll-Implement-NtQueryEvent.patch diff --git a/0007-proton-esync-fsync/0195-ntdll-Implement-NtQueryMutant.patch b/0006-proton-esync-fsync/0195-ntdll-Implement-NtQueryMutant.patch similarity index 100% rename from 0007-proton-esync-fsync/0195-ntdll-Implement-NtQueryMutant.patch rename to 0006-proton-esync-fsync/0195-ntdll-Implement-NtQueryMutant.patch diff --git a/0007-proton-esync-fsync/0196-server-Create-futex-sections-for-pseudo-fd-objects-a.patch b/0006-proton-esync-fsync/0196-server-Create-futex-sections-for-pseudo-fd-objects-a.patch similarity index 100% rename from 0007-proton-esync-fsync/0196-server-Create-futex-sections-for-pseudo-fd-objects-a.patch rename to 0006-proton-esync-fsync/0196-server-Create-futex-sections-for-pseudo-fd-objects-a.patch diff --git a/0007-proton-esync-fsync/0197-server-Create-futex-sections-for-true-file-objects-a.patch b/0006-proton-esync-fsync/0197-server-Create-futex-sections-for-true-file-objects-a.patch similarity index 100% rename from 0007-proton-esync-fsync/0197-server-Create-futex-sections-for-true-file-objects-a.patch rename to 0006-proton-esync-fsync/0197-server-Create-futex-sections-for-true-file-objects-a.patch diff --git a/0007-proton-esync-fsync/0198-ntdll-Skip-zero-length-waits.patch b/0006-proton-esync-fsync/0198-ntdll-Skip-zero-length-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0198-ntdll-Skip-zero-length-waits.patch rename to 0006-proton-esync-fsync/0198-ntdll-Skip-zero-length-waits.patch diff --git a/0007-proton-esync-fsync/0199-server-Add-a-diagnostic-message-for-fsync.patch b/0006-proton-esync-fsync/0199-server-Add-a-diagnostic-message-for-fsync.patch similarity index 100% rename from 0007-proton-esync-fsync/0199-server-Add-a-diagnostic-message-for-fsync.patch rename to 0006-proton-esync-fsync/0199-server-Add-a-diagnostic-message-for-fsync.patch diff --git a/0007-proton-esync-fsync/0200-ntdll-server-Make-extra-sure-that-esync-is-never-use.patch b/0006-proton-esync-fsync/0200-ntdll-server-Make-extra-sure-that-esync-is-never-use.patch similarity index 100% rename from 0007-proton-esync-fsync/0200-ntdll-server-Make-extra-sure-that-esync-is-never-use.patch rename to 0006-proton-esync-fsync/0200-ntdll-server-Make-extra-sure-that-esync-is-never-use.patch diff --git a/0007-proton-esync-fsync/0201-ntdll-server-Switch-to-testing-ABI.patch b/0006-proton-esync-fsync/0201-ntdll-server-Switch-to-testing-ABI.patch similarity index 100% rename from 0007-proton-esync-fsync/0201-ntdll-server-Switch-to-testing-ABI.patch rename to 0006-proton-esync-fsync/0201-ntdll-server-Switch-to-testing-ABI.patch diff --git a/0007-proton-esync-fsync/0202-ntdll-Check-the-APC-futex-first.patch b/0006-proton-esync-fsync/0202-ntdll-Check-the-APC-futex-first.patch similarity index 100% rename from 0007-proton-esync-fsync/0202-ntdll-Check-the-APC-futex-first.patch rename to 0006-proton-esync-fsync/0202-ntdll-Check-the-APC-futex-first.patch diff --git a/0007-proton-esync-fsync/0203-server-Fix-an-invalid-use-of-fsync_clear.patch b/0006-proton-esync-fsync/0203-server-Fix-an-invalid-use-of-fsync_clear.patch similarity index 100% rename from 0007-proton-esync-fsync/0203-server-Fix-an-invalid-use-of-fsync_clear.patch rename to 0006-proton-esync-fsync/0203-server-Fix-an-invalid-use-of-fsync_clear.patch diff --git a/0007-proton-esync-fsync/0204-server-Be-a-little-more-careful-about-futex-operatio.patch b/0006-proton-esync-fsync/0204-server-Be-a-little-more-careful-about-futex-operatio.patch similarity index 100% rename from 0007-proton-esync-fsync/0204-server-Be-a-little-more-careful-about-futex-operatio.patch rename to 0006-proton-esync-fsync/0204-server-Be-a-little-more-careful-about-futex-operatio.patch diff --git a/0007-proton-esync-fsync/0205-ntdll-Catch-closed-handles-more-gracefully.patch b/0006-proton-esync-fsync/0205-ntdll-Catch-closed-handles-more-gracefully.patch similarity index 100% rename from 0007-proton-esync-fsync/0205-ntdll-Catch-closed-handles-more-gracefully.patch rename to 0006-proton-esync-fsync/0205-ntdll-Catch-closed-handles-more-gracefully.patch diff --git a/0007-proton-esync-fsync/0206-ntdll-Implement-fsync_pulse_event.patch b/0006-proton-esync-fsync/0206-ntdll-Implement-fsync_pulse_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0206-ntdll-Implement-fsync_pulse_event.patch rename to 0006-proton-esync-fsync/0206-ntdll-Implement-fsync_pulse_event.patch diff --git a/0007-proton-esync-fsync/0207-server-Print-a-message-when-using-server-side-synchr.patch b/0006-proton-esync-fsync/0207-server-Print-a-message-when-using-server-side-synchr.patch similarity index 100% rename from 0007-proton-esync-fsync/0207-server-Print-a-message-when-using-server-side-synchr.patch rename to 0006-proton-esync-fsync/0207-server-Print-a-message-when-using-server-side-synchr.patch diff --git a/0007-proton-esync-fsync/0208-ntdll-Store-the-fsync-APC-futex-in-the-thread-data-d.patch b/0006-proton-esync-fsync/0208-ntdll-Store-the-fsync-APC-futex-in-the-thread-data-d.patch similarity index 100% rename from 0007-proton-esync-fsync/0208-ntdll-Store-the-fsync-APC-futex-in-the-thread-data-d.patch rename to 0006-proton-esync-fsync/0208-ntdll-Store-the-fsync-APC-futex-in-the-thread-data-d.patch diff --git a/0007-proton-esync-fsync/0209-ntdll-fsync-Lock-accessing-the-shm_addrs-array.patch b/0006-proton-esync-fsync/0209-ntdll-fsync-Lock-accessing-the-shm_addrs-array.patch similarity index 100% rename from 0007-proton-esync-fsync/0209-ntdll-fsync-Lock-accessing-the-shm_addrs-array.patch rename to 0006-proton-esync-fsync/0209-ntdll-fsync-Lock-accessing-the-shm_addrs-array.patch diff --git a/0007-proton-esync-fsync/0210-ntdll-fsync-Fix-a-race-condition-when-waiting-on-a-m.patch b/0006-proton-esync-fsync/0210-ntdll-fsync-Fix-a-race-condition-when-waiting-on-a-m.patch similarity index 100% rename from 0007-proton-esync-fsync/0210-ntdll-fsync-Fix-a-race-condition-when-waiting-on-a-m.patch rename to 0006-proton-esync-fsync/0210-ntdll-fsync-Fix-a-race-condition-when-waiting-on-a-m.patch diff --git a/0007-proton-esync-fsync/0211-ntdll-fsync-Introduce-a-configurable-spin-count.patch b/0006-proton-esync-fsync/0211-ntdll-fsync-Introduce-a-configurable-spin-count.patch similarity index 100% rename from 0007-proton-esync-fsync/0211-ntdll-fsync-Introduce-a-configurable-spin-count.patch rename to 0006-proton-esync-fsync/0211-ntdll-fsync-Introduce-a-configurable-spin-count.patch diff --git a/0007-proton-esync-fsync/0212-ntdll-server-Abandon-fsync-mutexes-on-thread-exit.patch b/0006-proton-esync-fsync/0212-ntdll-server-Abandon-fsync-mutexes-on-thread-exit.patch similarity index 100% rename from 0007-proton-esync-fsync/0212-ntdll-server-Abandon-fsync-mutexes-on-thread-exit.patch rename to 0006-proton-esync-fsync/0212-ntdll-server-Abandon-fsync-mutexes-on-thread-exit.patch diff --git a/0007-proton-esync-fsync/0213-ntdll-Default-the-spin-count-to-100.patch b/0006-proton-esync-fsync/0213-ntdll-Default-the-spin-count-to-100.patch similarity index 100% rename from 0007-proton-esync-fsync/0213-ntdll-Default-the-spin-count-to-100.patch rename to 0006-proton-esync-fsync/0213-ntdll-Default-the-spin-count-to-100.patch diff --git a/0007-proton-esync-fsync/0214-ntdll-Implement-an-esync-fsync-path-for-alertable-Nt.patch b/0006-proton-esync-fsync/0214-ntdll-Implement-an-esync-fsync-path-for-alertable-Nt.patch similarity index 100% rename from 0007-proton-esync-fsync/0214-ntdll-Implement-an-esync-fsync-path-for-alertable-Nt.patch rename to 0006-proton-esync-fsync/0214-ntdll-Implement-an-esync-fsync-path-for-alertable-Nt.patch diff --git a/0007-proton-esync-fsync/0215-esync-fsync-Use-usleep-0-instead-of-NtYieldExecution.patch b/0006-proton-esync-fsync/0215-esync-fsync-Use-usleep-0-instead-of-NtYieldExecution.patch similarity index 100% rename from 0007-proton-esync-fsync/0215-esync-fsync-Use-usleep-0-instead-of-NtYieldExecution.patch rename to 0006-proton-esync-fsync/0215-esync-fsync-Use-usleep-0-instead-of-NtYieldExecution.patch diff --git a/0007-proton-esync-fsync/0216-ntdll-Call-waitv-just-when-nr_futexes-1.patch b/0006-proton-esync-fsync/0216-ntdll-Call-waitv-just-when-nr_futexes-1.patch similarity index 100% rename from 0007-proton-esync-fsync/0216-ntdll-Call-waitv-just-when-nr_futexes-1.patch rename to 0006-proton-esync-fsync/0216-ntdll-Call-waitv-just-when-nr_futexes-1.patch diff --git a/0007-proton-esync-fsync/0217-ntdll-fsync-Encapsulate-timeout-conversion.patch b/0006-proton-esync-fsync/0217-ntdll-fsync-Encapsulate-timeout-conversion.patch similarity index 100% rename from 0007-proton-esync-fsync/0217-ntdll-fsync-Encapsulate-timeout-conversion.patch rename to 0006-proton-esync-fsync/0217-ntdll-fsync-Encapsulate-timeout-conversion.patch diff --git a/0007-proton-esync-fsync/0218-ntdll-fsync-Support-futex_waitv-API.patch b/0006-proton-esync-fsync/0218-ntdll-fsync-Support-futex_waitv-API.patch similarity index 100% rename from 0007-proton-esync-fsync/0218-ntdll-fsync-Support-futex_waitv-API.patch rename to 0006-proton-esync-fsync/0218-ntdll-fsync-Support-futex_waitv-API.patch diff --git a/0007-proton-esync-fsync/0219-ntdll-fsync-Use-absolute-timeouts-for-futex_wait.patch b/0006-proton-esync-fsync/0219-ntdll-fsync-Use-absolute-timeouts-for-futex_wait.patch similarity index 100% rename from 0007-proton-esync-fsync/0219-ntdll-fsync-Use-absolute-timeouts-for-futex_wait.patch rename to 0006-proton-esync-fsync/0219-ntdll-fsync-Use-absolute-timeouts-for-futex_wait.patch diff --git a/0007-proton-esync-fsync/0220-esync-fsync-Yield-execution-before-alertable-wait-fo.patch b/0006-proton-esync-fsync/0220-esync-fsync-Yield-execution-before-alertable-wait-fo.patch similarity index 100% rename from 0007-proton-esync-fsync/0220-esync-fsync-Yield-execution-before-alertable-wait-fo.patch rename to 0006-proton-esync-fsync/0220-esync-fsync-Yield-execution-before-alertable-wait-fo.patch diff --git a/0007-proton-esync-fsync/0221-fsync-Add-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-config-o.patch b/0006-proton-esync-fsync/0221-fsync-Add-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-config-o.patch similarity index 100% rename from 0007-proton-esync-fsync/0221-fsync-Add-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-config-o.patch rename to 0006-proton-esync-fsync/0221-fsync-Add-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-config-o.patch diff --git a/0007-proton-esync-fsync/0222-esync-Type-check-HANDLE-in-esync_set_event.patch b/0006-proton-esync-fsync/0222-esync-Type-check-HANDLE-in-esync_set_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0222-esync-Type-check-HANDLE-in-esync_set_event.patch rename to 0006-proton-esync-fsync/0222-esync-Type-check-HANDLE-in-esync_set_event.patch diff --git a/0007-proton-esync-fsync/0223-fsync-Type-check-HANDLE-in-fsync_set_event.patch b/0006-proton-esync-fsync/0223-fsync-Type-check-HANDLE-in-fsync_set_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0223-fsync-Type-check-HANDLE-in-fsync_set_event.patch rename to 0006-proton-esync-fsync/0223-fsync-Type-check-HANDLE-in-fsync_set_event.patch diff --git a/0007-proton-esync-fsync/0224-fsync-Fix-semaphore-grab-attempt-on-wait-all-path.patch b/0006-proton-esync-fsync/0224-fsync-Fix-semaphore-grab-attempt-on-wait-all-path.patch similarity index 100% rename from 0007-proton-esync-fsync/0224-fsync-Fix-semaphore-grab-attempt-on-wait-all-path.patch rename to 0006-proton-esync-fsync/0224-fsync-Fix-semaphore-grab-attempt-on-wait-all-path.patch diff --git a/0007-proton-esync-fsync/0225-fsync-Always-check-for-NULL-object-on-wait-all-path.patch b/0006-proton-esync-fsync/0225-fsync-Always-check-for-NULL-object-on-wait-all-path.patch similarity index 100% rename from 0007-proton-esync-fsync/0225-fsync-Always-check-for-NULL-object-on-wait-all-path.patch rename to 0006-proton-esync-fsync/0225-fsync-Always-check-for-NULL-object-on-wait-all-path.patch diff --git a/0007-proton-esync-fsync/0226-fsync-Get-rid-of-spin-before-futex-wait.patch b/0006-proton-esync-fsync/0226-fsync-Get-rid-of-spin-before-futex-wait.patch similarity index 100% rename from 0007-proton-esync-fsync/0226-fsync-Get-rid-of-spin-before-futex-wait.patch rename to 0006-proton-esync-fsync/0226-fsync-Get-rid-of-spin-before-futex-wait.patch diff --git a/0007-proton-esync-fsync/0227-fsync-Always-use-futex_waitv-for-wait.patch b/0006-proton-esync-fsync/0227-fsync-Always-use-futex_waitv-for-wait.patch similarity index 100% rename from 0007-proton-esync-fsync/0227-fsync-Always-use-futex_waitv-for-wait.patch rename to 0006-proton-esync-fsync/0227-fsync-Always-use-futex_waitv-for-wait.patch diff --git a/0007-proton-esync-fsync/0228-ntdll-Include-linux-futex.h-in-fsync.c.patch b/0006-proton-esync-fsync/0228-ntdll-Include-linux-futex.h-in-fsync.c.patch similarity index 100% rename from 0007-proton-esync-fsync/0228-ntdll-Include-linux-futex.h-in-fsync.c.patch rename to 0006-proton-esync-fsync/0228-ntdll-Include-linux-futex.h-in-fsync.c.patch diff --git a/0007-proton-esync-fsync/0229-fsync-Reuse-shared-mem-indices.patch b/0006-proton-esync-fsync/0229-fsync-Reuse-shared-mem-indices.patch similarity index 100% rename from 0007-proton-esync-fsync/0229-fsync-Reuse-shared-mem-indices.patch rename to 0006-proton-esync-fsync/0229-fsync-Reuse-shared-mem-indices.patch diff --git a/0007-proton-esync-fsync/0230-fsync-Use-CLOCK_MONOTONIC-for-relative-timeouts.patch b/0006-proton-esync-fsync/0230-fsync-Use-CLOCK_MONOTONIC-for-relative-timeouts.patch similarity index 100% rename from 0007-proton-esync-fsync/0230-fsync-Use-CLOCK_MONOTONIC-for-relative-timeouts.patch rename to 0006-proton-esync-fsync/0230-fsync-Use-CLOCK_MONOTONIC-for-relative-timeouts.patch diff --git a/0007-proton-esync-fsync/0231-fsync-Return-a-copy-of-the-object-instead-of-cache-p.patch b/0006-proton-esync-fsync/0231-fsync-Return-a-copy-of-the-object-instead-of-cache-p.patch similarity index 100% rename from 0007-proton-esync-fsync/0231-fsync-Return-a-copy-of-the-object-instead-of-cache-p.patch rename to 0006-proton-esync-fsync/0231-fsync-Return-a-copy-of-the-object-instead-of-cache-p.patch diff --git a/0007-proton-esync-fsync/0232-esync-fsync-Support-waiting-on-file-handles.patch b/0006-proton-esync-fsync/0232-esync-fsync-Support-waiting-on-file-handles.patch similarity index 100% rename from 0007-proton-esync-fsync/0232-esync-fsync-Support-waiting-on-file-handles.patch rename to 0006-proton-esync-fsync/0232-esync-fsync-Support-waiting-on-file-handles.patch diff --git a/0007-proton-esync-fsync/0233-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-P.patch b/0006-proton-esync-fsync/0233-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-P.patch similarity index 100% rename from 0007-proton-esync-fsync/0233-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-P.patch rename to 0006-proton-esync-fsync/0233-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-P.patch diff --git a/0007-proton-esync-fsync/0234-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-G.patch b/0006-proton-esync-fsync/0234-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-G.patch similarity index 100% rename from 0007-proton-esync-fsync/0234-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-G.patch rename to 0006-proton-esync-fsync/0234-ntdll-Enable-WINE_FSYNC_SIMULATE_SCHED_QUANTUM-for-G.patch diff --git a/0007-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch b/0006-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch similarity index 65% rename from 0007-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch rename to 0006-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch index 5d5b7c2..8b27851 100644 --- a/0007-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch +++ b/0006-proton-esync-fsync/0235-ntdll-HACK-Add-WINE_ALERT_SIMULATE_SCHED_QUANTUM-opt.patch @@ -42,34 +42,34 @@ index 8d8c1700937..60488301f16 100644 switch (sgi ? atoi( sgi ) : -1) { case 25700: /* Madballs in Babo: Invasion */ -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index f83a81afd9a..ed30388b026 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -2706,6 +2706,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) - { - union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread ); -+ BOOL waited = FALSE; - - TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); - -@@ -2741,8 +2742,15 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - else - ret = futex_wait( futex, 0, NULL ); - -+ if (!timeout || timeout->QuadPart) -+ waited = TRUE; -+ - if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT; - } -+ -+ if (alert_simulate_sched_quantum && waited) -+ usleep(0); -+ - return STATUS_ALERTED; - } - #endif +#diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +#index f83a81afd9a..ed30388b026 100644 +#--- a/dlls/ntdll/unix/sync.c +#+++ b/dlls/ntdll/unix/sync.c +#@@ -2706,6 +2706,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG +# NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) +# { +# union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread ); +#+ BOOL waited = FALSE; +# +# TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); +# +#@@ -2741,8 +2742,15 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG +# else +# ret = futex_wait( futex, 0, NULL ); +# +#+ if (!timeout || timeout->QuadPart) +#+ waited = TRUE; +#+ +# if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT; +# } +#+ +#+ if (alert_simulate_sched_quantum && waited) +#+ usleep(0); +#+ +# return STATUS_ALERTED; +# } +# #endif diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index cc5f1ffc9e0..92668512e90 100644 --- a/dlls/ntdll/unix/unix_private.h diff --git a/0007-proton-esync-fsync/0236-ntdll-HACK-Also-simulate-async-file-read-and-IO-canc.patch b/0006-proton-esync-fsync/0236-ntdll-HACK-Also-simulate-async-file-read-and-IO-canc.patch similarity index 100% rename from 0007-proton-esync-fsync/0236-ntdll-HACK-Also-simulate-async-file-read-and-IO-canc.patch rename to 0006-proton-esync-fsync/0236-ntdll-HACK-Also-simulate-async-file-read-and-IO-canc.patch diff --git a/0007-proton-esync-fsync/0237-fsync-Retry-grabbing-semaphore-if-count-has-changed.patch b/0006-proton-esync-fsync/0237-fsync-Retry-grabbing-semaphore-if-count-has-changed.patch similarity index 100% rename from 0007-proton-esync-fsync/0237-fsync-Retry-grabbing-semaphore-if-count-has-changed.patch rename to 0006-proton-esync-fsync/0237-fsync-Retry-grabbing-semaphore-if-count-has-changed.patch diff --git a/0007-proton-esync-fsync/0238-fsync-Cache-current-TID-in-__fsync_wait_objects.patch b/0006-proton-esync-fsync/0238-fsync-Cache-current-TID-in-__fsync_wait_objects.patch similarity index 100% rename from 0007-proton-esync-fsync/0238-fsync-Cache-current-TID-in-__fsync_wait_objects.patch rename to 0006-proton-esync-fsync/0238-fsync-Cache-current-TID-in-__fsync_wait_objects.patch diff --git a/0007-proton-esync-fsync/0239-fsync-Avoid-race-between-NtClose-and-get_object.patch b/0006-proton-esync-fsync/0239-fsync-Avoid-race-between-NtClose-and-get_object.patch similarity index 100% rename from 0007-proton-esync-fsync/0239-fsync-Avoid-race-between-NtClose-and-get_object.patch rename to 0006-proton-esync-fsync/0239-fsync-Avoid-race-between-NtClose-and-get_object.patch diff --git a/0007-proton-esync-fsync/0240-fsync-Check-for-NULL-handle-in-get_object.patch b/0006-proton-esync-fsync/0240-fsync-Check-for-NULL-handle-in-get_object.patch similarity index 100% rename from 0007-proton-esync-fsync/0240-fsync-Check-for-NULL-handle-in-get_object.patch rename to 0006-proton-esync-fsync/0240-fsync-Check-for-NULL-handle-in-get_object.patch diff --git a/0007-proton-esync-fsync/0241-fsync-Type-check-HANDLE-in-fsync_reset_event.patch b/0006-proton-esync-fsync/0241-fsync-Type-check-HANDLE-in-fsync_reset_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0241-fsync-Type-check-HANDLE-in-fsync_reset_event.patch rename to 0006-proton-esync-fsync/0241-fsync-Type-check-HANDLE-in-fsync_reset_event.patch diff --git a/0007-proton-esync-fsync/0242-fsync-Type-check-HANDLE-in-fsync_pulse_event.patch b/0006-proton-esync-fsync/0242-fsync-Type-check-HANDLE-in-fsync_pulse_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0242-fsync-Type-check-HANDLE-in-fsync_pulse_event.patch rename to 0006-proton-esync-fsync/0242-fsync-Type-check-HANDLE-in-fsync_pulse_event.patch diff --git a/0007-proton-esync-fsync/0243-esync-Type-check-HANDLE-in-esync_reset_event.patch b/0006-proton-esync-fsync/0243-esync-Type-check-HANDLE-in-esync_reset_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0243-esync-Type-check-HANDLE-in-esync_reset_event.patch rename to 0006-proton-esync-fsync/0243-esync-Type-check-HANDLE-in-esync_reset_event.patch diff --git a/0007-proton-esync-fsync/0244-esync-Type-check-HANDLE-in-esync_pulse_event.patch b/0006-proton-esync-fsync/0244-esync-Type-check-HANDLE-in-esync_pulse_event.patch similarity index 100% rename from 0007-proton-esync-fsync/0244-esync-Type-check-HANDLE-in-esync_pulse_event.patch rename to 0006-proton-esync-fsync/0244-esync-Type-check-HANDLE-in-esync_pulse_event.patch diff --git a/0007-proton-esync-fsync/0245-ntdll-HACK-Add-WINE_NO_PRIV_ELEVATION-option-and-aut.patch b/0006-proton-esync-fsync/0245-ntdll-HACK-Add-WINE_NO_PRIV_ELEVATION-option-and-aut.patch similarity index 100% rename from 0007-proton-esync-fsync/0245-ntdll-HACK-Add-WINE_NO_PRIV_ELEVATION-option-and-aut.patch rename to 0006-proton-esync-fsync/0245-ntdll-HACK-Add-WINE_NO_PRIV_ELEVATION-option-and-aut.patch diff --git a/0007-proton-esync-fsync/0246-ntdll-Don-t-leak-objattr-allocation-in-NtCreateSemap.patch b/0006-proton-esync-fsync/0246-ntdll-Don-t-leak-objattr-allocation-in-NtCreateSemap.patch similarity index 100% rename from 0007-proton-esync-fsync/0246-ntdll-Don-t-leak-objattr-allocation-in-NtCreateSemap.patch rename to 0006-proton-esync-fsync/0246-ntdll-Don-t-leak-objattr-allocation-in-NtCreateSemap.patch diff --git a/0007-proton-esync-fsync/0247-ntdll-Introduce-a-separate-per-thread-object-for-int.patch b/0006-proton-esync-fsync/0247-ntdll-Introduce-a-separate-per-thread-object-for-int.patch similarity index 100% rename from 0007-proton-esync-fsync/0247-ntdll-Introduce-a-separate-per-thread-object-for-int.patch rename to 0006-proton-esync-fsync/0247-ntdll-Introduce-a-separate-per-thread-object-for-int.patch diff --git a/0007-proton-esync-fsync/0248-ntdll-Assign-completion-to-thread-when-wait-for-comp.patch b/0006-proton-esync-fsync/0248-ntdll-Assign-completion-to-thread-when-wait-for-comp.patch similarity index 100% rename from 0007-proton-esync-fsync/0248-ntdll-Assign-completion-to-thread-when-wait-for-comp.patch rename to 0006-proton-esync-fsync/0248-ntdll-Assign-completion-to-thread-when-wait-for-comp.patch diff --git a/0007-proton-esync-fsync/0249-ntdll-Handle-user-APCs-explicitly-in-NtRemoveIoCompl.patch b/0006-proton-esync-fsync/0249-ntdll-Handle-user-APCs-explicitly-in-NtRemoveIoCompl.patch similarity index 100% rename from 0007-proton-esync-fsync/0249-ntdll-Handle-user-APCs-explicitly-in-NtRemoveIoCompl.patch rename to 0006-proton-esync-fsync/0249-ntdll-Handle-user-APCs-explicitly-in-NtRemoveIoCompl.patch diff --git a/0007-proton-esync-fsync/0250-server-Signal-completion-port-waits-on-handle-close.patch b/0006-proton-esync-fsync/0250-server-Signal-completion-port-waits-on-handle-close.patch similarity index 100% rename from 0007-proton-esync-fsync/0250-server-Signal-completion-port-waits-on-handle-close.patch rename to 0006-proton-esync-fsync/0250-server-Signal-completion-port-waits-on-handle-close.patch diff --git a/0007-proton-esync-fsync/0251-kernelbase-Set-the-proper-error-code-in-GetQueuedCom.patch b/0006-proton-esync-fsync/0251-kernelbase-Set-the-proper-error-code-in-GetQueuedCom.patch similarity index 100% rename from 0007-proton-esync-fsync/0251-kernelbase-Set-the-proper-error-code-in-GetQueuedCom.patch rename to 0006-proton-esync-fsync/0251-kernelbase-Set-the-proper-error-code-in-GetQueuedCom.patch diff --git a/0007-proton-esync-fsync/0252-ntdll-tests-Add-tests-for-completion-port-signaling.patch b/0006-proton-esync-fsync/0252-ntdll-tests-Add-tests-for-completion-port-signaling.patch similarity index 100% rename from 0007-proton-esync-fsync/0252-ntdll-tests-Add-tests-for-completion-port-signaling.patch rename to 0006-proton-esync-fsync/0252-ntdll-tests-Add-tests-for-completion-port-signaling.patch diff --git a/0007-proton-esync-fsync/0253-ntdll-fsync-Introduce-explicit-server-wait-helper-an.patch b/0006-proton-esync-fsync/0253-ntdll-fsync-Introduce-explicit-server-wait-helper-an.patch similarity index 100% rename from 0007-proton-esync-fsync/0253-ntdll-fsync-Introduce-explicit-server-wait-helper-an.patch rename to 0006-proton-esync-fsync/0253-ntdll-fsync-Introduce-explicit-server-wait-helper-an.patch diff --git a/0007-proton-esync-fsync/0254-esync-fsync-Support-wait-on-completion-ports.patch b/0006-proton-esync-fsync/0254-esync-fsync-Support-wait-on-completion-ports.patch similarity index 100% rename from 0007-proton-esync-fsync/0254-esync-fsync-Support-wait-on-completion-ports.patch rename to 0006-proton-esync-fsync/0254-esync-fsync-Support-wait-on-completion-ports.patch diff --git a/0007-proton-esync-fsync/0255-ntdll-esync-fsync-Check-for-port-signal-state-for-ze.patch b/0006-proton-esync-fsync/0255-ntdll-esync-fsync-Check-for-port-signal-state-for-ze.patch similarity index 100% rename from 0007-proton-esync-fsync/0255-ntdll-esync-fsync-Check-for-port-signal-state-for-ze.patch rename to 0006-proton-esync-fsync/0255-ntdll-esync-fsync-Check-for-port-signal-state-for-ze.patch diff --git a/0007-proton-esync-fsync/0256-fixup-server-ntdll-Implement-message-waits.patch b/0006-proton-esync-fsync/0256-fixup-server-ntdll-Implement-message-waits.patch similarity index 100% rename from 0007-proton-esync-fsync/0256-fixup-server-ntdll-Implement-message-waits.patch rename to 0006-proton-esync-fsync/0256-fixup-server-ntdll-Implement-message-waits.patch diff --git a/0007-proton-esync-fsync/0257-HACK-user32-Always-call-get_message-request-after-wa.patch b/0006-proton-esync-fsync/0257-HACK-user32-Always-call-get_message-request-after-wa.patch similarity index 100% rename from 0007-proton-esync-fsync/0257-HACK-user32-Always-call-get_message-request-after-wa.patch rename to 0006-proton-esync-fsync/0257-HACK-user32-Always-call-get_message-request-after-wa.patch diff --git a/0007-proton-esync-fsync/0258-fsync-cache-all-tids.patch b/0006-proton-esync-fsync/0258-fsync-cache-all-tids.patch similarity index 100% rename from 0007-proton-esync-fsync/0258-fsync-cache-all-tids.patch rename to 0006-proton-esync-fsync/0258-fsync-cache-all-tids.patch diff --git a/0007-proton-esync-fsync/0259-fsync-clean-up-hacks.patch b/0006-proton-esync-fsync/0259-fsync-clean-up-hacks.patch similarity index 100% rename from 0007-proton-esync-fsync/0259-fsync-clean-up-hacks.patch rename to 0006-proton-esync-fsync/0259-fsync-clean-up-hacks.patch diff --git a/0007-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch b/0006-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch similarity index 98% rename from 0007-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch rename to 0006-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch index ace35f7..7b0292d 100644 --- a/0007-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch +++ b/0006-proton-esync-fsync/0261-fsync-Use-monitorx-mwaitx-and-spin-before-relying-on.patch @@ -46,7 +46,7 @@ index 169ceab10ad..40b10b0d8d2 100644 +#define CHECK_VALUE_CHANGED( addr, expected, observed ) \ + do \ + { \ -+ int __val = __atomic_load_n( (addr), __ATOMIC_SEQ_CST ); \ ++ int __val = __atomic_load_n( (addr), __ATOMIC_ACQUIRE ); \ + if (__val != (expected)) \ + { \ + if (observed) \ @@ -108,7 +108,7 @@ index 169ceab10ad..40b10b0d8d2 100644 + + if (attempts < SPIN_MAX_RETRIES) + { -+ volatile int i; ++ int i; + for (i = 0; i != 1 << attempts; i++) + { + YieldProcessor(); @@ -122,7 +122,7 @@ index 169ceab10ad..40b10b0d8d2 100644 + } + + if (observed_val) -+ *observed_val = __atomic_load_n( addr, __ATOMIC_SEQ_CST ); ++ *observed_val = __atomic_load_n( addr, __ATOMIC_ACQUIRE ); + return STATUS_UNSUCCESSFUL; +} + diff --git a/0007-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_wait_s.patch b/0006-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_acquire.patch similarity index 99% rename from 0007-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_wait_s.patch rename to 0006-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_acquire.patch index cc837d8..f0eb19d 100644 --- a/0007-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_wait_s.patch +++ b/0006-proton-esync-fsync/0262-fsync-Don-t-spin-on-zero-timeouts-and-fix-try_acquire.patch @@ -2,7 +2,7 @@ From a0642db0c5a57d93c66193a14a8eb4da28f84359 Mon Sep 17 00:00:00 2001 From: William Horvath Date: Mon, 16 Dec 2024 00:43:14 -0800 Subject: [PATCH] fsync: Don't spin on zero timeouts, and fix - try_wait_semaphore logic. + try_acquire_semaphore logic. --- dlls/ntdll/unix/fsync.c | 28 +++++++++++++--------------- diff --git a/0007-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch b/0006-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch similarity index 100% rename from 0007-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch rename to 0006-proton-esync-fsync/0300-esync-fsync-Prevent-div-by-zero-pagesize-in-init-cre.patch diff --git a/0007-ntsync/0002-gcc-13-warnings.patch b/0007-ntsync/0002-gcc-13-warnings.patch new file mode 100644 index 0000000..8be3e9c --- /dev/null +++ b/0007-ntsync/0002-gcc-13-warnings.patch @@ -0,0 +1,27 @@ +From 2d000d05e050d33c928dfecb4ebcafa35179483d Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 31 Oct 2023 12:23:30 -0500 +Subject: [PATCH 02/32] gcc 13 warnings + +--- + dlls/webservices/tests/channel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/dlls/webservices/tests/channel.c b/dlls/webservices/tests/channel.c +index 4cf39c10732..1fb12297eef 100644 +--- a/dlls/webservices/tests/channel.c ++++ b/dlls/webservices/tests/channel.c +@@ -1214,6 +1214,9 @@ static const char send_record_begin[] = { + static const char send_record_middle[] = { 0x01, 0x56, 0x0e, 0x42 }; + static const char send_record_end[] = { 0x08, 0x02, 0x6e, 0x73, 0x89, 0xff, 0x01, 0x01 }; + ++#pragma GCC diagnostic ignored "-Warray-bounds" ++#pragma GCC diagnostic ignored "-Wstringop-overflow" ++ + static BOOL send_dict_str( int sock, char *addr, const char *str, int dict_str_count ) + { + char buf[512], dict_buf[256], body_buf[128], dict_size_buf[5]; +-- +2.47.1 + + diff --git a/0007-ntsync/0003-server-Add-an-object-operation-to-retrieve-an-in-process-synchronization-object.patch b/0007-ntsync/0003-server-Add-an-object-operation-to-retrieve-an-in-process-synchronization-object.patch new file mode 100644 index 0000000..a9135d5 --- /dev/null +++ b/0007-ntsync/0003-server-Add-an-object-operation-to-retrieve-an-in-process-synchronization-object.patch @@ -0,0 +1,807 @@ +From ce77469e02f347bb201e65aad25d3dbe47b86ab3 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 22:31:06 +0200 +Subject: [PATCH 03/32] server: Add an object operation to retrieve an + in-process synchronization object. + +--- + server/async.c | 2 ++ + server/atom.c | 1 + + server/change.c | 1 + + server/clipboard.c | 1 + + server/completion.c | 2 ++ + server/console.c | 7 +++++++ + server/debugger.c | 2 ++ + server/device.c | 4 ++++ + server/directory.c | 2 ++ + server/esync.c | 1 + + server/event.c | 2 ++ + server/fd.c | 4 ++++ + server/file.c | 1 + + server/fsync.c | 1 + + server/handle.c | 1 + + server/hook.c | 1 + + server/mailslot.c | 4 ++++ + server/mapping.c | 3 +++ + server/mutex.c | 1 + + server/named_pipe.c | 5 +++++ + server/object.c | 6 ++++++ + server/object.h | 7 +++++++ + server/process.c | 3 +++ + server/protocol.def | 12 ++++++++++++ + server/queue.c | 2 ++ + server/registry.c | 1 + + server/request.c | 1 + + server/semaphore.c | 1 + + server/serial.c | 1 + + server/signal.c | 1 + + server/sock.c | 3 +++ + server/symlink.c | 1 + + server/thread.c | 3 +++ + server/timer.c | 1 + + server/token.c | 1 + + server/window.c | 1 + + server/winstation.c | 2 ++ + 37 files changed, 93 insertions(+) + +diff --git a/server/async.c b/server/async.c +index 1f32d10a0f5..713f560d511 100644 +--- a/server/async.c ++++ b/server/async.c +@@ -92,6 +92,7 @@ static const struct object_ops async_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + async_destroy /* destroy */ + }; +@@ -714,6 +715,7 @@ static const struct object_ops iosb_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + iosb_destroy /* destroy */ + }; +diff --git a/server/atom.c b/server/atom.c +index 6b95a546597..25d7f6041c2 100644 +--- a/server/atom.c ++++ b/server/atom.c +@@ -93,6 +93,7 @@ static const struct object_ops atom_table_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + atom_table_destroy /* destroy */ + }; +diff --git a/server/change.c b/server/change.c +index 8a97b66409d..c1040194ad0 100644 +--- a/server/change.c ++++ b/server/change.c +@@ -126,6 +126,7 @@ static const struct object_ops dir_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + dir_close_handle, /* close_handle */ + dir_destroy /* destroy */ + }; +diff --git a/server/clipboard.c b/server/clipboard.c +index f24924eafa5..bf20515ee30 100644 +--- a/server/clipboard.c ++++ b/server/clipboard.c +@@ -90,6 +90,7 @@ static const struct object_ops clipboard_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + clipboard_destroy /* destroy */ + }; +diff --git a/server/completion.c b/server/completion.c +index 580f83b4a82..a8c3e2ce6bc 100644 +--- a/server/completion.c ++++ b/server/completion.c +@@ -110,6 +110,7 @@ static const struct object_ops completion_wait_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + completion_wait_destroy /* destroy */ + }; +@@ -193,6 +194,7 @@ static const struct object_ops completion_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + completion_close_handle, /* close_handle */ + completion_destroy /* destroy */ + }; +diff --git a/server/console.c b/server/console.c +index 9084e5a3828..fcd70f21dd0 100644 +--- a/server/console.c ++++ b/server/console.c +@@ -97,6 +97,7 @@ static const struct object_ops console_ops = + NULL, /* unlink_name */ + console_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_destroy /* destroy */ + }; +@@ -180,6 +181,7 @@ static const struct object_ops console_server_ops = + NULL, /* unlink_name */ + console_server_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_server_destroy /* destroy */ + }; +@@ -251,6 +253,7 @@ static const struct object_ops screen_buffer_ops = + NULL, /* unlink_name */ + screen_buffer_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + screen_buffer_destroy /* destroy */ + }; +@@ -302,6 +305,7 @@ static const struct object_ops console_device_ops = + default_unlink_name, /* unlink_name */ + console_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +@@ -341,6 +345,7 @@ static const struct object_ops console_input_ops = + default_unlink_name, /* unlink_name */ + console_input_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_input_destroy /* destroy */ + }; +@@ -400,6 +405,7 @@ static const struct object_ops console_output_ops = + default_unlink_name, /* unlink_name */ + console_output_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_output_destroy /* destroy */ + }; +@@ -460,6 +466,7 @@ static const struct object_ops console_connection_ops = + default_unlink_name, /* unlink_name */ + console_connection_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + console_connection_close_handle, /* close_handle */ + console_connection_destroy /* destroy */ + }; +diff --git a/server/debugger.c b/server/debugger.c +index b0cd35604d2..35c93d3c948 100644 +--- a/server/debugger.c ++++ b/server/debugger.c +@@ -100,6 +100,7 @@ static const struct object_ops debug_event_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + debug_event_destroy /* destroy */ + }; +@@ -130,6 +131,7 @@ static const struct object_ops debug_obj_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + debug_obj_destroy /* destroy */ + }; +diff --git a/server/device.c b/server/device.c +index 7e9911efb6a..a0216152ea7 100644 +--- a/server/device.c ++++ b/server/device.c +@@ -82,6 +82,7 @@ static const struct object_ops irp_call_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + irp_call_destroy /* destroy */ + }; +@@ -128,6 +129,7 @@ static const struct object_ops device_manager_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + device_manager_destroy /* destroy */ + }; +@@ -187,6 +189,7 @@ static const struct object_ops device_ops = + default_unlink_name, /* unlink_name */ + device_open_file, /* open_file */ + device_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + device_destroy /* destroy */ + }; +@@ -241,6 +244,7 @@ static const struct object_ops device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + device_file_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + device_file_close_handle, /* close_handle */ + device_file_destroy /* destroy */ + }; +diff --git a/server/directory.c b/server/directory.c +index 878941cddbf..ab07a64c73d 100644 +--- a/server/directory.c ++++ b/server/directory.c +@@ -84,6 +84,7 @@ static const struct object_ops object_type_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +@@ -136,6 +137,7 @@ static const struct object_ops directory_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + directory_destroy /* destroy */ + }; +diff --git a/server/esync.c b/server/esync.c +index a5164435ed6..24f3d41ad77 100644 +--- a/server/esync.c ++++ b/server/esync.c +@@ -143,6 +143,7 @@ const struct object_ops esync_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + esync_destroy /* destroy */ + }; +diff --git a/server/event.c b/server/event.c +index b93a9960ad2..80c8df69252 100644 +--- a/server/event.c ++++ b/server/event.c +@@ -93,6 +93,7 @@ static const struct object_ops event_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + event_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + event_destroy /* destroy */ + }; +@@ -142,6 +143,7 @@ static const struct object_ops keyed_event_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +diff --git a/server/fd.c b/server/fd.c +index 85676910e3f..08025a999a6 100644 +--- a/server/fd.c ++++ b/server/fd.c +@@ -187,6 +187,7 @@ static const struct object_ops fd_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + fd_destroy /* destroy */ + }; +@@ -230,6 +231,7 @@ static const struct object_ops device_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + device_destroy /* destroy */ + }; +@@ -272,6 +274,7 @@ static const struct object_ops inode_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + inode_destroy /* destroy */ + }; +@@ -316,6 +319,7 @@ static const struct object_ops file_lock_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +diff --git a/server/file.c b/server/file.c +index 3d9bb46c590..e4c00f30457 100644 +--- a/server/file.c ++++ b/server/file.c +@@ -137,6 +137,7 @@ static const struct object_ops file_ops = + NULL, /* unlink_name */ + file_open_file, /* open_file */ + file_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + file_destroy /* destroy */ + }; +diff --git a/server/fsync.c b/server/fsync.c +index dc50aa0a1f3..d41fee58c0b 100644 +--- a/server/fsync.c ++++ b/server/fsync.c +@@ -164,6 +164,7 @@ const struct object_ops fsync_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + fsync_destroy /* destroy */ + }; +diff --git a/server/handle.c b/server/handle.c +index 2f47442d1f8..0380cf03f9b 100644 +--- a/server/handle.c ++++ b/server/handle.c +@@ -140,6 +140,7 @@ static const struct object_ops handle_table_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + handle_table_destroy /* destroy */ + }; +diff --git a/server/hook.c b/server/hook.c +index 24eb27434db..1069af8dd43 100644 +--- a/server/hook.c ++++ b/server/hook.c +@@ -94,6 +94,7 @@ static const struct object_ops hook_table_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + hook_table_destroy /* destroy */ + }; +diff --git a/server/mailslot.c b/server/mailslot.c +index 41fb020aaf0..fb7c7914d5a 100644 +--- a/server/mailslot.c ++++ b/server/mailslot.c +@@ -88,6 +88,7 @@ static const struct object_ops mailslot_ops = + default_unlink_name, /* unlink_name */ + mailslot_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mailslot_destroy /* destroy */ + }; +@@ -149,6 +150,7 @@ static const struct object_ops mail_writer_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mail_writer_destroy /* destroy */ + }; +@@ -214,6 +216,7 @@ static const struct object_ops mailslot_device_ops = + default_unlink_name, /* unlink_name */ + mailslot_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mailslot_device_destroy /* destroy */ + }; +@@ -246,6 +249,7 @@ static const struct object_ops mailslot_device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mailslot_device_file_destroy /* destroy */ + }; +diff --git a/server/mapping.c b/server/mapping.c +index d6c6c46d7c4..4e725d90402 100644 +--- a/server/mapping.c ++++ b/server/mapping.c +@@ -86,6 +86,7 @@ static const struct object_ops ranges_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + ranges_destroy /* destroy */ + }; +@@ -124,6 +125,7 @@ static const struct object_ops shared_map_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + shared_map_destroy /* destroy */ + }; +@@ -202,6 +204,7 @@ static const struct object_ops mapping_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mapping_destroy /* destroy */ + }; +diff --git a/server/mutex.c b/server/mutex.c +index 2503d12057f..58ac83bd3f7 100644 +--- a/server/mutex.c ++++ b/server/mutex.c +@@ -87,6 +87,7 @@ static const struct object_ops mutex_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mutex_destroy /* destroy */ + }; +diff --git a/server/named_pipe.c b/server/named_pipe.c +index 59a90c36663..fd10bbc474a 100644 +--- a/server/named_pipe.c ++++ b/server/named_pipe.c +@@ -131,6 +131,7 @@ static const struct object_ops named_pipe_ops = + default_unlink_name, /* unlink_name */ + named_pipe_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_destroy /* destroy */ + }; +@@ -179,6 +180,7 @@ static const struct object_ops pipe_server_ops = + NULL, /* unlink_name */ + pipe_server_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + async_close_obj_handle, /* close_handle */ + pipe_server_destroy /* destroy */ + }; +@@ -223,6 +225,7 @@ static const struct object_ops pipe_client_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + async_close_obj_handle, /* close_handle */ + pipe_end_destroy /* destroy */ + }; +@@ -270,6 +273,7 @@ static const struct object_ops named_pipe_device_ops = + default_unlink_name, /* unlink_name */ + named_pipe_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_device_destroy /* destroy */ + }; +@@ -301,6 +305,7 @@ static const struct object_ops named_pipe_device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_device_file_destroy /* destroy */ + }; +@@ -351,6 +356,7 @@ static const struct object_ops named_pipe_dir_ops = + NULL, /* unlink_name */ + named_pipe_dir_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_dir_destroy /* destroy */ + }; +diff --git a/server/object.c b/server/object.c +index 29f1ea96129..1af3df77467 100644 +--- a/server/object.c ++++ b/server/object.c +@@ -538,6 +538,12 @@ struct fd *no_get_fd( struct object *obj ) + return NULL; + } + ++struct inproc_sync *no_get_inproc_sync( struct object *obj ) ++{ ++ set_error( STATUS_OBJECT_TYPE_MISMATCH ); ++ return NULL; ++} ++ + unsigned int default_map_access( struct object *obj, unsigned int access ) + { + return map_access( access, &obj->ops->type->mapping ); +diff --git a/server/object.h b/server/object.h +index 3b405e36db0..395b22e5dbc 100644 +--- a/server/object.h ++++ b/server/object.h +@@ -42,6 +42,7 @@ struct async; + struct async_queue; + struct winstation; + struct object_type; ++struct inproc_sync; + + + struct unicode_str +@@ -107,6 +108,8 @@ struct object_ops + unsigned int options); + /* return list of kernel objects */ + struct list *(*get_kernel_obj_list)(struct object *); ++ /* get a client-waitable in-process synchronization handle to this object */ ++ struct inproc_sync *(*get_inproc_sync)(struct object *); + /* close a handle to this object */ + int (*close_handle)(struct object *,struct process *,obj_handle_t); + /* destroy on refcount == 0 */ +@@ -226,6 +229,10 @@ extern void reset_event( struct event *event ); + + extern void abandon_mutexes( struct thread *thread ); + ++/* in-process synchronization functions */ ++ ++extern struct inproc_sync *no_get_inproc_sync( struct object *obj ); ++ + /* serial functions */ + + int get_serial_async_timeout(struct object *obj, int type, int count); +diff --git a/server/process.c b/server/process.c +index 2e46f71f25d..6d5140ab7b3 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -124,6 +124,7 @@ static const struct object_ops process_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + process_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + process_destroy /* destroy */ + }; +@@ -177,6 +178,7 @@ static const struct object_ops startup_info_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + startup_info_destroy /* destroy */ + }; +@@ -240,6 +242,7 @@ static const struct object_ops job_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + job_close_handle, /* close_handle */ + job_destroy /* destroy */ + }; +diff --git a/server/protocol.def b/server/protocol.def +index f52d2cf3b49..06dd44d3e79 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -4205,3 +4205,15 @@ enum fsync_type + unsigned int shm_idx; + @REPLY + @END ++ ++ ++enum inproc_sync_type ++{ ++ INPROC_SYNC_SEMAPHORE = 1, ++ INPROC_SYNC_MUTEX, ++ INPROC_SYNC_AUTO_EVENT, ++ INPROC_SYNC_MANUAL_EVENT, ++ INPROC_SYNC_AUTO_SERVER, ++ INPROC_SYNC_MANUAL_SERVER, ++ INPROC_SYNC_QUEUE, ++}; +diff --git a/server/queue.c b/server/queue.c +index 9a74e476483..ddcf45ff519 100644 +--- a/server/queue.c ++++ b/server/queue.c +@@ -190,6 +190,7 @@ static const struct object_ops msg_queue_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + msg_queue_destroy /* destroy */ + }; +@@ -229,6 +230,7 @@ static const struct object_ops thread_input_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + thread_input_destroy /* destroy */ + }; +diff --git a/server/registry.c b/server/registry.c +index c8de2376989..75a9f629afb 100644 +--- a/server/registry.c ++++ b/server/registry.c +@@ -195,6 +195,7 @@ static const struct object_ops key_ops = + key_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + key_close_handle, /* close_handle */ + key_destroy /* destroy */ + }; +diff --git a/server/request.c b/server/request.c +index 343e1a92e0e..0b915b06398 100644 +--- a/server/request.c ++++ b/server/request.c +@@ -104,6 +104,7 @@ static const struct object_ops master_socket_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + master_socket_destroy /* destroy */ + }; +diff --git a/server/semaphore.c b/server/semaphore.c +index d354892c224..567a922c0ac 100644 +--- a/server/semaphore.c ++++ b/server/semaphore.c +@@ -84,6 +84,7 @@ static const struct object_ops semaphore_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +diff --git a/server/serial.c b/server/serial.c +index 1915d00a977..d86bf283b3a 100644 +--- a/server/serial.c ++++ b/server/serial.c +@@ -99,6 +99,7 @@ static const struct object_ops serial_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + serial_destroy /* destroy */ + }; +diff --git a/server/signal.c b/server/signal.c +index 802b7f936b9..2f58105452f 100644 +--- a/server/signal.c ++++ b/server/signal.c +@@ -76,6 +76,7 @@ static const struct object_ops handler_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + handler_destroy /* destroy */ + }; +diff --git a/server/sock.c b/server/sock.c +index beb6b2921b3..f353e70e3aa 100644 +--- a/server/sock.c ++++ b/server/sock.c +@@ -485,6 +485,7 @@ static const struct object_ops sock_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + sock_close_handle, /* close_handle */ + sock_destroy /* destroy */ + }; +@@ -3618,6 +3619,7 @@ static const struct object_ops ifchange_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + ifchange_destroy /* destroy */ + }; +@@ -3841,6 +3843,7 @@ static const struct object_ops socket_device_ops = + default_unlink_name, /* unlink_name */ + socket_device_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +diff --git a/server/symlink.c b/server/symlink.c +index 47098fe5823..8f2a6916c65 100644 +--- a/server/symlink.c ++++ b/server/symlink.c +@@ -85,6 +85,7 @@ static const struct object_ops symlink_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + symlink_destroy /* destroy */ + }; +diff --git a/server/thread.c b/server/thread.c +index cbc41f6dcb4..30caeba7622 100644 +--- a/server/thread.c ++++ b/server/thread.c +@@ -116,6 +116,7 @@ static const struct object_ops thread_apc_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + thread_apc_destroy /* destroy */ + }; +@@ -160,6 +161,7 @@ static const struct object_ops context_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ + }; +@@ -213,6 +215,7 @@ static const struct object_ops thread_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + thread_get_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + destroy_thread /* destroy */ + }; +diff --git a/server/timer.c b/server/timer.c +index 884ace9376f..247b19c8305 100644 +--- a/server/timer.c ++++ b/server/timer.c +@@ -96,6 +96,7 @@ static const struct object_ops timer_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + timer_destroy /* destroy */ + }; +diff --git a/server/token.c b/server/token.c +index ec2d7539262..aec87715cc2 100644 +--- a/server/token.c ++++ b/server/token.c +@@ -162,6 +162,7 @@ static const struct object_ops token_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + token_destroy /* destroy */ + }; +diff --git a/server/window.c b/server/window.c +index 66e09719759..d66b60a004c 100644 +--- a/server/window.c ++++ b/server/window.c +@@ -121,6 +121,7 @@ static const struct object_ops window_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + window_destroy /* destroy */ + }; +diff --git a/server/winstation.c b/server/winstation.c +index 875e87ed6b2..01dbbb6e79f 100644 +--- a/server/winstation.c ++++ b/server/winstation.c +@@ -90,6 +90,7 @@ static const struct object_ops winstation_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + winstation_close_handle, /* close_handle */ + winstation_destroy /* destroy */ + }; +@@ -132,6 +133,7 @@ static const struct object_ops desktop_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ + desktop_close_handle, /* close_handle */ + desktop_destroy /* destroy */ + }; +-- +2.47.1 + + diff --git a/0007-ntsync/0004-server-Create-in-process-synchronization-objects-for-events.patch b/0007-ntsync/0004-server-Create-in-process-synchronization-objects-for-events.patch new file mode 100644 index 0000000..355b21e --- /dev/null +++ b/0007-ntsync/0004-server-Create-in-process-synchronization-objects-for-events.patch @@ -0,0 +1,450 @@ +From 5f9a69ce4639e6f9478ddf491ce0515df811775a Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 00:38:18 +0200 +Subject: [PATCH 04/32] server: Create in-process synchronization objects for + events. + +--- + configure.ac | 1 + + server/Makefile.in | 1 + + server/event.c | 22 +++- + server/inproc_sync.c | 304 +++++++++++++++++++++++++++++++++++++++++++ + server/object.h | 4 + + 5 files changed, 331 insertions(+), 1 deletion(-) + create mode 100644 server/inproc_sync.c + +diff --git a/configure.ac b/configure.ac +index 5756da2c4ab..244ab602f1b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -432,6 +432,7 @@ AC_CHECK_HEADERS(\ + linux/input.h \ + linux/ioctl.h \ + linux/major.h \ ++ linux/ntsync.h \ + linux/param.h \ + linux/seccomp.h \ + linux/serial.h \ +diff --git a/server/Makefile.in b/server/Makefile.in +index a98615cce72..963e0756584 100644 +--- a/server/Makefile.in ++++ b/server/Makefile.in +@@ -18,6 +18,7 @@ SOURCES = \ + fsync.c \ + handle.c \ + hook.c \ ++ inproc_sync.c \ + mach.c \ + mailslot.c \ + main.c \ +diff --git a/server/event.c b/server/event.c +index 80c8df69252..6a47cbec89e 100644 +--- a/server/event.c ++++ b/server/event.c +@@ -58,6 +58,7 @@ struct event + struct list kernel_object; /* list of kernel object pointers */ + int manual_reset; /* is it a manual reset event? */ + int signaled; /* event has been signaled */ ++ struct inproc_sync *inproc_sync;/* in-process synchronization object */ + int esync_fd; /* esync file descriptor */ + unsigned int fsync_idx; + }; +@@ -69,6 +70,7 @@ static int event_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int event_get_fsync_idx( struct object *obj, enum fsync_type *type ); + static int event_signal( struct object *obj, unsigned int access); + static struct list *event_get_kernel_obj_list( struct object *obj ); ++static struct inproc_sync *event_get_inproc_sync( struct object *obj ); + static void event_destroy( struct object *obj ); + + static const struct object_ops event_ops = +@@ -93,7 +95,7 @@ static const struct object_ops event_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + event_get_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ event_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + event_destroy /* destroy */ + }; +@@ -163,6 +165,7 @@ struct event *create_event( struct object *root, const struct unicode_str *name, + list_init( &event->kernel_object ); + event->manual_reset = manual_reset; + event->signaled = initial_state; ++ event->inproc_sync = NULL; + event->fsync_idx = 0; + + if (do_fsync()) +@@ -216,6 +219,7 @@ void set_event( struct event *event ) + event->signaled = 1; + /* wake up all waiters if manual reset, a single one otherwise */ + wake_up( &event->obj, !event->manual_reset ); ++ set_inproc_event( event->inproc_sync ); + } + + void reset_event( struct event *event ) +@@ -238,6 +242,8 @@ void reset_event( struct event *event ) + + if (do_esync()) + esync_clear( event->esync_fd ); ++ ++ reset_inproc_event( event->inproc_sync ); + } + + static void event_dump( struct object *obj, int verbose ) +@@ -297,6 +303,19 @@ static struct list *event_get_kernel_obj_list( struct object *obj ) + return &event->kernel_object; + } + ++static struct inproc_sync *event_get_inproc_sync( struct object *obj ) ++{ ++ struct event *event = (struct event *)obj; ++ ++ if (!event->inproc_sync) ++ { ++ enum inproc_sync_type type = event->manual_reset ? INPROC_SYNC_MANUAL_EVENT : INPROC_SYNC_AUTO_EVENT; ++ event->inproc_sync = create_inproc_event( type, event->signaled ); ++ } ++ if (event->inproc_sync) grab_object( event->inproc_sync ); ++ return event->inproc_sync; ++} ++ + static void event_destroy( struct object *obj ) + { + struct event *event = (struct event *)obj; +@@ -304,6 +323,7 @@ static void event_destroy( struct object *obj ) + if (do_esync()) + close( event->esync_fd ); + if (event->fsync_idx) fsync_free_shm_idx( event->fsync_idx ); ++ if (event->inproc_sync) release_object( event->inproc_sync ); + } + + struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name, +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +new file mode 100644 +index 00000000000..9054d48fca4 +--- /dev/null ++++ b/server/inproc_sync.c +@@ -0,0 +1,304 @@ ++/* ++ * In-process synchronization primitives ++ * ++ * Copyright (C) 2021-2022 Elizabeth Figura for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "ntstatus.h" ++#define WIN32_NO_STATUS ++#include "winternl.h" ++ ++#include "file.h" ++#include "thread.h" ++ ++#ifdef HAVE_LINUX_NTSYNC_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct linux_device ++{ ++ struct object obj; /* object header */ ++ struct fd *fd; /* fd for unix fd */ ++}; ++ ++static struct linux_device *linux_device_object; ++ ++static void linux_device_dump( struct object *obj, int verbose ); ++static struct fd *linux_device_get_fd( struct object *obj ); ++static void linux_device_destroy( struct object *obj ); ++static enum server_fd_type inproc_sync_get_fd_type( struct fd *fd ); ++ ++static const struct object_ops linux_device_ops = ++{ ++ sizeof(struct linux_device), /* size */ ++ &no_type, /* type */ ++ linux_device_dump, /* dump */ ++ no_add_queue, /* add_queue */ ++ NULL, /* remove_queue */ ++ NULL, /* signaled */ ++ NULL, /* get_esync_fd */ ++ NULL, /* get_fsync_idx */ ++ NULL, /* satisfied */ ++ no_signal, /* signal */ ++ linux_device_get_fd, /* get_fd */ ++ default_map_access, /* map_access */ ++ default_get_sd, /* get_sd */ ++ default_set_sd, /* set_sd */ ++ no_get_full_name, /* get_full_name */ ++ no_lookup_name, /* lookup_name */ ++ no_link_name, /* link_name */ ++ NULL, /* unlink_name */ ++ no_open_file, /* open_file */ ++ no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ ++ no_close_handle, /* close_handle */ ++ linux_device_destroy /* destroy */ ++}; ++ ++static const struct fd_ops inproc_sync_fd_ops = ++{ ++ default_fd_get_poll_events, /* get_poll_events */ ++ default_poll_event, /* poll_event */ ++ inproc_sync_get_fd_type, /* get_fd_type */ ++ no_fd_read, /* read */ ++ no_fd_write, /* write */ ++ no_fd_flush, /* flush */ ++ no_fd_get_file_info, /* get_file_info */ ++ no_fd_get_volume_info, /* get_volume_info */ ++ no_fd_ioctl, /* ioctl */ ++ default_fd_cancel_async, /* cancel_async */ ++ no_fd_queue_async, /* queue_async */ ++ default_fd_reselect_async /* reselect_async */ ++}; ++ ++static void linux_device_dump( struct object *obj, int verbose ) ++{ ++ struct linux_device *device = (struct linux_device *)obj; ++ assert( obj->ops == &linux_device_ops ); ++ fprintf( stderr, "In-process synchronization device fd=%p\n", device->fd ); ++} ++ ++static struct fd *linux_device_get_fd( struct object *obj ) ++{ ++ struct linux_device *device = (struct linux_device *)obj; ++ return (struct fd *)grab_object( device->fd ); ++} ++ ++static void linux_device_destroy( struct object *obj ) ++{ ++ struct linux_device *device = (struct linux_device *)obj; ++ assert( obj->ops == &linux_device_ops ); ++ if (device->fd) release_object( device->fd ); ++ linux_device_object = NULL; ++} ++ ++static enum server_fd_type inproc_sync_get_fd_type( struct fd *fd ) ++{ ++ return FD_TYPE_FILE; ++} ++ ++static struct linux_device *get_linux_device(void) ++{ ++ struct linux_device *device; ++ int unix_fd; ++ ++ if (linux_device_object) ++ return (struct linux_device *)grab_object( linux_device_object ); ++ ++ unix_fd = open( "/dev/ntsync", O_CLOEXEC | O_RDONLY ); ++ if (unix_fd == -1) ++ { ++ file_set_error(); ++ return NULL; ++ } ++ ++ if (!(device = alloc_object( &linux_device_ops ))) ++ { ++ close( unix_fd ); ++ set_error( STATUS_NO_MEMORY ); ++ return NULL; ++ } ++ ++ if (!(device->fd = create_anonymous_fd( &inproc_sync_fd_ops, unix_fd, &device->obj, 0 ))) ++ { ++ release_object( device ); ++ return NULL; ++ } ++ ++ linux_device_object = device; ++ return device; ++} ++ ++struct inproc_sync ++{ ++ struct object obj; ++ enum inproc_sync_type type; ++ struct fd *fd; ++}; ++ ++static void linux_obj_dump( struct object *obj, int verbose ); ++static void linux_obj_destroy( struct object *obj ); ++ ++static const struct object_ops inproc_sync_ops = ++{ ++ sizeof(struct inproc_sync), /* size */ ++ &no_type, /* type */ ++ linux_obj_dump, /* dump */ ++ no_add_queue, /* add_queue */ ++ NULL, /* remove_queue */ ++ NULL, /* signaled */ ++ NULL, /* get_esync_fd */ ++ NULL, /* get_fsync_idx */ ++ NULL, /* satisfied */ ++ no_signal, /* signal */ ++ no_get_fd, /* get_fd */ ++ default_map_access, /* map_access */ ++ default_get_sd, /* get_sd */ ++ default_set_sd, /* set_sd */ ++ no_get_full_name, /* get_full_name */ ++ no_lookup_name, /* lookup_name */ ++ no_link_name, /* link_name */ ++ NULL, /* unlink_name */ ++ no_open_file, /* open_file */ ++ no_kernel_obj_list, /* get_kernel_obj_list */ ++ no_get_inproc_sync, /* get_inproc_sync */ ++ no_close_handle, /* close_handle */ ++ linux_obj_destroy /* destroy */ ++}; ++ ++static void linux_obj_dump( struct object *obj, int verbose ) ++{ ++ struct inproc_sync *inproc_sync = (struct inproc_sync *)obj; ++ assert( obj->ops == &inproc_sync_ops ); ++ fprintf( stderr, "In-process synchronization object type=%u fd=%p\n", inproc_sync->type, inproc_sync->fd ); ++} ++ ++static void linux_obj_destroy( struct object *obj ) ++{ ++ struct inproc_sync *inproc_sync = (struct inproc_sync *)obj; ++ assert( obj->ops == &inproc_sync_ops ); ++ if (inproc_sync->fd) release_object( inproc_sync->fd ); ++} ++ ++static struct inproc_sync *create_inproc_sync( enum inproc_sync_type type, int unix_fd ) ++{ ++ struct inproc_sync *inproc_sync; ++ ++ if (!(inproc_sync = alloc_object( &inproc_sync_ops ))) ++ { ++ close( unix_fd ); ++ return NULL; ++ } ++ ++ inproc_sync->type = type; ++ ++ if (!(inproc_sync->fd = create_anonymous_fd( &inproc_sync_fd_ops, unix_fd, &inproc_sync->obj, 0 ))) ++ { ++ release_object( inproc_sync ); ++ return NULL; ++ } ++ ++ return inproc_sync; ++} ++ ++struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ) ++{ ++ struct ntsync_event_args args; ++ struct linux_device *device; ++ int event; ++ ++ if (!(device = get_linux_device())) return NULL; ++ ++ args.signaled = signaled; ++ switch (type) ++ { ++ case INPROC_SYNC_AUTO_EVENT: ++ case INPROC_SYNC_AUTO_SERVER: ++ args.manual = 0; ++ break; ++ ++ case INPROC_SYNC_MANUAL_EVENT: ++ case INPROC_SYNC_MANUAL_SERVER: ++ case INPROC_SYNC_QUEUE: ++ args.manual = 1; ++ break; ++ ++ case INPROC_SYNC_MUTEX: ++ case INPROC_SYNC_SEMAPHORE: ++ assert(0); ++ break; ++ } ++ if ((event = ioctl( get_unix_fd( device->fd ), NTSYNC_IOC_CREATE_EVENT, &args )) < 0) ++ { ++ file_set_error(); ++ release_object( device ); ++ return NULL; ++ } ++ release_object( device ); ++ ++ return create_inproc_sync( type, event ); ++} ++ ++void set_inproc_event( struct inproc_sync *inproc_sync ) ++{ ++ __u32 count; ++ ++ if (!inproc_sync) return; ++ ++ if (debug_level) fprintf( stderr, "set_inproc_event %p\n", inproc_sync->fd ); ++ ++ ioctl( get_unix_fd( inproc_sync->fd ), NTSYNC_IOC_EVENT_SET, &count ); ++} ++ ++void reset_inproc_event( struct inproc_sync *inproc_sync ) ++{ ++ __u32 count; ++ ++ if (!inproc_sync) return; ++ ++ if (debug_level) fprintf( stderr, "set_inproc_event %p\n", inproc_sync->fd ); ++ ++ ioctl( get_unix_fd( inproc_sync->fd ), NTSYNC_IOC_EVENT_RESET, &count ); ++} ++ ++#else ++ ++struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ) ++{ ++ set_error( STATUS_NOT_IMPLEMENTED ); ++ return NULL; ++} ++ ++void set_inproc_event( struct inproc_sync *inproc_sync ) ++{ ++} ++ ++void reset_inproc_event( struct inproc_sync *obj ) ++{ ++} ++ ++#endif +diff --git a/server/object.h b/server/object.h +index 395b22e5dbc..aaeaa3515e6 100644 +--- a/server/object.h ++++ b/server/object.h +@@ -231,6 +231,10 @@ extern void abandon_mutexes( struct thread *thread ); + + /* in-process synchronization functions */ + ++extern struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ); ++extern void set_inproc_event( struct inproc_sync *obj ); ++extern void reset_inproc_event( struct inproc_sync *obj ); ++ + extern struct inproc_sync *no_get_inproc_sync( struct object *obj ); + + /* serial functions */ +-- +2.47.1 + + diff --git a/0007-ntsync/0005-server-Create-in-process-synchronization-objects-for-semaphores.patch b/0007-ntsync/0005-server-Create-in-process-synchronization-objects-for-semaphores.patch new file mode 100644 index 0000000..6493dc1 --- /dev/null +++ b/0007-ntsync/0005-server-Create-in-process-synchronization-objects-for-semaphores.patch @@ -0,0 +1,191 @@ +From 14b419c4cd74958deb0dfbb8b7c9e02fa58db612 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Thu, 11 Mar 2021 16:45:30 -0600 +Subject: [PATCH 05/32] server: Create in-process synchronization objects for + semaphores. + +--- + server/inproc_sync.c | 46 +++++++++++++++++++++++++++++++++++++++----- + server/object.h | 1 + + server/semaphore.c | 25 ++++++++++++++++++++++-- + 3 files changed, 65 insertions(+), 7 deletions(-) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index 9054d48fca4..8d01deffa1a 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -162,8 +162,9 @@ struct inproc_sync + + static void linux_obj_dump( struct object *obj, int verbose ); + static void linux_obj_destroy( struct object *obj ); ++static struct fd *linux_obj_get_fd( struct object *obj ); + +-static const struct object_ops inproc_sync_ops = ++static const struct object_ops linux_obj_ops = + { + sizeof(struct inproc_sync), /* size */ + &no_type, /* type */ +@@ -175,7 +176,7 @@ static const struct object_ops inproc_sync_ops = + NULL, /* get_fsync_idx */ + NULL, /* satisfied */ + no_signal, /* signal */ +- no_get_fd, /* get_fd */ ++ linux_obj_get_fd, /* get_fd */ + default_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ +@@ -193,22 +194,29 @@ static const struct object_ops inproc_sync_ops = + static void linux_obj_dump( struct object *obj, int verbose ) + { + struct inproc_sync *inproc_sync = (struct inproc_sync *)obj; +- assert( obj->ops == &inproc_sync_ops ); ++ assert( obj->ops == &linux_obj_ops ); + fprintf( stderr, "In-process synchronization object type=%u fd=%p\n", inproc_sync->type, inproc_sync->fd ); + } + + static void linux_obj_destroy( struct object *obj ) + { + struct inproc_sync *inproc_sync = (struct inproc_sync *)obj; +- assert( obj->ops == &inproc_sync_ops ); ++ assert( obj->ops == &linux_obj_ops ); + if (inproc_sync->fd) release_object( inproc_sync->fd ); + } + ++static struct fd *linux_obj_get_fd( struct object *obj ) ++{ ++ struct inproc_sync *inproc_sync = (struct inproc_sync *)obj; ++ assert( obj->ops == &linux_obj_ops ); ++ return (struct fd *)grab_object( inproc_sync->fd ); ++} ++ + static struct inproc_sync *create_inproc_sync( enum inproc_sync_type type, int unix_fd ) + { + struct inproc_sync *inproc_sync; + +- if (!(inproc_sync = alloc_object( &inproc_sync_ops ))) ++ if (!(inproc_sync = alloc_object( &linux_obj_ops ))) + { + close( unix_fd ); + return NULL; +@@ -263,6 +271,28 @@ struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signale + return create_inproc_sync( type, event ); + } + ++struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int max ) ++{ ++ struct ntsync_sem_args args; ++ struct linux_device *device; ++ int semaphore; ++ ++ if (!(device = get_linux_device())) return NULL; ++ ++ args.count = count; ++ args.max = max; ++ if ((semaphore = ioctl( get_unix_fd( device->fd ), NTSYNC_IOC_CREATE_SEM, &args )) < 0) ++ { ++ file_set_error(); ++ release_object( device ); ++ return NULL; ++ } ++ ++ release_object( device ); ++ ++ return create_inproc_sync( INPROC_SYNC_SEMAPHORE, semaphore ); ++} ++ + void set_inproc_event( struct inproc_sync *inproc_sync ) + { + __u32 count; +@@ -293,6 +323,12 @@ struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signale + return NULL; + } + ++struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int max ) ++{ ++ set_error( STATUS_NOT_IMPLEMENTED ); ++ return NULL; ++} ++ + void set_inproc_event( struct inproc_sync *inproc_sync ) + { + } +diff --git a/server/object.h b/server/object.h +index aaeaa3515e6..1d21e61f7df 100644 +--- a/server/object.h ++++ b/server/object.h +@@ -232,6 +232,7 @@ extern void abandon_mutexes( struct thread *thread ); + /* in-process synchronization functions */ + + extern struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ); ++extern struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int max ); + extern void set_inproc_event( struct inproc_sync *obj ); + extern void reset_inproc_event( struct inproc_sync *obj ); + +diff --git a/server/semaphore.c b/server/semaphore.c +index 567a922c0ac..778823394a6 100644 +--- a/server/semaphore.c ++++ b/server/semaphore.c +@@ -55,12 +55,15 @@ struct semaphore + struct object obj; /* object header */ + unsigned int count; /* current count */ + unsigned int max; /* maximum possible count */ ++ struct inproc_sync *inproc_sync; /* fast synchronization object */ + }; + + static void semaphore_dump( struct object *obj, int verbose ); + static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ); + static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); + static int semaphore_signal( struct object *obj, unsigned int access ); ++static struct inproc_sync *semaphore_get_inproc_sync( struct object *obj ); ++static void semaphore_destroy( struct object *obj ); + + static const struct object_ops semaphore_ops = + { +@@ -84,9 +87,9 @@ static const struct object_ops semaphore_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ semaphore_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ +- no_destroy /* destroy */ ++ semaphore_destroy /* destroy */ + }; + + +@@ -108,6 +111,7 @@ static struct semaphore *create_semaphore( struct object *root, const struct uni + /* initialize it if it didn't already exist */ + sem->count = initial; + sem->max = max; ++ sem->inproc_sync = NULL; + } + } + return sem; +@@ -170,6 +174,23 @@ static int semaphore_signal( struct object *obj, unsigned int access ) + return release_semaphore( sem, 1, NULL ); + } + ++static struct inproc_sync *semaphore_get_inproc_sync( struct object *obj ) ++{ ++ struct semaphore *semaphore = (struct semaphore *)obj; ++ ++ if (!semaphore->inproc_sync) ++ semaphore->inproc_sync = create_inproc_semaphore( semaphore->count, semaphore->max ); ++ if (semaphore->inproc_sync) grab_object( semaphore->inproc_sync ); ++ return semaphore->inproc_sync; ++} ++ ++static void semaphore_destroy( struct object *obj ) ++{ ++ struct semaphore *semaphore = (struct semaphore *)obj; ++ ++ if (semaphore->inproc_sync) release_object( semaphore->inproc_sync ); ++} ++ + /* create a semaphore */ + DECL_HANDLER(create_semaphore) + { +-- +2.47.1 + + diff --git a/0007-ntsync/0006-server-Create-in-process-synchronization-objects-for-mutexes.patch b/0007-ntsync/0006-server-Create-in-process-synchronization-objects-for-mutexes.patch new file mode 100644 index 0000000..353e402 --- /dev/null +++ b/0007-ntsync/0006-server-Create-in-process-synchronization-objects-for-mutexes.patch @@ -0,0 +1,206 @@ +From cba9a52c94139ff7bf90b42bf026a1dc892eb3f4 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Thu, 11 Mar 2021 16:52:55 -0600 +Subject: [PATCH 06/32] server: Create in-process synchronization objects for + mutexes. + +--- + server/inproc_sync.c | 37 +++++++++++++++++++++++++++++++++++++ + server/mutex.c | 40 +++++++++++++++++++++++++++++++++++----- + server/object.h | 2 ++ + 3 files changed, 74 insertions(+), 5 deletions(-) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index 8d01deffa1a..11c0a87d13f 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -293,6 +293,28 @@ struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int ma + return create_inproc_sync( INPROC_SYNC_SEMAPHORE, semaphore ); + } + ++struct inproc_sync *create_inproc_mutex( thread_id_t owner, unsigned int count ) ++{ ++ struct ntsync_mutex_args args; ++ struct linux_device *device; ++ int mutex; ++ ++ if (!(device = get_linux_device())) return NULL; ++ ++ args.owner = owner; ++ args.count = count; ++ if ((mutex = ioctl( get_unix_fd( device->fd ), NTSYNC_IOC_CREATE_MUTEX, &args )) < 0) ++ { ++ file_set_error(); ++ release_object( device ); ++ return NULL; ++ } ++ ++ release_object( device ); ++ ++ return create_inproc_sync( INPROC_SYNC_MUTEX, mutex ); ++} ++ + void set_inproc_event( struct inproc_sync *inproc_sync ) + { + __u32 count; +@@ -315,6 +337,11 @@ void reset_inproc_event( struct inproc_sync *inproc_sync ) + ioctl( get_unix_fd( inproc_sync->fd ), NTSYNC_IOC_EVENT_RESET, &count ); + } + ++void abandon_inproc_mutex( thread_id_t tid, struct inproc_sync *inproc_sync ) ++{ ++ ioctl( get_unix_fd( inproc_sync->fd ), NTSYNC_IOC_MUTEX_KILL, &tid ); ++} ++ + #else + + struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ) +@@ -329,6 +356,12 @@ struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int ma + return NULL; + } + ++struct inproc_sync *create_inproc_mutex( thread_id_t owner, unsigned int count ) ++{ ++ set_error( STATUS_NOT_IMPLEMENTED ); ++ return NULL; ++} ++ + void set_inproc_event( struct inproc_sync *inproc_sync ) + { + } +@@ -337,4 +370,8 @@ void reset_inproc_event( struct inproc_sync *obj ) + { + } + ++void abandon_inproc_mutex( thread_id_t tid, struct inproc_sync *inproc_sync ) ++{ ++} ++ + #endif +diff --git a/server/mutex.c b/server/mutex.c +index 58ac83bd3f7..d97f54b8e82 100644 +--- a/server/mutex.c ++++ b/server/mutex.c +@@ -38,6 +38,8 @@ + + static const WCHAR mutex_name[] = {'M','u','t','a','n','t'}; + ++static struct list inproc_mutexes = LIST_INIT(inproc_mutexes); ++ + struct type_descr mutex_type = + { + { mutex_name, sizeof(mutex_name) }, /* name */ +@@ -57,6 +59,8 @@ struct mutex + unsigned int count; /* recursion count */ + int abandoned; /* has it been abandoned? */ + struct list entry; /* entry in owner thread mutex list */ ++ struct list inproc_mutexes_entry; /* entry in inproc_mutexes list */ ++ struct inproc_sync *inproc_sync;/* in-process synchronization object */ + }; + + static void mutex_dump( struct object *obj, int verbose ); +@@ -64,6 +68,7 @@ static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ); + static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); + static void mutex_destroy( struct object *obj ); + static int mutex_signal( struct object *obj, unsigned int access ); ++static struct inproc_sync *mutex_get_inproc_sync( struct object *obj ); + + static const struct object_ops mutex_ops = + { +@@ -87,7 +92,7 @@ static const struct object_ops mutex_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ mutex_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mutex_destroy /* destroy */ + }; +@@ -130,6 +135,7 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str + mutex->owner = NULL; + mutex->abandoned = 0; + if (owned) do_grab( mutex, current ); ++ mutex->inproc_sync = NULL; + } + } + return mutex; +@@ -137,16 +143,20 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str + + void abandon_mutexes( struct thread *thread ) + { ++ struct mutex *mutex; + struct list *ptr; + + while ((ptr = list_head( &thread->mutex_list )) != NULL) + { +- struct mutex *mutex = LIST_ENTRY( ptr, struct mutex, entry ); ++ mutex = LIST_ENTRY( ptr, struct mutex, entry ); + assert( mutex->owner == thread ); + mutex->count = 0; + mutex->abandoned = 1; + do_release( mutex ); + } ++ ++ LIST_FOR_EACH_ENTRY(mutex, &inproc_mutexes, struct mutex, inproc_mutexes_entry) ++ abandon_inproc_mutex( thread->id, mutex->inproc_sync ); + } + + static void mutex_dump( struct object *obj, int verbose ) +@@ -192,14 +202,34 @@ static int mutex_signal( struct object *obj, unsigned int access ) + return 1; + } + ++static struct inproc_sync *mutex_get_inproc_sync( struct object *obj ) ++{ ++ struct mutex *mutex = (struct mutex *)obj; ++ ++ if (!mutex->inproc_sync) ++ { ++ mutex->inproc_sync = create_inproc_mutex( mutex->owner ? mutex->owner->id : 0, mutex->count ); ++ if (mutex->inproc_sync) list_add_tail( &inproc_mutexes, &mutex->inproc_mutexes_entry ); ++ } ++ if (mutex->inproc_sync) grab_object( mutex->inproc_sync ); ++ return mutex->inproc_sync; ++} ++ + static void mutex_destroy( struct object *obj ) + { + struct mutex *mutex = (struct mutex *)obj; + assert( obj->ops == &mutex_ops ); + +- if (!mutex->count) return; +- mutex->count = 0; +- do_release( mutex ); ++ if (mutex->count) ++ { ++ mutex->count = 0; ++ do_release( mutex ); ++ } ++ if (mutex->inproc_sync) ++ { ++ release_object( mutex->inproc_sync ); ++ list_remove( &mutex->inproc_mutexes_entry ); ++ } + } + + /* create a mutex */ +diff --git a/server/object.h b/server/object.h +index 1d21e61f7df..b83eb671280 100644 +--- a/server/object.h ++++ b/server/object.h +@@ -232,9 +232,11 @@ extern void abandon_mutexes( struct thread *thread ); + /* in-process synchronization functions */ + + extern struct inproc_sync *create_inproc_event( enum inproc_sync_type type, int signaled ); ++extern struct inproc_sync *create_inproc_mutex( thread_id_t owner, unsigned int count ); + extern struct inproc_sync *create_inproc_semaphore( unsigned int count, unsigned int max ); + extern void set_inproc_event( struct inproc_sync *obj ); + extern void reset_inproc_event( struct inproc_sync *obj ); ++extern void abandon_inproc_mutex( thread_id_t tid, struct inproc_sync *inproc_sync ); + + extern struct inproc_sync *no_get_inproc_sync( struct object *obj ); + +-- +2.47.1 + + diff --git a/0007-ntsync/0007-server-Create-in-process-synchronization-objects-for-completion-ports.patch b/0007-ntsync/0007-server-Create-in-process-synchronization-objects-for-completion-ports.patch new file mode 100644 index 0000000..ea50e9f --- /dev/null +++ b/0007-ntsync/0007-server-Create-in-process-synchronization-objects-for-completion-ports.patch @@ -0,0 +1,105 @@ +From 89c5155107e8f1a43a3157fd1bd1b3d406edeebe Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Fri, 12 Mar 2021 04:32:58 +0200 +Subject: [PATCH 07/32] server: Create in-process synchronization objects for + completion ports. + +--- + server/completion.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/server/completion.c b/server/completion.c +index a8c3e2ce6bc..e021f99b700 100644 +--- a/server/completion.c ++++ b/server/completion.c +@@ -79,6 +79,7 @@ struct completion + struct list wait_queue; + unsigned int depth; + int closed; ++ struct inproc_sync *inproc_sync; + int esync_fd; + unsigned int fsync_idx; + }; +@@ -170,6 +171,7 @@ static int completion_signaled( struct object *obj, struct wait_queue_entry *ent + static int completion_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int completion_get_fsync_idx( struct object *obj, enum fsync_type *type ); + static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); ++static struct inproc_sync *completion_get_inproc_sync( struct object *obj ); + static void completion_destroy( struct object * ); + + static const struct object_ops completion_ops = +@@ -194,7 +196,7 @@ static const struct object_ops completion_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ completion_get_inproc_sync,/* get_inproc_sync */ + completion_close_handle, /* close_handle */ + completion_destroy /* destroy */ + }; +@@ -211,6 +213,7 @@ static void completion_destroy( struct object *obj) + { + free( tmp ); + } ++ if (completion->inproc_sync) release_object( completion->inproc_sync ); + } + + static void completion_dump( struct object *obj, int verbose ) +@@ -265,6 +268,7 @@ static int completion_close_handle( struct object *obj, struct process *process, + } + completion->closed = 1; + wake_up( obj, 0 ); ++ set_inproc_event( completion->inproc_sync ); + return 1; + } + +@@ -299,6 +303,16 @@ static struct completion_wait *create_completion_wait( struct completion *comple + return wait; + } + ++static struct inproc_sync *completion_get_inproc_sync( struct object *obj ) ++{ ++ struct completion *completion = (struct completion *)obj; ++ ++ if (!completion->inproc_sync) ++ completion->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, !list_empty( &completion->queue ) ); ++ if (completion->inproc_sync) grab_object( completion->inproc_sync ); ++ return completion->inproc_sync; ++} ++ + static struct completion *create_completion( struct object *root, const struct unicode_str *name, + unsigned int attr, unsigned int concurrent, + const struct security_descriptor *sd ) +@@ -313,6 +327,7 @@ static struct completion *create_completion( struct object *root, const struct u + list_init( &completion->wait_queue ); + completion->depth = 0; + completion->closed = 0; ++ completion->inproc_sync = NULL; + } + } + if (do_esync()) completion->esync_fd = esync_create_fd( 0, 0 ); +@@ -347,7 +362,11 @@ void add_completion( struct completion *completion, apc_param_t ckey, apc_param_ + wake_up( &wait->obj, 1 ); + if (list_empty( &completion->queue )) return; + } +- if (!list_empty( &completion->queue )) wake_up( &completion->obj, 0 ); ++ if (!list_empty( &completion->queue )) ++ { ++ wake_up( &completion->obj, 0 ); ++ set_inproc_event( completion->inproc_sync ); ++ } + } + + /* create a completion */ +@@ -433,6 +452,7 @@ DECL_HANDLER(remove_completion) + { + if (do_esync()) esync_clear( completion->esync_fd ); + if (do_fsync()) fsync_clear( &completion->obj ); ++ reset_inproc_event( completion->inproc_sync ); + } + } + +-- +2.47.1 + + diff --git a/0007-ntsync/0008-server-Create-in-process-synchronization-objects-for-consoles.patch b/0007-ntsync/0008-server-Create-in-process-synchronization-objects-for-consoles.patch new file mode 100644 index 0000000..fc130d9 --- /dev/null +++ b/0007-ntsync/0008-server-Create-in-process-synchronization-objects-for-consoles.patch @@ -0,0 +1,198 @@ +From fa73d56df28ec3ab76b83a033e95bd42669cf99b Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 16:54:34 -0600 +Subject: [PATCH 08/32] server: Create in-process synchronization objects for + consoles. + +--- + server/console.c | 64 ++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 59 insertions(+), 5 deletions(-) + +diff --git a/server/console.c b/server/console.c +index fcd70f21dd0..d5c672126c0 100644 +--- a/server/console.c ++++ b/server/console.c +@@ -63,6 +63,7 @@ struct console + struct fd *fd; /* for bare console, attached input fd */ + struct async_queue ioctl_q; /* ioctl queue */ + struct async_queue read_q; /* read queue */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + }; + + static void console_dump( struct object *obj, int verbose ); +@@ -74,6 +75,7 @@ static struct object *console_lookup_name( struct object *obj, struct unicode_st + static struct object *console_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); + static int console_add_queue( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *console_get_inproc_sync( struct object *obj ); + + static const struct object_ops console_ops = + { +@@ -97,7 +99,7 @@ static const struct object_ops console_ops = + NULL, /* unlink_name */ + console_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ console_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_destroy /* destroy */ + }; +@@ -230,6 +232,7 @@ static int screen_buffer_add_queue( struct object *obj, struct wait_queue_entry + static struct fd *screen_buffer_get_fd( struct object *obj ); + static struct object *screen_buffer_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); ++static struct inproc_sync *screen_buffer_get_inproc_sync( struct object *obj ); + + static const struct object_ops screen_buffer_ops = + { +@@ -253,7 +256,7 @@ static const struct object_ops screen_buffer_ops = + NULL, /* unlink_name */ + screen_buffer_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ screen_buffer_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + screen_buffer_destroy /* destroy */ + }; +@@ -321,6 +324,7 @@ static struct object *console_input_open_file( struct object *obj, unsigned int + unsigned int sharing, unsigned int options ); + static int console_input_add_queue( struct object *obj, struct wait_queue_entry *entry ); + static struct fd *console_input_get_fd( struct object *obj ); ++static struct inproc_sync *console_input_get_inproc_sync( struct object *obj ); + static void console_input_destroy( struct object *obj ); + + static const struct object_ops console_input_ops = +@@ -345,7 +349,7 @@ static const struct object_ops console_input_ops = + default_unlink_name, /* unlink_name */ + console_input_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ console_input_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_input_destroy /* destroy */ + }; +@@ -381,6 +385,7 @@ static int console_output_add_queue( struct object *obj, struct wait_queue_entry + static struct fd *console_output_get_fd( struct object *obj ); + static struct object *console_output_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); ++static struct inproc_sync *console_output_get_inproc_sync( struct object *obj ); + static void console_output_destroy( struct object *obj ); + + static const struct object_ops console_output_ops = +@@ -405,7 +410,7 @@ static const struct object_ops console_output_ops = + default_unlink_name, /* unlink_name */ + console_output_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ console_output_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_output_destroy /* destroy */ + }; +@@ -566,6 +571,7 @@ static struct object *create_console(void) + console->server = NULL; + console->fd = NULL; + console->last_id = 0; ++ console->inproc_sync = NULL; + init_async_queue( &console->ioctl_q ); + init_async_queue( &console->read_q ); + +@@ -795,6 +801,8 @@ static void console_destroy( struct object *obj ) + free_async_queue( &console->read_q ); + if (console->fd) + release_object( console->fd ); ++ ++ if (console->inproc_sync) release_object( console->inproc_sync ); + } + + static struct object *create_console_connection( struct console *console ) +@@ -842,6 +850,16 @@ static struct object *console_open_file( struct object *obj, unsigned int access + return grab_object( obj ); + } + ++static struct inproc_sync *console_get_inproc_sync( struct object *obj ) ++{ ++ struct console *console = (struct console *)obj; ++ ++ if (!console->inproc_sync) ++ console->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, console->signaled ); ++ if (console->inproc_sync) grab_object( console->inproc_sync ); ++ return console->inproc_sync; ++} ++ + static void screen_buffer_dump( struct object *obj, int verbose ) + { + struct screen_buffer *screen_buffer = (struct screen_buffer *)obj; +@@ -891,6 +909,17 @@ static struct fd *screen_buffer_get_fd( struct object *obj ) + return NULL; + } + ++static struct inproc_sync *screen_buffer_get_inproc_sync( struct object *obj ) ++{ ++ struct screen_buffer *screen_buffer = (struct screen_buffer *)obj; ++ if (!screen_buffer->input) ++ { ++ set_error( STATUS_ACCESS_DENIED ); ++ return NULL; ++ } ++ return console_get_inproc_sync( &screen_buffer->input->obj ); ++} ++ + static void console_server_dump( struct object *obj, int verbose ) + { + assert( obj->ops == &console_server_ops ); +@@ -1457,6 +1486,16 @@ static struct object *console_input_open_file( struct object *obj, unsigned int + return grab_object( obj ); + } + ++static struct inproc_sync *console_input_get_inproc_sync( struct object *obj ) ++{ ++ if (!current->process->console) ++ { ++ set_error( STATUS_ACCESS_DENIED ); ++ return NULL; ++ } ++ return console_get_inproc_sync( ¤t->process->console->obj ); ++} ++ + static void console_input_destroy( struct object *obj ) + { + struct console_input *console_input = (struct console_input *)obj; +@@ -1529,6 +1568,16 @@ static struct object *console_output_open_file( struct object *obj, unsigned int + return grab_object( obj ); + } + ++static struct inproc_sync *console_output_get_inproc_sync( struct object *obj ) ++{ ++ if (!current->process->console || !current->process->console->active) ++ { ++ set_error( STATUS_ACCESS_DENIED ); ++ return NULL; ++ } ++ return console_get_inproc_sync( ¤t->process->console->obj ); ++} ++ + static void console_output_destroy( struct object *obj ) + { + struct console_output *console_output = (struct console_output *)obj; +@@ -1586,11 +1635,16 @@ DECL_HANDLER(get_next_console_request) + + if (!server->console->renderer) server->console->renderer = current; + +- if (!req->signal) server->console->signaled = 0; ++ if (!req->signal) ++ { ++ server->console->signaled = 0; ++ reset_inproc_event( server->console->inproc_sync ); ++ } + else if (!server->console->signaled) + { + server->console->signaled = 1; + wake_up( &server->console->obj, 0 ); ++ set_inproc_event( server->console->inproc_sync ); + } + + if (req->read) +-- +2.47.1 + + diff --git a/0007-ntsync/0009-server-Create-in-process-synchronization-objects-for-console-servers.patch b/0007-ntsync/0009-server-Create-in-process-synchronization-objects-for-console-servers.patch new file mode 100644 index 0000000..e47ba00 --- /dev/null +++ b/0007-ntsync/0009-server-Create-in-process-synchronization-objects-for-console-servers.patch @@ -0,0 +1,111 @@ +From a3f81a5a9fb78c193125d278d01cb28e062dbe84 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 01:00:51 +0200 +Subject: [PATCH 09/32] server: Create in-process synchronization objects for + console servers. + +--- + server/console.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/server/console.c b/server/console.c +index d5c672126c0..be674f17332 100644 +--- a/server/console.c ++++ b/server/console.c +@@ -146,6 +146,7 @@ struct console_server + unsigned int once_input : 1; /* flag if input thread has already been requested */ + int term_fd; /* UNIX terminal fd */ + struct termios termios; /* original termios */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + int esync_fd; + unsigned int fsync_idx; + }; +@@ -160,6 +161,7 @@ static struct object *console_server_lookup_name( struct object *obj, struct uni + unsigned int attr, struct object *root ); + static struct object *console_server_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); ++static struct inproc_sync *console_server_get_inproc_sync( struct object *obj ); + + static const struct object_ops console_server_ops = + { +@@ -183,7 +185,7 @@ static const struct object_ops console_server_ops = + NULL, /* unlink_name */ + console_server_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ console_server_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + console_server_destroy /* destroy */ + }; +@@ -611,6 +613,7 @@ static int queue_host_ioctl( struct console_server *server, unsigned int code, u + } + list_add_tail( &server->queue, &ioctl->entry ); + wake_up( &server->obj, 0 ); ++ set_inproc_event( server->inproc_sync ); + if (async) set_error( STATUS_PENDING ); + return 1; + } +@@ -647,6 +650,7 @@ static void disconnect_console_server( struct console_server *server ) + server->console->server = NULL; + server->console = NULL; + wake_up( &server->obj, 0 ); ++ set_inproc_event( server->inproc_sync ); + } + } + +@@ -934,6 +938,7 @@ static void console_server_destroy( struct object *obj ) + if (server->fd) release_object( server->fd ); + if (do_esync()) close( server->esync_fd ); + if (server->fsync_idx) fsync_free_shm_idx( server->fsync_idx ); ++ if (server->inproc_sync) release_object( server->inproc_sync ); + } + + static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, +@@ -1002,6 +1007,17 @@ static struct object *console_server_open_file( struct object *obj, unsigned int + return grab_object( obj ); + } + ++static struct inproc_sync *console_server_get_inproc_sync( struct object *obj ) ++{ ++ struct console_server *server = (struct console_server *)obj; ++ int signaled = !server->console || !list_empty( &server->queue ); ++ ++ if (!server->inproc_sync) ++ server->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, signaled ); ++ if (server->inproc_sync) grab_object( server->inproc_sync ); ++ return server->inproc_sync; ++} ++ + static struct object *create_console_server( void ) + { + struct console_server *server; +@@ -1013,6 +1029,7 @@ static struct object *create_console_server( void ) + server->term_fd = -1; + list_init( &server->queue ); + list_init( &server->read_queue ); ++ server->inproc_sync = NULL; + server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT ); + if (!server->fd) + { +@@ -1670,6 +1687,8 @@ DECL_HANDLER(get_next_console_request) + fsync_clear( &server->obj ); + if (do_esync() && list_empty( &server->queue )) + esync_clear( server->esync_fd ); ++ if (list_empty( &server->queue )) ++ reset_inproc_event( server->inproc_sync ); + } + + if (ioctl) +@@ -1760,5 +1779,8 @@ DECL_HANDLER(get_next_console_request) + if (do_esync() && list_empty( &server->queue )) + esync_clear( server->esync_fd ); + ++ if (list_empty( &server->queue )) ++ reset_inproc_event( server->inproc_sync ); ++ + release_object( server ); + } +-- +2.47.1 + + diff --git a/0007-ntsync/0010-server-Create-in-process-synchronization-objects-for-debug-objects.patch b/0007-ntsync/0010-server-Create-in-process-synchronization-objects-for-debug-objects.patch new file mode 100644 index 0000000..59bf74b --- /dev/null +++ b/0007-ntsync/0010-server-Create-in-process-synchronization-objects-for-debug-objects.patch @@ -0,0 +1,104 @@ +From 229c73503433c3839caec10f40bc3b2e88601eda Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:11:03 -0600 +Subject: [PATCH 10/32] server: Create in-process synchronization objects for + debug objects. + +--- + server/debugger.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/server/debugger.c b/server/debugger.c +index 35c93d3c948..bb69b70eb55 100644 +--- a/server/debugger.c ++++ b/server/debugger.c +@@ -71,6 +71,7 @@ struct debug_obj + struct object obj; /* object header */ + struct list event_queue; /* pending events queue */ + unsigned int flags; /* debug flags */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + }; + + +@@ -107,6 +108,7 @@ static const struct object_ops debug_event_ops = + + static void debug_obj_dump( struct object *obj, int verbose ); + static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *debug_obj_get_inproc_sync( struct object *obj ); + static void debug_obj_destroy( struct object *obj ); + + static const struct object_ops debug_obj_ops = +@@ -131,7 +133,7 @@ static const struct object_ops debug_obj_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ debug_obj_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + debug_obj_destroy /* destroy */ + }; +@@ -259,6 +261,7 @@ static void link_event( struct debug_obj *debug_obj, struct debug_event *event ) + /* grab reference since debugger could be killed while trying to wake up */ + grab_object( debug_obj ); + wake_up( &debug_obj->obj, 0 ); ++ set_inproc_event( debug_obj->inproc_sync ); + release_object( debug_obj ); + } + } +@@ -271,6 +274,7 @@ static void resume_event( struct debug_obj *debug_obj, struct debug_event *event + { + grab_object( debug_obj ); + wake_up( &debug_obj->obj, 0 ); ++ set_inproc_event( debug_obj->inproc_sync ); + release_object( debug_obj ); + } + } +@@ -336,6 +340,17 @@ static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entr + return find_event_to_send( debug_obj ) != NULL; + } + ++static struct inproc_sync *debug_obj_get_inproc_sync( struct object *obj ) ++{ ++ struct debug_obj *debug_obj = (struct debug_obj *)obj; ++ int signaled = find_event_to_send( debug_obj ) != NULL; ++ ++ if (!debug_obj->inproc_sync) ++ debug_obj->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, signaled ); ++ if (debug_obj->inproc_sync) grab_object( debug_obj->inproc_sync ); ++ return debug_obj->inproc_sync; ++} ++ + static void debug_obj_destroy( struct object *obj ) + { + struct list *ptr; +@@ -348,6 +363,8 @@ static void debug_obj_destroy( struct object *obj ) + /* free all pending events */ + while ((ptr = list_head( &debug_obj->event_queue ))) + unlink_event( debug_obj, LIST_ENTRY( ptr, struct debug_event, entry )); ++ ++ if (debug_obj->inproc_sync) release_object( debug_obj->inproc_sync ); + } + + struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access ) +@@ -367,6 +384,7 @@ static struct debug_obj *create_debug_obj( struct object *root, const struct uni + { + debug_obj->flags = flags; + list_init( &debug_obj->event_queue ); ++ debug_obj->inproc_sync = NULL; + } + } + return debug_obj; +@@ -575,6 +593,9 @@ DECL_HANDLER(wait_debug_event) + reply->tid = get_thread_id( event->sender ); + alloc_event_handles( event, current->process ); + set_reply_data( &event->data, min( get_reply_max_size(), sizeof(event->data) )); ++ ++ if (!find_event_to_send( debug_obj )) ++ reset_inproc_event( debug_obj->inproc_sync ); + } + else + { +-- +2.47.1 + + diff --git a/0007-ntsync/0011-server-Create-in-process-synchronization-objects-for-device-managers.patch b/0007-ntsync/0011-server-Create-in-process-synchronization-objects-for-device-managers.patch new file mode 100644 index 0000000..83cec8c --- /dev/null +++ b/0007-ntsync/0011-server-Create-in-process-synchronization-objects-for-device-managers.patch @@ -0,0 +1,111 @@ +From 18ddf33be6fb7c534b5f7d9b6f6416886edf0b36 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Wed, 10 Mar 2021 19:02:42 +0200 +Subject: [PATCH 11/32] server: Create in-process synchronization objects for + device managers. + +--- + server/device.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/server/device.c b/server/device.c +index a0216152ea7..6bb748f8b01 100644 +--- a/server/device.c ++++ b/server/device.c +@@ -97,12 +97,14 @@ struct device_manager + struct list requests; /* list of pending irps across all devices */ + struct irp_call *current_call; /* call currently executed on client side */ + struct wine_rb_tree kernel_objects; /* map of objects that have client side pointer associated */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + int esync_fd; /* esync file descriptor */ + unsigned int fsync_idx; + }; + + static void device_manager_dump( struct object *obj, int verbose ); + static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *device_manager_get_inproc_sync( struct object *obj ); + static int device_manager_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int device_manager_get_fsync_idx( struct object *obj, enum fsync_type *type ); + static void device_manager_destroy( struct object *obj ); +@@ -129,7 +131,7 @@ static const struct object_ops device_manager_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ device_manager_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + device_manager_destroy /* destroy */ + }; +@@ -435,7 +437,12 @@ static void add_irp_to_queue( struct device_manager *manager, struct irp_call *i + irp->thread = thread ? (struct thread *)grab_object( thread ) : NULL; + if (irp->file) list_add_tail( &irp->file->requests, &irp->dev_entry ); + list_add_tail( &manager->requests, &irp->mgr_entry ); +- if (list_head( &manager->requests ) == &irp->mgr_entry) wake_up( &manager->obj, 0 ); /* first one */ ++ if (list_head( &manager->requests ) == &irp->mgr_entry) ++ { ++ /* first one */ ++ wake_up( &manager->obj, 0 ); ++ set_inproc_event( manager->inproc_sync ); ++ } + } + + static struct object *device_open_file( struct object *obj, unsigned int access, +@@ -775,6 +782,9 @@ static void delete_file( struct device_file *file ) + set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 ); + } + ++ if (list_empty( &file->device->manager->requests )) ++ reset_inproc_event( file->device->manager->inproc_sync ); ++ + release_object( file ); + } + +@@ -806,6 +816,16 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry + return !list_empty( &manager->requests ); + } + ++static struct inproc_sync *device_manager_get_inproc_sync( struct object *obj ) ++{ ++ struct device_manager *manager = (struct device_manager *)obj; ++ ++ if (!manager->inproc_sync) ++ manager->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, !list_empty( &manager->requests ) ); ++ if (manager->inproc_sync) grab_object( manager->inproc_sync ); ++ return manager->inproc_sync; ++} ++ + static int device_manager_get_esync_fd( struct object *obj, enum esync_type *type ) + { + struct device_manager *manager = (struct device_manager *)obj; +@@ -858,6 +878,8 @@ static void device_manager_destroy( struct object *obj ) + if (do_esync()) + close( manager->esync_fd ); + if (manager->fsync_idx) fsync_free_shm_idx( manager->fsync_idx ); ++ ++ if (manager->inproc_sync) release_object( manager->inproc_sync ); + } + + static struct device_manager *create_device_manager(void) +@@ -867,6 +889,7 @@ static struct device_manager *create_device_manager(void) + if ((manager = alloc_object( &device_manager_ops ))) + { + manager->current_call = NULL; ++ manager->inproc_sync = NULL; + list_init( &manager->devices ); + list_init( &manager->requests ); + wine_rb_init( &manager->kernel_objects, compare_kernel_object ); +@@ -1063,6 +1086,10 @@ DECL_HANDLER(get_next_device_request) + } + list_remove( &irp->mgr_entry ); + list_init( &irp->mgr_entry ); ++ ++ if (list_empty( &manager->requests )) ++ reset_inproc_event( manager->inproc_sync ); ++ + /* we already own the object if it's only on manager queue */ + if (irp->file) grab_object( irp ); + manager->current_call = irp; +-- +2.47.1 + + diff --git a/0007-ntsync/0012-server-Create-in-process-synchronization-objects-for-keyed-events.patch b/0007-ntsync/0012-server-Create-in-process-synchronization-objects-for-keyed-events.patch new file mode 100644 index 0000000..5fb9963 --- /dev/null +++ b/0007-ntsync/0012-server-Create-in-process-synchronization-objects-for-keyed-events.patch @@ -0,0 +1,76 @@ +From f4ca5640c329dabb3c69ee362dc397121522f643 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:13:20 -0600 +Subject: [PATCH 12/32] server: Create in-process synchronization objects for + keyed events. + +--- + server/event.c | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/server/event.c b/server/event.c +index 6a47cbec89e..7197a7017b1 100644 +--- a/server/event.c ++++ b/server/event.c +@@ -118,10 +118,13 @@ struct type_descr keyed_event_type = + struct keyed_event + { + struct object obj; /* object header */ ++ struct inproc_sync *inproc_sync;/* in-process synchronization object */ + }; + + static void keyed_event_dump( struct object *obj, int verbose ); + static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *keyed_event_get_inproc_sync( struct object *obj ); ++static void keyed_event_destroy( struct object *obj ); + + static const struct object_ops keyed_event_ops = + { +@@ -145,9 +148,9 @@ static const struct object_ops keyed_event_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ keyed_event_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ +- no_destroy /* destroy */ ++ keyed_event_destroy /* destroy */ + }; + + +@@ -336,6 +339,7 @@ struct keyed_event *create_keyed_event( struct object *root, const struct unicod + if (get_error() != STATUS_OBJECT_NAME_EXISTS) + { + /* initialize it if it didn't already exist */ ++ event->inproc_sync = NULL; + } + } + return event; +@@ -379,6 +383,23 @@ static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *en + return 0; + } + ++static struct inproc_sync *keyed_event_get_inproc_sync( struct object *obj ) ++{ ++ struct keyed_event *event = (struct keyed_event *)obj; ++ ++ if (!event->inproc_sync) ++ event->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, 1 ); ++ if (event->inproc_sync) grab_object( event->inproc_sync ); ++ return event->inproc_sync; ++} ++ ++static void keyed_event_destroy( struct object *obj ) ++{ ++ struct keyed_event *event = (struct keyed_event *)obj; ++ ++ if (event->inproc_sync) release_object( event->inproc_sync ); ++} ++ + /* create an event */ + DECL_HANDLER(create_event) + { +-- +2.47.1 + + diff --git a/0007-ntsync/0013-server-Create-in-process-synchronization-objects-for-processes.patch b/0007-ntsync/0013-server-Create-in-process-synchronization-objects-for-processes.patch new file mode 100644 index 0000000..182be09 --- /dev/null +++ b/0007-ntsync/0013-server-Create-in-process-synchronization-objects-for-processes.patch @@ -0,0 +1,89 @@ +From 0e626ed7633e2152c55bf8b1cf4619da9dc6b5cc Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 01:16:53 +0200 +Subject: [PATCH 13/32] server: Create in-process synchronization objects for + processes. + +--- + server/process.c | 17 ++++++++++++++++- + server/process.h | 1 + + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/server/process.c b/server/process.c +index 6d5140ab7b3..c51e4e5f34f 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -96,6 +96,7 @@ static unsigned int process_map_access( struct object *obj, unsigned int access + static struct security_descriptor *process_get_sd( struct object *obj ); + static void process_poll_event( struct fd *fd, int event ); + static struct list *process_get_kernel_obj_list( struct object *obj ); ++static struct inproc_sync *process_get_inproc_sync( struct object *obj ); + static void process_destroy( struct object *obj ); + static int process_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int process_get_fsync_idx( struct object *obj, enum fsync_type *type ); +@@ -123,7 +124,7 @@ static const struct object_ops process_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + process_get_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ process_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + process_destroy /* destroy */ + }; +@@ -697,6 +698,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla + process->rawinput_device_count = 0; + process->rawinput_mouse = NULL; + process->rawinput_kbd = NULL; ++ process->inproc_sync = NULL; + memset( &process->image_info, 0, sizeof(process->image_info) ); + list_init( &process->rawinput_entry ); + process->esync_fd = -1; +@@ -807,6 +809,7 @@ static void process_destroy( struct object *obj ) + free( process->image ); + if (do_esync()) close( process->esync_fd ); + if (process->fsync_idx) fsync_free_shm_idx( process->fsync_idx ); ++ if (process->inproc_sync) release_object( process->inproc_sync ); + } + + /* dump a process on stdout for debugging purposes */ +@@ -854,6 +857,16 @@ static struct list *process_get_kernel_obj_list( struct object *obj ) + return &process->kernel_object; + } + ++static struct inproc_sync *process_get_inproc_sync( struct object *obj ) ++{ ++ struct process *process = (struct process *)obj; ++ ++ if (!process->inproc_sync) ++ process->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, !process->running_threads ); ++ if (process->inproc_sync) grab_object( process->inproc_sync ); ++ return process->inproc_sync; ++} ++ + static struct security_descriptor *process_get_sd( struct object *obj ) + { + static struct security_descriptor *process_default_sd; +@@ -1018,6 +1031,7 @@ static void process_killed( struct process *process ) + release_job_process( process ); + start_sigkill_timer( process ); + wake_up( &process->obj, 0 ); ++ set_inproc_event( process->inproc_sync ); + } + + /* add a thread to a process running threads list */ +diff --git a/server/process.h b/server/process.h +index 112aa5d5062..90817ddd969 100644 +--- a/server/process.h ++++ b/server/process.h +@@ -85,6 +85,7 @@ struct process + struct list rawinput_entry; /* entry in the rawinput process list */ + struct list kernel_object; /* list of kernel object pointers */ + struct pe_image_info image_info; /* main exe image info */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + int esync_fd; /* esync file descriptor (signaled on exit) */ + unsigned int fsync_idx; + }; +-- +2.47.1 + + diff --git a/0007-ntsync/0014-server-Create-in-process-synchronization-objects-for-jobs.patch b/0007-ntsync/0014-server-Create-in-process-synchronization-objects-for-jobs.patch new file mode 100644 index 0000000..5dd81b1 --- /dev/null +++ b/0007-ntsync/0014-server-Create-in-process-synchronization-objects-for-jobs.patch @@ -0,0 +1,78 @@ +From 5a1906200026621faa148458d5f42b4a9ba8cba1 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:17:35 -0600 +Subject: [PATCH 14/32] server: Create in-process synchronization objects for + jobs. + +--- + server/process.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/server/process.c b/server/process.c +index c51e4e5f34f..4d3e96b5b7a 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -202,6 +202,7 @@ struct type_descr job_type = + + static void job_dump( struct object *obj, int verbose ); + static int job_signaled( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *job_get_inproc_sync( struct object *obj ); + static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); + static void job_destroy( struct object *obj ); + +@@ -219,6 +220,7 @@ struct job + struct job *parent; + struct list parent_job_entry; /* list entry for parent job */ + struct list child_job_list; /* list of child jobs */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + }; + + static const struct object_ops job_ops = +@@ -243,7 +245,7 @@ static const struct object_ops job_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ job_get_inproc_sync, /* get_inproc_sync */ + job_close_handle, /* close_handle */ + job_destroy /* destroy */ + }; +@@ -268,6 +270,7 @@ static struct job *create_job_object( struct object *root, const struct unicode_ + job->completion_port = NULL; + job->completion_key = 0; + job->parent = NULL; ++ job->inproc_sync = NULL; + } + } + return job; +@@ -424,6 +427,17 @@ static void terminate_job( struct job *job, int exit_code ) + job->terminating = 0; + job->signaled = 1; + wake_up( &job->obj, 0 ); ++ set_inproc_event( job->inproc_sync ); ++} ++ ++static struct inproc_sync *job_get_inproc_sync( struct object *obj ) ++{ ++ struct job *job = (struct job *)obj; ++ ++ if (!job->inproc_sync) ++ job->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, job->signaled ); ++ if (job->inproc_sync) grab_object( job->inproc_sync ); ++ return job->inproc_sync; + } + + static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) +@@ -454,6 +468,8 @@ static void job_destroy( struct object *obj ) + list_remove( &job->parent_job_entry ); + release_object( job->parent ); + } ++ ++ if (job->inproc_sync) release_object( job->inproc_sync ); + } + + static void job_dump( struct object *obj, int verbose ) +-- +2.47.1 + + diff --git a/0007-ntsync/0015-server-Create-in-process-synchronization-objects-for-message-queues.patch b/0007-ntsync/0015-server-Create-in-process-synchronization-objects-for-message-queues.patch new file mode 100644 index 0000000..5458092 --- /dev/null +++ b/0007-ntsync/0015-server-Create-in-process-synchronization-objects-for-message-queues.patch @@ -0,0 +1,154 @@ +From 9137e8f6e2b3498ddcca1166ead1e0a1926b42e7 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 01:24:15 +0200 +Subject: [PATCH 15/32] server: Create in-process synchronization objects for + message queues. + +--- + server/queue.c | 44 +++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/server/queue.c b/server/queue.c +index ddcf45ff519..323f0f90e2c 100644 +--- a/server/queue.c ++++ b/server/queue.c +@@ -135,6 +135,7 @@ struct msg_queue + timeout_t last_get_msg; /* time of last get message call */ + int keystate_lock; /* owns an input keystate lock */ + const queue_shm_t *shared; /* queue in session shared memory */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */ + int esync_fd; /* esync file descriptor (signalled on message) */ + int esync_in_msgwait; /* our thread is currently waiting on us */ +@@ -159,6 +160,7 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr + static int msg_queue_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int msg_queue_get_fsync_idx( struct object *obj, enum fsync_type *type ); + static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *msg_queue_get_inproc_sync( struct object *obj ); + static void msg_queue_destroy( struct object *obj ); + static void msg_queue_poll_event( struct fd *fd, int event ); + static void thread_input_dump( struct object *obj, int verbose ); +@@ -187,7 +189,7 @@ static const struct object_ops msg_queue_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ msg_queue_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + msg_queue_destroy /* destroy */ + }; +@@ -327,6 +329,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ + queue->hooks = NULL; + queue->last_get_msg = current_time; + queue->keystate_lock = 0; ++ queue->inproc_sync = NULL; + queue->ignore_post_msg = 0; + queue->esync_fd = -1; + queue->esync_in_msgwait = 0; +@@ -754,7 +757,11 @@ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) + } + SHARED_WRITE_END; + +- if (is_signaled( queue )) wake_up( &queue->obj, 0 ); ++ if (is_signaled( queue )) ++ { ++ wake_up( &queue->obj, 0 ); ++ set_inproc_event( queue->inproc_sync ); ++ } + } + + /* clear some queue bits */ +@@ -780,6 +787,9 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits + if (queue->keystate_lock) unlock_input_keystate( queue->input ); + queue->keystate_lock = 0; + } ++ ++ if (!is_signaled( queue )) ++ reset_inproc_event( queue->inproc_sync ); + } + + /* check if message is matched by the filter */ +@@ -1355,6 +1365,18 @@ static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *en + shared->changed_mask = 0; + } + SHARED_WRITE_END; ++ ++ reset_inproc_event( queue->inproc_sync ); ++} ++ ++static struct inproc_sync *msg_queue_get_inproc_sync( struct object *obj ) ++{ ++ struct msg_queue *queue = (struct msg_queue *)obj; ++ ++ if (!queue->inproc_sync) ++ queue->inproc_sync = create_inproc_event( INPROC_SYNC_QUEUE, is_signaled( queue ) ); ++ if (queue->inproc_sync) grab_object( queue->inproc_sync ); ++ return queue->inproc_sync; + } + + static void msg_queue_destroy( struct object *obj ) +@@ -1402,6 +1424,7 @@ static void msg_queue_destroy( struct object *obj ) + if (queue->shared) free_shared_object( queue->shared ); + if (do_esync()) close( queue->esync_fd ); + if (queue->fsync_idx) fsync_free_shm_idx( queue->fsync_idx ); ++ if (queue->inproc_sync) release_object( queue->inproc_sync ); + } + + static void msg_queue_poll_event( struct fd *fd, int event ) +@@ -1412,6 +1435,7 @@ static void msg_queue_poll_event( struct fd *fd, int event ) + if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 ); + else set_fd_events( queue->fd, 0 ); + wake_up( &queue->obj, 0 ); ++ set_inproc_event( queue->inproc_sync ); + } + + static void thread_input_dump( struct object *obj, int verbose ) +@@ -3187,7 +3211,15 @@ DECL_HANDLER(set_queue_mask) + } + SHARED_WRITE_END; + } +- else wake_up( &queue->obj, 0 ); ++ else ++ { ++ wake_up( &queue->obj, 0 ); ++ set_inproc_event( queue->inproc_sync ); ++ } ++ } ++ else ++ { ++ reset_inproc_event( queue->inproc_sync ); + } + + if (do_fsync() && !is_signaled( queue )) +@@ -3221,6 +3253,9 @@ DECL_HANDLER(get_queue_status) + shared->changed_bits &= ~req->clear_bits; + } + SHARED_WRITE_END; ++ ++ if (!is_signaled( queue )) ++ reset_inproc_event( queue->inproc_sync ); + } + else reply->wake_bits = reply->changed_bits = 0; + } +@@ -3419,6 +3454,9 @@ DECL_HANDLER(get_message) + } + SHARED_WRITE_END; + ++ if (!is_signaled( queue )) ++ reset_inproc_event( queue->inproc_sync ); ++ + /* then check for posted messages */ + if ((filter & QS_POSTMESSAGE) && + get_posted_message( queue, queue->ignore_post_msg, get_win, req->get_first, req->get_last, req->flags, reply )) +@@ -3488,6 +3526,7 @@ DECL_HANDLER(get_message) + } + SHARED_WRITE_END; + ++ reset_inproc_event( queue->inproc_sync ); + set_error( STATUS_PENDING ); /* FIXME */ + + if (do_fsync() && !is_signaled( queue )) +-- +2.47.1 + + diff --git a/0007-ntsync/0016-server-Create-in-process-synchronization-objects-for-threads.patch b/0007-ntsync/0016-server-Create-in-process-synchronization-objects-for-threads.patch new file mode 100644 index 0000000..82bd93e --- /dev/null +++ b/0007-ntsync/0016-server-Create-in-process-synchronization-objects-for-threads.patch @@ -0,0 +1,89 @@ +From 98dbf9e61293883e49774c0b526251921c67165c Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 01:26:35 +0200 +Subject: [PATCH 16/32] server: Create in-process synchronization objects for + threads. + +--- + server/thread.c | 16 +++++++++++++++- + server/thread.h | 1 + + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/server/thread.c b/server/thread.c +index 30caeba7622..ea57e7303c0 100644 +--- a/server/thread.c ++++ b/server/thread.c +@@ -187,6 +187,7 @@ static unsigned int thread_get_fsync_idx( struct object *obj, enum fsync_type *t + static unsigned int thread_map_access( struct object *obj, unsigned int access ); + static void thread_poll_event( struct fd *fd, int event ); + static struct list *thread_get_kernel_obj_list( struct object *obj ); ++static struct inproc_sync *thread_get_inproc_sync( struct object *obj ); + static void destroy_thread( struct object *obj ); + + static const struct object_ops thread_ops = +@@ -211,7 +212,7 @@ static const struct object_ops thread_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + thread_get_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ thread_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + destroy_thread /* destroy */ + }; +@@ -262,6 +263,7 @@ static inline void init_thread_structure( struct thread *thread ) + thread->token = NULL; + thread->desc = NULL; + thread->desc_len = 0; ++ thread->inproc_sync = NULL; + thread->exit_poll = NULL; + + thread->creation_time = current_time; +@@ -428,6 +430,16 @@ static struct list *thread_get_kernel_obj_list( struct object *obj ) + return &thread->kernel_object; + } + ++static struct inproc_sync *thread_get_inproc_sync( struct object *obj ) ++{ ++ struct thread *thread = (struct thread *)obj; ++ ++ if (!thread->inproc_sync) ++ thread->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, thread->state == TERMINATED ); ++ if (thread->inproc_sync) grab_object( thread->inproc_sync ); ++ return thread->inproc_sync; ++} ++ + /* cleanup everything that is no longer needed by a dead thread */ + /* used by destroy_thread and kill_thread */ + static void cleanup_thread( struct thread *thread ) +@@ -492,6 +504,7 @@ static void destroy_thread( struct object *obj ) + fsync_free_shm_idx( thread->fsync_idx ); + fsync_free_shm_idx( thread->fsync_apc_idx ); + } ++ if (thread->inproc_sync) release_object( thread->inproc_sync ); + } + + /* dump a thread on stdout for debugging purposes */ +@@ -1394,6 +1407,7 @@ void kill_thread( struct thread *thread, int violent_death ) + fsync_abandon_mutexes( thread ); + if (do_esync()) + esync_abandon_mutexes( thread ); ++ set_inproc_event( thread->inproc_sync ); + if (violent_death) + { + send_thread_signal( thread, SIGQUIT ); +diff --git a/server/thread.h b/server/thread.h +index 416b01db318..b5afb565ef4 100644 +--- a/server/thread.h ++++ b/server/thread.h +@@ -100,6 +100,7 @@ struct thread + struct object *input_shared_mapping; /* thread input shared memory mapping */ + input_shm_t *input_shared; /* thread input shared memory ptr */ + struct completion_wait *completion_wait; /* completion port wait object the thread is associated with */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + }; + + extern struct thread *current; +-- +2.47.1 + + diff --git a/0007-ntsync/0017-server-Create-in-process-synchronization-objects-for-timers.patch b/0007-ntsync/0017-server-Create-in-process-synchronization-objects-for-timers.patch new file mode 100644 index 0000000..1885566 --- /dev/null +++ b/0007-ntsync/0017-server-Create-in-process-synchronization-objects-for-timers.patch @@ -0,0 +1,96 @@ +From 4ce49febd0d8e571e99b899a88a5b3f044a040e6 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 01:29:38 +0200 +Subject: [PATCH 17/32] server: Create in-process synchronization objects for + timers. + +--- + server/timer.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/server/timer.c b/server/timer.c +index 247b19c8305..16a7aed690c 100644 +--- a/server/timer.c ++++ b/server/timer.c +@@ -63,6 +63,7 @@ struct timer + struct thread *thread; /* thread that set the APC function */ + client_ptr_t callback; /* callback APC function */ + client_ptr_t arg; /* callback argument */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + int esync_fd; /* esync file descriptor */ + unsigned int fsync_idx; /* fsync shm index */ + }; +@@ -72,6 +73,7 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ); + static int timer_get_esync_fd( struct object *obj, enum esync_type *type ); + static unsigned int timer_get_fsync_idx( struct object *obj, enum fsync_type *type ); + static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ); ++static struct inproc_sync *timer_get_inproc_sync( struct object *obj ); + static void timer_destroy( struct object *obj ); + + static const struct object_ops timer_ops = +@@ -96,7 +98,7 @@ static const struct object_ops timer_ops = + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ timer_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + timer_destroy /* destroy */ + }; +@@ -119,6 +121,7 @@ static struct timer *create_timer( struct object *root, const struct unicode_str + timer->period = 0; + timer->timeout = NULL; + timer->thread = NULL; ++ timer->inproc_sync = NULL; + timer->esync_fd = -1; + timer->fsync_idx = 0; + +@@ -168,6 +171,7 @@ static void timer_callback( void *private ) + /* wake up waiters */ + timer->signaled = 1; + wake_up( &timer->obj, 0 ); ++ set_inproc_event( timer->inproc_sync ); + } + + /* cancel a running timer */ +@@ -204,6 +208,8 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period + + if (do_esync()) + esync_clear( timer->esync_fd ); ++ ++ reset_inproc_event( timer->inproc_sync ); + } + timer->when = (expire <= 0) ? expire - monotonic_time : max( expire, current_time ); + timer->period = period; +@@ -252,6 +258,19 @@ static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry + if (!timer->manual) timer->signaled = 0; + } + ++static struct inproc_sync *timer_get_inproc_sync( struct object *obj ) ++{ ++ struct timer *timer = (struct timer *)obj; ++ ++ if (!timer->inproc_sync) ++ { ++ enum inproc_sync_type type = timer->manual ? INPROC_SYNC_MANUAL_SERVER : INPROC_SYNC_AUTO_SERVER; ++ timer->inproc_sync = create_inproc_event( type, timer->signaled ); ++ } ++ if (timer->inproc_sync) grab_object( timer->inproc_sync ); ++ return timer->inproc_sync; ++} ++ + static void timer_destroy( struct object *obj ) + { + struct timer *timer = (struct timer *)obj; +@@ -261,6 +280,7 @@ static void timer_destroy( struct object *obj ) + if (timer->thread) release_object( timer->thread ); + if (do_esync()) close( timer->esync_fd ); + if (timer->fsync_idx) fsync_free_shm_idx( timer->fsync_idx ); ++ if (timer->inproc_sync) release_object( timer->inproc_sync ); + } + + /* create a timer */ +-- +2.47.1 + + diff --git a/0007-ntsync/0018-server-Create-in-process-synchronization-objects-for-fd-based-objects.patch b/0007-ntsync/0018-server-Create-in-process-synchronization-objects-for-fd-based-objects.patch new file mode 100644 index 0000000..6130f26 --- /dev/null +++ b/0007-ntsync/0018-server-Create-in-process-synchronization-objects-for-fd-based-objects.patch @@ -0,0 +1,242 @@ +From 6fba08cb22366f64b3005967cc853510807e951f Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:40:57 -0600 +Subject: [PATCH 17/30] server: Create in-process synchronization objects for + fd-based objects. + +--- + server/change.c | 2 +- + server/device.c | 2 +- + server/fd.c | 27 ++++++++++++++++++++++++++- + server/file.c | 2 +- + server/file.h | 1 + + server/mailslot.c | 6 +++--- + server/named_pipe.c | 8 ++++---- + server/serial.c | 2 +- + server/sock.c | 2 +- + 9 files changed, 39 insertions(+), 13 deletions(-) + +diff --git a/server/change.c b/server/change.c +index 54fcfade398..92d321c8784 100644 +--- a/server/change.c ++++ b/server/change.c +@@ -124,7 +124,7 @@ static const struct object_ops dir_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + dir_close_handle, /* close_handle */ + dir_destroy /* destroy */ + }; +diff --git a/server/device.c b/server/device.c +index f067db0d9aa..72410c2da8b 100644 +--- a/server/device.c ++++ b/server/device.c +@@ -232,7 +232,7 @@ static const struct object_ops device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + device_file_get_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + device_file_close_handle, /* close_handle */ + device_file_destroy /* destroy */ + }; +diff --git a/server/fd.c b/server/fd.c +index 9004f4cd0b7..77ac22b9655 100644 +--- a/server/fd.c ++++ b/server/fd.c +@@ -154,6 +154,7 @@ struct fd + struct completion *completion; /* completion object attached to this fd */ + apc_param_t comp_key; /* completion key to set in completion events */ + unsigned int comp_flags; /* completion flags */ ++ struct inproc_sync *inproc_sync; /* in-process synchronization object */ + int esync_fd; /* esync file descriptor */ + unsigned int fsync_idx; /* fsync shm index */ + }; +@@ -1804,6 +1805,7 @@ static void fd_destroy( struct object *obj ) + if (do_esync()) + close( fd->esync_fd ); + if (fd->fsync_idx) fsync_free_shm_idx( fd->fsync_idx ); ++ if (fd->inproc_sync) release_object( fd->inproc_sync ); + } + + /* check if the desired access is possible without violating */ +@@ -1694,6 +1696,7 @@ static struct fd *alloc_fd_object(void) + fd->poll_index = -1; + fd->completion = NULL; + fd->comp_flags = 0; ++ fd->inproc_sync = NULL; + fd->esync_fd = -1; + fd->fsync_idx = 0; + init_async_queue( &fd->read_q ); +@@ -1734,6 +1737,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use + fd->poll_index = -1; + fd->completion = NULL; + fd->comp_flags = 0; ++ fd->inproc_sync = NULL; + fd->no_fd_status = STATUS_BAD_DEVICE_TYPE; + fd->esync_fd = -1; + fd->fsync_idx = 0; +@@ -2144,7 +2148,15 @@ void set_fd_signaled( struct fd *fd, int signaled ) + { + if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return; + fd->signaled = signaled; +- if (signaled) wake_up( fd->user, 0 ); ++ if (signaled) ++ { ++ wake_up( fd->user, 0 ); ++ set_inproc_event( fd->inproc_sync ); ++ } ++ else ++ { ++ reset_inproc_event( fd->inproc_sync ); ++ } + + if (do_fsync() && !signaled) + fsync_clear( fd->user ); +@@ -2170,6 +2182,19 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ) + return ret; + } + ++struct inproc_sync *default_fd_get_inproc_sync( struct object *obj ) ++{ ++ struct fd *fd = get_obj_fd( obj ); ++ struct inproc_sync *ret; ++ ++ if (!fd->inproc_sync) ++ fd->inproc_sync = create_inproc_event( INPROC_SYNC_MANUAL_SERVER, fd->signaled ); ++ ret = fd->inproc_sync; ++ release_object( fd ); ++ if (ret) grab_object( ret ); ++ return ret; ++} ++ + int default_fd_get_poll_events( struct fd *fd ) + { + int events = 0; +diff --git a/server/file.c b/server/file.c +index dbbbad43707..bab203b1914 100644 +--- a/server/file.c ++++ b/server/file.c +@@ -106,7 +106,7 @@ static const struct object_ops file_ops = + NULL, /* unlink_name */ + file_open_file, /* open_file */ + file_get_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + file_destroy /* destroy */ + }; +diff --git a/server/file.h b/server/file.h +index 4f5fc7b26f1..882976e9e02 100644 +--- a/server/file.h ++++ b/server/file.h +@@ -109,6 +109,7 @@ extern char *dup_fd_name( struct fd *root, const char *name ) __WINE_DEALLOC(fre + extern void get_nt_name( struct fd *fd, struct unicode_str *name ); + + extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ); ++extern struct inproc_sync *default_fd_get_inproc_sync( struct object *obj ); + extern int default_fd_get_esync_fd( struct object *obj, enum esync_type *type ); + extern unsigned int default_fd_get_fsync_idx( struct object *obj, enum fsync_type *type ); + extern int default_fd_get_poll_events( struct fd *fd ); +diff --git a/server/mailslot.c b/server/mailslot.c +index 4533ceee516..701ac35f393 100644 +--- a/server/mailslot.c ++++ b/server/mailslot.c +@@ -93,7 +93,7 @@ static const struct object_ops mailslot_ops = + default_unlink_name, /* unlink_name */ + mailslot_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync,/* get_inproc_sync */ + no_close_handle, /* close_handle */ + mailslot_destroy /* destroy */ + }; +@@ -155,7 +155,7 @@ static const struct object_ops mail_writer_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mail_writer_destroy /* destroy */ + }; +@@ -252,7 +252,7 @@ static const struct object_ops mailslot_device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + mailslot_device_file_destroy /* destroy */ + }; +diff --git a/server/named_pipe.c b/server/named_pipe.c +index fd10bbc474a..04e8f49fb79 100644 +--- a/server/named_pipe.c ++++ b/server/named_pipe.c +@@ -180,7 +180,7 @@ static const struct object_ops pipe_server_ops = + NULL, /* unlink_name */ + pipe_server_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + async_close_obj_handle, /* close_handle */ + pipe_server_destroy /* destroy */ + }; +@@ -225,7 +225,7 @@ static const struct object_ops pipe_client_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + async_close_obj_handle, /* close_handle */ + pipe_end_destroy /* destroy */ + }; +@@ -305,7 +305,7 @@ static const struct object_ops named_pipe_device_file_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_device_file_destroy /* destroy */ + }; +@@ -356,7 +356,7 @@ static const struct object_ops named_pipe_dir_ops = + NULL, /* unlink_name */ + named_pipe_dir_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + named_pipe_dir_destroy /* destroy */ + }; +diff --git a/server/serial.c b/server/serial.c +index df242058a43..93753328d4d 100644 +--- a/server/serial.c ++++ b/server/serial.c +@@ -103,7 +103,7 @@ static const struct object_ops serial_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + no_close_handle, /* close_handle */ + serial_destroy /* destroy */ + }; +diff --git a/server/sock.c b/server/sock.c +index f186aff51fd..09366ea7dde 100644 +--- a/server/sock.c ++++ b/server/sock.c +@@ -483,7 +483,7 @@ static const struct object_ops sock_ops = + NULL, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ +- no_get_inproc_sync, /* get_inproc_sync */ ++ default_fd_get_inproc_sync, /* get_inproc_sync */ + sock_close_handle, /* close_handle */ + sock_destroy /* destroy */ + }; +-- +2.47.1 + diff --git a/0007-ntsync/0019-server-Add-a-request-to-retrieve-the-in-process-synchronization-device.patch b/0007-ntsync/0019-server-Add-a-request-to-retrieve-the-in-process-synchronization-device.patch new file mode 100644 index 0000000..338aa4e --- /dev/null +++ b/0007-ntsync/0019-server-Add-a-request-to-retrieve-the-in-process-synchronization-device.patch @@ -0,0 +1,62 @@ +From 3a9d8ac85ee930d38dc89e23ff32182e4e5566eb Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:46:06 -0600 +Subject: [PATCH 19/32] server: Add a request to retrieve the in-process + synchronization device. + +--- + server/inproc_sync.c | 17 +++++++++++++++++ + server/protocol.def | 7 +++++++ + 2 files changed, 24 insertions(+) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index 11c0a87d13f..b69a39f027c 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -29,6 +29,8 @@ + #include "winternl.h" + + #include "file.h" ++#include "handle.h" ++#include "request.h" + #include "thread.h" + + #ifdef HAVE_LINUX_NTSYNC_H +@@ -375,3 +377,18 @@ void abandon_inproc_mutex( thread_id_t tid, struct inproc_sync *inproc_sync ) + } + + #endif ++ ++DECL_HANDLER(get_linux_sync_device) ++{ ++#ifdef HAVE_LINUX_NTSYNC_H ++ struct linux_device *device; ++ ++ if ((device = get_linux_device())) ++ { ++ reply->handle = alloc_handle_no_access_check( current->process, device, 0, 0 ); ++ release_object( device ); ++ } ++#else ++ set_error( STATUS_NOT_IMPLEMENTED ); ++#endif ++} +diff --git a/server/protocol.def b/server/protocol.def +index 06dd44d3e79..dc53d2b5716 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -4217,3 +4217,10 @@ enum inproc_sync_type + INPROC_SYNC_MANUAL_SERVER, + INPROC_SYNC_QUEUE, + }; ++ ++ ++/* Obtain a handle to the ntsync device object */ ++@REQ(get_linux_sync_device) ++@REPLY ++ obj_handle_t handle; /* handle to the device */ ++@END +-- +2.47.1 + + diff --git a/0007-ntsync/0020-server-Add-a-request-to-retrieve-the-in-process-synchronization-object-from-a-handle.patch b/0007-ntsync/0020-server-Add-a-request-to-retrieve-the-in-process-synchronization-object-from-a-handle.patch new file mode 100644 index 0000000..c68bdac --- /dev/null +++ b/0007-ntsync/0020-server-Add-a-request-to-retrieve-the-in-process-synchronization-object-from-a-handle.patch @@ -0,0 +1,64 @@ +From 51b8e5da6fef71ba7fe5a018beb82710f76bc3e6 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Mon, 8 Mar 2021 17:55:00 -0600 +Subject: [PATCH 20/32] server: Add a request to retrieve the in-process + synchronization object from a handle. + +--- + server/inproc_sync.c | 23 +++++++++++++++++++++++ + server/protocol.def | 10 ++++++++++ + 2 files changed, 33 insertions(+) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index b69a39f027c..c50bbb52bbc 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -392,3 +392,26 @@ DECL_HANDLER(get_linux_sync_device) + set_error( STATUS_NOT_IMPLEMENTED ); + #endif + } ++ ++DECL_HANDLER(get_linux_sync_obj) ++{ ++#ifdef HAVE_LINUX_NTSYNC_H ++ struct object *obj; ++ ++ if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) ++ { ++ struct inproc_sync *inproc_sync; ++ ++ if ((inproc_sync = obj->ops->get_inproc_sync( obj ))) ++ { ++ reply->handle = alloc_handle_no_access_check( current->process, inproc_sync, 0, 0 ); ++ reply->type = inproc_sync->type; ++ reply->access = get_handle_access( current->process, req->handle ); ++ release_object( inproc_sync ); ++ } ++ release_object( obj ); ++ } ++#else ++ set_error( STATUS_NOT_IMPLEMENTED ); ++#endif ++} +diff --git a/server/protocol.def b/server/protocol.def +index dc53d2b5716..488fa3f973f 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -4224,3 +4224,13 @@ enum inproc_sync_type + @REPLY + obj_handle_t handle; /* handle to the device */ + @END ++ ++ ++/* Get the in-process synchronization object associated with the given handle */ ++@REQ(get_linux_sync_obj) ++ obj_handle_t handle; /* handle to the object */ ++@REPLY ++ obj_handle_t handle; /* handle to the fast synchronization object */ ++ int type; /* object type */ ++ unsigned int access; /* handle access rights */ ++@END +-- +2.47.1 + + diff --git a/0007-ntsync/0021-server-Introduce-select_inproc_queue-and-unselect_inproc_queue-requests.patch b/0007-ntsync/0021-server-Introduce-select_inproc_queue-and-unselect_inproc_queue-requests.patch new file mode 100644 index 0000000..8111bcc --- /dev/null +++ b/0007-ntsync/0021-server-Introduce-select_inproc_queue-and-unselect_inproc_queue-requests.patch @@ -0,0 +1,107 @@ +From 485c24acffbcfa97ae195b9aface52cffeff6dad Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 19:32:25 +0200 +Subject: [PATCH 21/32] server: Introduce select_inproc_queue and + unselect_inproc_queue requests. + +--- + server/protocol.def | 11 +++++++++++ + server/queue.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 55 insertions(+) + +diff --git a/server/protocol.def b/server/protocol.def +index 488fa3f973f..8868c0bfc57 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -4234,3 +4234,14 @@ enum inproc_sync_type + int type; /* object type */ + unsigned int access; /* handle access rights */ + @END ++ ++ ++/* Begin a client-side wait on a message queue */ ++@REQ(select_inproc_queue) ++@END ++ ++ ++/* End a client-side wait on a message queue */ ++@REQ(unselect_inproc_queue) ++ int signaled; /* was the queue signaled? */ ++@END +diff --git a/server/queue.c b/server/queue.c +index 323f0f90e2c..7ca7a85035d 100644 +--- a/server/queue.c ++++ b/server/queue.c +@@ -140,6 +140,7 @@ struct msg_queue + int keystate_lock; /* owns an input keystate lock */ + const queue_shm_t *shared; /* thread queue shared memory ptr */ + struct inproc_sync *inproc_sync; /* in-process synchronization object */ ++ int in_inproc_wait; /* are we in a client-side wait? */ + unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */ + int esync_fd; /* esync file descriptor (signalled on message) */ + int esync_in_msgwait; /* our thread is currently waiting on us */ +@@ -352,6 +353,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ + queue->last_get_msg = current_time; + queue->keystate_lock = 0; + queue->inproc_sync = NULL; ++ queue->in_inproc_wait = 0; + queue->ignore_post_msg = 0; + queue->esync_fd = -1; + queue->esync_in_msgwait = 0; +@@ -1280,6 +1282,9 @@ static int is_queue_hung( struct msg_queue *queue ) + if (do_esync() && queue->esync_in_msgwait) + return 0; /* thread is waiting on queue in absentia -> not hung */ + ++ if (queue->in_inproc_wait) ++ return 0; /* thread is waiting on queue in absentia -> not hung */ ++ + return 1; + } + +@@ -4100,3 +4105,42 @@ DECL_HANDLER(fsync_msgwait) + if (queue->fd) + set_fd_events( queue->fd, req->in_msgwait ? POLLIN : 0 ); + } ++ ++DECL_HANDLER(select_inproc_queue) ++{ ++ struct msg_queue *queue = current->queue; ++ ++ if (queue->in_inproc_wait) ++ { ++ set_error( STATUS_ACCESS_DENIED ); ++ } ++ else ++ { ++ check_thread_queue_idle( current ); ++ ++ if (queue->fd) ++ set_fd_events( queue->fd, POLLIN ); ++ ++ queue->in_inproc_wait = 1; ++ } ++} ++ ++DECL_HANDLER(unselect_inproc_queue) ++{ ++ struct msg_queue *queue = current->queue; ++ ++ if (!queue->in_inproc_wait) ++ { ++ set_error( STATUS_ACCESS_DENIED ); ++ } ++ else ++ { ++ if (queue->fd) ++ set_fd_events( queue->fd, 0 ); ++ ++ if (req->signaled) ++ msg_queue_satisfied( &queue->obj, NULL ); ++ ++ queue->in_inproc_wait = 0; ++ } ++} +-- +2.47.1 + + diff --git a/0007-ntsync/0022-server-Allow-creating-an-event-object-for-client-side-user-APC-signaling.patch b/0007-ntsync/0022-server-Allow-creating-an-event-object-for-client-side-user-APC-signaling.patch new file mode 100644 index 0000000..90f7a1b --- /dev/null +++ b/0007-ntsync/0022-server-Allow-creating-an-event-object-for-client-side-user-APC-signaling.patch @@ -0,0 +1,105 @@ +From 8cdf1ad54a1b970c5d3d703a5429399375d20436 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Fri, 22 Apr 2022 00:11:14 +0300 +Subject: [PATCH 22/32] server: Allow creating an event object for client-side + user APC signaling. + +--- + server/protocol.def | 7 +++++++ + server/thread.c | 19 +++++++++++++++++++ + server/thread.h | 1 + + 3 files changed, 27 insertions(+) + +diff --git a/server/protocol.def b/server/protocol.def +index 8868c0bfc57..3c35f2e39ba 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -4245,3 +4245,10 @@ enum inproc_sync_type + @REQ(unselect_inproc_queue) + int signaled; /* was the queue signaled? */ + @END ++ ++ ++/* Get an event handle to be used for thread alerts with in-process synchronization */ ++@REQ(get_inproc_alert_event) ++@REPLY ++ obj_handle_t handle; /* handle to the event */ ++@END +diff --git a/server/thread.c b/server/thread.c +index ea57e7303c0..cfd4c2c4256 100644 +--- a/server/thread.c ++++ b/server/thread.c +@@ -312,6 +312,7 @@ static inline void init_thread_structure( struct thread *thread ) + thread->desc = NULL; + thread->desc_len = 0; + thread->inproc_sync = NULL; ++ thread->inproc_alert_event = NULL; + thread->exit_poll = NULL; + + thread->creation_time = current_time; +@@ -621,6 +622,7 @@ static void destroy_thread( struct object *obj ) + fsync_free_shm_idx( thread->fsync_apc_idx ); + } + if (thread->inproc_sync) release_object( thread->inproc_sync ); ++ if (thread->inproc_alert_event) release_object( thread->inproc_alert_event ); + } + + /* dump a thread on stdout for debugging purposes */ +@@ -1402,6 +1404,9 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr + + if (do_esync() && queue == &thread->user_apc) + esync_wake_fd( thread->esync_apc_fd ); ++ ++ if (apc->call.type == APC_USER && thread->inproc_alert_event) ++ set_event( thread->inproc_alert_event ); + } + + return 1; +@@ -1434,6 +1439,8 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty + apc->executed = 1; + wake_up( &apc->obj, 0 ); + release_object( apc ); ++ if (list_empty( &thread->user_apc ) && thread->inproc_alert_event) ++ reset_event( thread->inproc_alert_event ); + return; + } + } +@@ -1448,6 +1455,9 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system + { + apc = LIST_ENTRY( ptr, struct thread_apc, entry ); + list_remove( ptr ); ++ ++ if (list_empty( &thread->user_apc ) && thread->inproc_alert_event) ++ reset_event( thread->inproc_alert_event ); + } + + if (do_fsync() && list_empty( &thread->system_apc ) && list_empty( &thread->user_apc )) +@@ -2325,3 +2335,12 @@ DECL_HANDLER(get_next_thread) + set_error( STATUS_NO_MORE_ENTRIES ); + release_object( process ); + } ++ ++DECL_HANDLER(get_inproc_alert_event) ++{ ++ if (!current->inproc_alert_event) ++ current->inproc_alert_event = create_event( NULL, NULL, 0, 1, !list_empty( ¤t->user_apc ), NULL ); ++ ++ if (current->inproc_alert_event) ++ reply->handle = alloc_handle( current->process, current->inproc_alert_event, SYNCHRONIZE, 0 ); ++} +diff --git a/server/thread.h b/server/thread.h +index b5afb565ef4..06d861b2776 100644 +--- a/server/thread.h ++++ b/server/thread.h +@@ -101,6 +101,7 @@ struct thread + input_shm_t *input_shared; /* thread input shared memory ptr */ + struct completion_wait *completion_wait; /* completion port wait object the thread is associated with */ + struct inproc_sync *inproc_sync; /* in-process synchronization object */ ++ struct event *inproc_alert_event; /* in-process synchronization alert event */ + }; + + extern struct thread *current; +-- +2.47.1 + + diff --git a/0007-ntsync/0023-ntdll-Introduce-a-helper-to-wait-on-an-internal-server-handle.patch b/0007-ntsync/0023-ntdll-Introduce-a-helper-to-wait-on-an-internal-server-handle.patch new file mode 100644 index 0000000..892be8d --- /dev/null +++ b/0007-ntsync/0023-ntdll-Introduce-a-helper-to-wait-on-an-internal-server-handle.patch @@ -0,0 +1,104 @@ +From 0d669b31b010f97ad579d7210db85a0d59b5729a Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 02:07:23 +0200 +Subject: [PATCH 23/32] ntdll: Introduce a helper to wait on an internal server + handle. + +--- + dlls/ntdll/unix/file.c | 2 +- + dlls/ntdll/unix/process.c | 2 +- + dlls/ntdll/unix/server.c | 17 ++++++++++++++++- + dlls/ntdll/unix/thread.c | 2 +- + dlls/ntdll/unix/unix_private.h | 1 + + 5 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index 61f7522cab6..a70c487f9f4 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -6895,7 +6895,7 @@ NTSTATUS WINAPI NtLockFile( HANDLE file, HANDLE event, PIO_APC_ROUTINE apc, void + } + if (handle) + { +- NtWaitForSingleObject( handle, FALSE, NULL ); ++ server_wait_for_object( handle, FALSE, NULL ); + NtClose( handle ); + } + else /* Unix lock conflict, sleep a bit and retry */ +diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c +index 3085510243f..85fc32b9334 100644 +--- a/dlls/ntdll/unix/process.c ++++ b/dlls/ntdll/unix/process.c +@@ -916,7 +916,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_ + + /* wait for the new process info to be ready */ + +- NtWaitForSingleObject( process_info, FALSE, NULL ); ++ server_wait_for_object( process_info, FALSE, NULL ); + SERVER_START_REQ( get_new_process_info ) + { + req->info = wine_server_obj_handle( process_info ); +diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c +index 992e5cfdc3d..d31d31be64f 100644 +--- a/dlls/ntdll/unix/server.c ++++ b/dlls/ntdll/unix/server.c +@@ -800,6 +800,21 @@ unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT f + } + + ++/* helper function to perform a server-side wait on an internal handle without ++ * using the fast synchronization path */ ++unsigned int server_wait_for_object( HANDLE handle, BOOL alertable, const LARGE_INTEGER *timeout ) ++{ ++ union select_op select_op; ++ UINT flags = SELECT_INTERRUPTIBLE; ++ ++ if (alertable) flags |= SELECT_ALERTABLE; ++ ++ select_op.wait.op = SELECT_WAIT; ++ select_op.wait.handles[0] = wine_server_obj_handle( handle ); ++ return server_wait( &select_op, offsetof( union select_op, wait.handles[1] ), flags, timeout ); ++} ++ ++ + /*********************************************************************** + * NtContinue (NTDLL.@) + */ +@@ -861,7 +876,7 @@ unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, a + } + else + { +- NtWaitForSingleObject( handle, FALSE, NULL ); ++ server_wait_for_object( handle, FALSE, NULL ); + + SERVER_START_REQ( get_apc_result ) + { +diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c +index c3ab1317295..8314d8800b0 100644 +--- a/dlls/ntdll/unix/thread.c ++++ b/dlls/ntdll/unix/thread.c +@@ -1808,7 +1808,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma + + if (ret == STATUS_PENDING) + { +- NtWaitForSingleObject( context_handle, FALSE, NULL ); ++ server_wait_for_object( context_handle, FALSE, NULL ); + + SERVER_START_REQ( get_thread_context ) + { +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index 9dc8ea627e0..8c335cd1efd 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -214,6 +214,7 @@ extern unsigned int server_select( const union select_op *select_op, data_size_t siz + timeout_t abs_timeout, context_t *context, user_apc_t *user_apc ); + extern unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT flags, + const LARGE_INTEGER *timeout ); ++extern unsigned int server_wait_for_object( HANDLE handle, BOOL alertable, const LARGE_INTEGER *timeout ); + extern NTSTATUS wait_internal_server( HANDLE handle, BOOLEAN alertable, const LARGE_INTEGER *timeout ); + extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, + apc_result_t *result ); +-- +2.47.1 + + diff --git a/0007-ntsync/0024-ntdll-Add-some-traces-to-synchronization-methods.patch b/0007-ntsync/0024-ntdll-Add-some-traces-to-synchronization-methods.patch new file mode 100644 index 0000000..2f1df20 --- /dev/null +++ b/0007-ntsync/0024-ntdll-Add-some-traces-to-synchronization-methods.patch @@ -0,0 +1,237 @@ +From 0a692452a3949ed09630a071efe978be50c94d7f Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 9 Mar 2021 20:08:29 +0200 +Subject: [PATCH 24/32] ntdll: Add some traces to synchronization methods. + +Normally we can rely on +server for these, but with fast synchronization we'll +be skipping the server. +--- + dlls/ntdll/unix/sync.c | 59 ++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 57 insertions(+), 2 deletions(-) + +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index 8361f12bb89..22563eb9930 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -76,9 +76,11 @@ HANDLE keyed_event = 0; + static const char *debugstr_timeout( const LARGE_INTEGER *timeout ) + { + if (!timeout) return "(infinite)"; +- return wine_dbgstr_longlong( timeout->QuadPart ); ++ return wine_dbg_sprintf( "%lld.%07ld", (long long)(timeout->QuadPart / TICKSPERSEC), ++ (long)(timeout->QuadPart % TICKSPERSEC) ); + } + ++ + /* return a monotonic time counter, in Win32 ticks */ + static inline ULONGLONG monotonic_counter(void) + { +@@ -273,6 +275,9 @@ NTSTATUS WINAPI NtCreateSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJ + data_size_t len; + struct object_attributes *objattr; + ++ TRACE( "access %#x, name %s, initial %d, max %d\n", (int)access, ++ attr ? debugstr_us(attr->ObjectName) : "(null)", (int)initial, (int)max ); ++ + *handle = 0; + if (max <= 0 || initial < 0 || initial > max) return STATUS_INVALID_PARAMETER; + +@@ -307,6 +312,8 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC + { + unsigned int ret; + ++ TRACE( "access %#x, name %s\n", (int)access, attr ? debugstr_us(attr->ObjectName) : "(null)" ); ++ + *handle = 0; + + if (do_fsync()) +@@ -385,6 +392,8 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, ULONG *previous + if (do_esync()) + return esync_release_semaphore( handle, count, previous ); + ++ TRACE( "handle %p, count %u, prev_count %p\n", handle, (int)count, previous ); ++ + SERVER_START_REQ( release_semaphore ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -409,6 +418,9 @@ NTSTATUS WINAPI NtCreateEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_ + data_size_t len; + struct object_attributes *objattr; + ++ TRACE( "access %#x, name %s, type %u, state %u\n", (int)access, ++ attr ? debugstr_us(attr->ObjectName) : "(null)", type, state ); ++ + *handle = 0; + if (type != NotificationEvent && type != SynchronizationEvent) return STATUS_INVALID_PARAMETER; + +@@ -443,6 +455,8 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT + { + unsigned int ret; + ++ TRACE( "access %#x, name %s\n", (int)access, attr ? debugstr_us(attr->ObjectName) : "(null)" ); ++ + *handle = 0; + if ((ret = validate_open_object_attributes( attr ))) return ret; + +@@ -481,6 +495,8 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state ) + if (do_esync()) + return esync_set_event( handle ); + ++ TRACE( "handle %p, prev_state %p\n", handle, prev_state ); ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -508,6 +524,8 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state ) + return esync_reset_event( handle ); + + ++ TRACE( "handle %p, prev_state %p\n", handle, prev_state ); ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -543,6 +561,8 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state ) + if (do_esync()) + return esync_pulse_event( handle ); + ++ TRACE( "handle %p, prev_state %p\n", handle, prev_state ); ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -605,6 +625,9 @@ NTSTATUS WINAPI NtCreateMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT + data_size_t len; + struct object_attributes *objattr; + ++ TRACE( "access %#x, name %s, owned %u\n", (int)access, ++ attr ? debugstr_us(attr->ObjectName) : "(null)", owned ); ++ + *handle = 0; + + if (do_fsync()) +@@ -637,6 +660,8 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A + { + unsigned int ret; + ++ TRACE( "access %#x, name %s\n", (int)access, attr ? debugstr_us(attr->ObjectName) : "(null)" ); ++ + *handle = 0; + if ((ret = validate_open_object_attributes( attr ))) return ret; + +@@ -674,6 +699,8 @@ NTSTATUS WINAPI NtReleaseMutant( HANDLE handle, LONG *prev_count ) + if (do_esync()) + return esync_release_mutex( handle, prev_count ); + ++ TRACE( "handle %p, prev_count %p\n", handle, prev_count ); ++ + SERVER_START_REQ( release_mutex ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -1417,6 +1444,9 @@ NTSTATUS WINAPI NtCreateTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ + data_size_t len; + struct object_attributes *objattr; + ++ TRACE( "access %#x, name %s, type %u\n", (int)access, ++ attr ? debugstr_us(attr->ObjectName) : "(null)", type ); ++ + *handle = 0; + if (type != NotificationTimer && type != SynchronizationTimer) return STATUS_INVALID_PARAMETER; + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; +@@ -1444,6 +1474,8 @@ NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT + { + unsigned int ret; + ++ TRACE( "access %#x, name %s\n", (int)access, attr ? debugstr_us(attr->ObjectName) : "(null)" ); ++ + *handle = 0; + if ((ret = validate_open_object_attributes( attr ))) return ret; + +@@ -1497,6 +1529,8 @@ NTSTATUS WINAPI NtCancelTimer( HANDLE handle, BOOLEAN *state ) + { + unsigned int ret; + ++ TRACE( "handle %p, state %p\n", handle, state ); ++ + SERVER_START_REQ( cancel_timer ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -1565,6 +1599,7 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO + { + union select_op select_op; + UINT i, flags = SELECT_INTERRUPTIBLE; ++ unsigned int ret; + + if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1; + +@@ -1582,10 +1617,19 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO + return ret; + } + ++ if (TRACE_ON(sync)) ++ { ++ TRACE( "wait_any %u, alertable %u, handles {%p", wait_any, alertable, handles[0] ); ++ for (i = 1; i < count; i++) TRACE( ", %p", handles[i] ); ++ TRACE( "}, timeout %s\n", debugstr_timeout(timeout) ); ++ } ++ + if (alertable) flags |= SELECT_ALERTABLE; + select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL; + for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] ); +- return server_wait( &select_op, offsetof( union select_op, wait.handles[count] ), flags, timeout ); ++ ret = server_wait( &select_op, offsetof( union select_op, wait.handles[count] ), flags, timeout ); ++ TRACE( "-> %#x\n", ret ); ++ return ret; + } + + +@@ -1623,6 +1667,8 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait, + if (do_esync()) + return esync_signal_and_wait( signal, wait, alertable, timeout ); + ++ TRACE( "signal %p, wait %p, alertable %u, timeout %s\n", signal, wait, alertable, debugstr_timeout(timeout) ); ++ + if (!signal) return STATUS_INVALID_HANDLE; + + if (alertable) flags |= SELECT_ALERTABLE; +@@ -1874,6 +1920,9 @@ NTSTATUS WINAPI NtCreateKeyedEvent( HANDLE *handle, ACCESS_MASK access, + data_size_t len; + struct object_attributes *objattr; + ++ TRACE( "access %#x, name %s, flags %#x\n", (int)access, ++ attr ? debugstr_us(attr->ObjectName) : "(null)", (int)flags ); ++ + *handle = 0; + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; + +@@ -1898,6 +1947,8 @@ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJE + { + unsigned int ret; + ++ TRACE( "access %#x, name %s\n", (int)access, attr ? debugstr_us(attr->ObjectName) : "(null)" ); ++ + *handle = 0; + if ((ret = validate_open_object_attributes( attr ))) return ret; + +@@ -1924,6 +1975,8 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key, + union select_op select_op; + UINT flags = SELECT_INTERRUPTIBLE; + ++ TRACE( "handle %p, key %p, alertable %u, timeout %s\n", handle, key, alertable, debugstr_timeout(timeout) ); ++ + if (!handle) handle = keyed_event; + if ((ULONG_PTR)key & 1) return STATUS_INVALID_PARAMETER_1; + if (alertable) flags |= SELECT_ALERTABLE; +@@ -1943,6 +1996,8 @@ NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key, + union select_op select_op; + UINT flags = SELECT_INTERRUPTIBLE; + ++ TRACE( "handle %p, key %p, alertable %u, timeout %s\n", handle, key, alertable, debugstr_timeout(timeout) ); ++ + if (!handle) handle = keyed_event; + if ((ULONG_PTR)key & 1) return STATUS_INVALID_PARAMETER_1; + if (alertable) flags |= SELECT_ALERTABLE; +-- +2.47.1 + + diff --git a/0007-ntsync/0025-ntdll-Use-in-process-synchronization-objects.patch b/0007-ntsync/0025-ntdll-Use-in-process-synchronization-objects.patch new file mode 100644 index 0000000..dc2b7ef --- /dev/null +++ b/0007-ntsync/0025-ntdll-Use-in-process-synchronization-objects.patch @@ -0,0 +1,919 @@ +From 61d0927a98936d2fde8eed8621c2f2fc65d9c816 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 6 Apr 2021 23:37:02 +0300 +Subject: [PATCH 25/32] ntdll: Use in-process synchronization objects. + +--- + dlls/ntdll/unix/sync.c | 760 +++++++++++++++++++++++++++++++++ + dlls/ntdll/unix/unix_private.h | 2 + + dlls/ntdll/unix/virtual.c | 1 + + 3 files changed, 763 insertions(+) + +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index 22563eb9930..a433ba456e4 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -30,9 +30,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #ifdef HAVE_SYS_SYSCALL_H + #include +@@ -48,6 +50,7 @@ + #endif + #include + #include ++#include + #include + #include + #include +@@ -57,6 +60,9 @@ + #ifdef HAVE_KQUEUE + # include + #endif ++#ifdef HAVE_LINUX_NTSYNC_H ++# include ++#endif + + #include "ntstatus.h" + #define WIN32_NO_STATUS +@@ -265,6 +271,717 @@ static unsigned int validate_open_object_attributes( const OBJECT_ATTRIBUTES *at + } + + ++#ifdef HAVE_LINUX_NTSYNC_H ++ ++static int get_linux_sync_device(void) ++{ ++ static LONG device = -2; ++ ++ if (device == -2) ++ { ++ HANDLE handle; ++ int fd, needs_close; ++ NTSTATUS ret; ++ ++ SERVER_START_REQ( get_linux_sync_device ) ++ { ++ if (!(ret = wine_server_call( req ))) handle = wine_server_ptr_handle( reply->handle ); ++ } ++ SERVER_END_REQ; ++ ++ if (!ret) ++ { ++ if (!server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )) ++ { ++ if (InterlockedCompareExchange( &device, fd, -2 ) != -2) ++ { ++ /* someone beat us to it */ ++ if (needs_close) close( fd ); ++ NtClose( handle ); ++ } ++ /* otherwise don't close the device */ ++ } ++ else ++ { ++ InterlockedCompareExchange( &device, -1, -2 ); ++ NtClose( handle ); ++ } ++ } ++ else ++ { ++ InterlockedCompareExchange( &device, -1, -2 ); ++ } ++ } ++ return device; ++} ++ ++/* It's possible for synchronization primitives to remain alive even after being ++ * closed, because a thread is still waiting on them. It's rare in practice, and ++ * documented as being undefined behaviour by Microsoft, but it works, and some ++ * applications rely on it. This means we need to refcount handles, and defer ++ * deleting them on the server side until the refcount reaches zero. We do this ++ * by having each client process hold a handle to the in-process synchronization ++ * object, as well as a private refcount. When the client refcount reaches zero, ++ * it closes the handle; when all handles are closed, the server deletes the ++ * in-process synchronization object. ++ * ++ * We want lookup of objects from the cache to be very fast; ideally, it should ++ * be lock-free. We achieve this by using atomic modifications to "refcount", ++ * and guaranteeing that all other fields are valid and correct *as long as* ++ * refcount is nonzero, and we store the entire structure in memory which will ++ * never be freed. ++ * ++ * This means that acquiring the object can't use a simple atomic increment; it ++ * has to use a compare-and-swap loop to ensure that it doesn't try to increment ++ * an object with a zero refcount. That's still leagues better than a real lock, ++ * though, and release can be a single atomic decrement. ++ * ++ * It also means that threads modifying the cache need to take a lock, to ++ * prevent other threads from writing to it concurrently. ++ * ++ * It's possible for an object currently in use (by a waiter) to be closed and ++ * the same handle immediately reallocated to a different object. This should be ++ * a very rare situation, and in that case we simply don't cache the handle. ++ */ ++struct inproc_sync_cache_entry ++{ ++ LONG refcount; ++ int fd; ++ enum inproc_sync_type type; ++ unsigned int access; ++ BOOL closed; ++ /* handle to the underlying in-process sync object, stored as obj_handle_t ++ * to save space */ ++ obj_handle_t handle; ++}; ++ ++ ++static void release_inproc_sync_obj( struct inproc_sync_cache_entry *cache ) ++{ ++ /* save the handle and fd now; as soon as the refcount hits 0 we cannot ++ * access the cache anymore */ ++ HANDLE handle = wine_server_ptr_handle( cache->handle ); ++ int fd = cache->fd; ++ LONG refcount = InterlockedDecrement( &cache->refcount ); ++ ++ assert( refcount >= 0 ); ++ ++ if (!refcount) ++ { ++ NTSTATUS ret = NtClose( handle ); ++ assert( !ret ); ++ close( fd ); ++ } ++} ++ ++ ++static BOOL inproc_sync_types_match( enum inproc_sync_type a, enum inproc_sync_type b ) ++{ ++ if (a == b) return TRUE; ++ if (a == INPROC_SYNC_AUTO_EVENT && b == INPROC_SYNC_MANUAL_EVENT) return TRUE; ++ if (b == INPROC_SYNC_AUTO_EVENT && a == INPROC_SYNC_MANUAL_EVENT) return TRUE; ++ return FALSE; ++} ++ ++ ++/* returns a pointer to a cache entry; if the object could not be cached, ++ * returns "stack_cache" instead, which should be allocated on stack */ ++static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desired_type, ++ ACCESS_MASK desired_access, ++ struct inproc_sync_cache_entry *stack_cache, ++ struct inproc_sync_cache_entry **ret_cache ) ++{ ++ struct inproc_sync_cache_entry *cache = stack_cache; ++ int needs_close; ++ NTSTATUS ret; ++ ++ *ret_cache = stack_cache; ++ ++ SERVER_START_REQ( get_linux_sync_obj ) ++ { ++ req->handle = wine_server_obj_handle( handle ); ++ if (!(ret = wine_server_call( req ))) ++ { ++ cache->handle = reply->handle; ++ cache->access = reply->access; ++ cache->type = reply->type; ++ cache->refcount = 1; ++ cache->closed = FALSE; ++ } ++ } ++ SERVER_END_REQ; ++ ++ if (ret) return ret; ++ ++ if ((ret = server_get_unix_fd( wine_server_ptr_handle( cache->handle ), ++ 0, &cache->fd, &needs_close, NULL, NULL ))) ++ return ret; ++ ++ if (desired_type && !inproc_sync_types_match( cache->type, desired_type )) ++ { ++ release_inproc_sync_obj( cache ); ++ return STATUS_OBJECT_TYPE_MISMATCH; ++ } ++ ++ if ((cache->access & desired_access) != desired_access) ++ { ++ release_inproc_sync_obj( cache ); ++ return STATUS_ACCESS_DENIED; ++ } ++ ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS linux_release_semaphore_obj( int obj, ULONG count, ULONG *prev_count ) ++{ ++ NTSTATUS ret; ++ ++ ret = ioctl( obj, NTSYNC_IOC_SEM_RELEASE, &count ); ++ if (ret < 0) ++ { ++ if (errno == EOVERFLOW) ++ return STATUS_SEMAPHORE_LIMIT_EXCEEDED; ++ else ++ return errno_to_status( errno ); ++ } ++ if (prev_count) *prev_count = count; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_SEMAPHORE, ++ SEMAPHORE_MODIFY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_release_semaphore_obj( cache->fd, count, prev_count ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_query_semaphore_obj( int obj, SEMAPHORE_BASIC_INFORMATION *info ) ++{ ++ struct ntsync_sem_args args = {0}; ++ NTSTATUS ret; ++ ++ ret = ioctl( obj, NTSYNC_IOC_SEM_READ, &args ); ++ if (ret < 0) ++ return errno_to_status( errno ); ++ info->CurrentCount = args.count; ++ info->MaximumCount = args.max; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_query_semaphore( HANDLE handle, SEMAPHORE_BASIC_INFORMATION *info ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_SEMAPHORE, ++ SEMAPHORE_QUERY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_query_semaphore_obj( cache->fd, info ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_set_event_obj( int obj, LONG *prev_state ) ++{ ++ NTSTATUS ret; ++ __u32 prev; ++ ++ ret = ioctl( obj, NTSYNC_IOC_EVENT_SET, &prev ); ++ if (ret < 0) ++ return errno_to_status( errno ); ++ if (prev_state) *prev_state = prev; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_set_event( HANDLE handle, LONG *prev_state ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT, ++ EVENT_MODIFY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_set_event_obj( cache->fd, prev_state ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_reset_event_obj( int obj, LONG *prev_state ) ++{ ++ NTSTATUS ret; ++ __u32 prev; ++ ++ ret = ioctl( obj, NTSYNC_IOC_EVENT_RESET, &prev ); ++ if (ret < 0) ++ return errno_to_status( errno ); ++ if (prev_state) *prev_state = prev; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_reset_event( HANDLE handle, LONG *prev_state ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT, ++ EVENT_MODIFY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_reset_event_obj( cache->fd, prev_state ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_pulse_event_obj( int obj, LONG *prev_state ) ++{ ++ NTSTATUS ret; ++ __u32 prev; ++ ++ ret = ioctl( obj, NTSYNC_IOC_EVENT_PULSE, &prev ); ++ if (ret < 0) ++ return errno_to_status( errno ); ++ if (prev_state) *prev_state = prev; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_pulse_event( HANDLE handle, LONG *prev_state ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT, ++ EVENT_MODIFY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_pulse_event_obj( cache->fd, prev_state ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_query_event_obj( int obj, enum inproc_sync_type type, EVENT_BASIC_INFORMATION *info ) ++{ ++ struct ntsync_event_args args = {0}; ++ NTSTATUS ret; ++ ++ ret = ioctl( obj, NTSYNC_IOC_EVENT_READ, &args ); ++ if (ret < 0) ++ return errno_to_status( errno ); ++ info->EventType = (type == INPROC_SYNC_AUTO_EVENT) ? SynchronizationEvent : NotificationEvent; ++ info->EventState = args.signaled; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_query_event( HANDLE handle, EVENT_BASIC_INFORMATION *info ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT, ++ EVENT_QUERY_STATE, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_query_event_obj( cache->fd, cache->type, info ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_release_mutex_obj( int obj, LONG *prev_count ) ++{ ++ struct ntsync_mutex_args args = {0}; ++ NTSTATUS ret; ++ ++ args.owner = GetCurrentThreadId(); ++ ret = ioctl( obj, NTSYNC_IOC_MUTEX_UNLOCK, &args ); ++ ++ if (ret < 0) ++ { ++ if (errno == EOVERFLOW) ++ return STATUS_MUTANT_LIMIT_EXCEEDED; ++ else if (errno == EPERM) ++ return STATUS_MUTANT_NOT_OWNED; ++ else ++ return errno_to_status( errno ); ++ } ++ if (prev_count) *prev_count = 1 - args.count; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_release_mutex( HANDLE handle, LONG *prev_count ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_MUTEX, 0, &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_release_mutex_obj( cache->fd, prev_count ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++ ++static NTSTATUS linux_query_mutex_obj( int obj, MUTANT_BASIC_INFORMATION *info ) ++{ ++ struct ntsync_mutex_args args = {0}; ++ NTSTATUS ret; ++ ++ ret = ioctl( obj, NTSYNC_IOC_MUTEX_READ, &args ); ++ ++ if (ret < 0) ++ { ++ if (errno == EOWNERDEAD) ++ { ++ info->AbandonedState = TRUE; ++ info->OwnedByCaller = FALSE; ++ info->CurrentCount = 1; ++ return STATUS_SUCCESS; ++ } ++ else ++ return errno_to_status( errno ); ++ } ++ info->AbandonedState = FALSE; ++ info->OwnedByCaller = (args.owner == GetCurrentThreadId()); ++ info->CurrentCount = 1 - args.count; ++ return STATUS_SUCCESS; ++} ++ ++ ++static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *info ) ++{ ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ NTSTATUS ret; ++ ++ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_MUTEX, MUTANT_QUERY_STATE, ++ &stack_cache, &cache ))) ++ return ret; ++ ++ ret = linux_query_mutex_obj( cache->fd, info ); ++ ++ release_inproc_sync_obj( cache ); ++ return ret; ++} ++ ++static void select_queue(void) ++{ ++ SERVER_START_REQ( select_inproc_queue ) ++ { ++ wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++} ++ ++static void unselect_queue( BOOL signaled ) ++{ ++ SERVER_START_REQ( unselect_inproc_queue ) ++ { ++ req->signaled = signaled; ++ wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++} ++ ++static int get_inproc_alert_obj(void) ++{ ++ struct ntdll_thread_data *data = ntdll_get_thread_data(); ++ struct inproc_sync_cache_entry stack_cache, *cache; ++ HANDLE alert_handle; ++ unsigned int ret; ++ ++ if (data->linux_alert_obj == -1) ++ { ++ SERVER_START_REQ( get_inproc_alert_event ) ++ { ++ if ((ret = wine_server_call( req ))) ++ ERR( "failed to get inproc alert event, status %#x\n", ret ); ++ alert_handle = wine_server_ptr_handle( reply->handle ); ++ } ++ SERVER_END_REQ; ++ ++ if ((ret = get_inproc_sync_obj( alert_handle, 0, SYNCHRONIZE, &stack_cache, &cache ))) ++ ERR( "failed to get inproc alert obj, status %#x\n", ret ); ++ data->linux_alert_obj = cache->fd; ++ /* Set the fd to -1 so release_inproc_sync_obj() won't close it. ++ * Manhandling the cache entry here is fine since we're the only thread ++ * that can access our own alert event. */ ++ cache->fd = -1; ++ release_inproc_sync_obj( cache ); ++ NtClose( alert_handle ); ++ } ++ ++ return data->linux_alert_obj; ++} ++ ++static NTSTATUS linux_wait_objs( int device, const DWORD count, const int *objs, ++ BOOLEAN wait_any, BOOLEAN alertable, const LARGE_INTEGER *timeout ) ++{ ++ struct ntsync_wait_args args = {0}; ++ unsigned long request; ++ struct timespec now; ++ int ret; ++ ++ if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE) ++ { ++ args.timeout = ~(__u64)0; ++ } ++ else if (timeout->QuadPart <= 0) ++ { ++ clock_gettime( CLOCK_MONOTONIC, &now ); ++ args.timeout = (now.tv_sec * NSECPERSEC) + now.tv_nsec + (-timeout->QuadPart * 100); ++ } ++ else ++ { ++ args.timeout = (timeout->QuadPart * 100) - (SECS_1601_TO_1970 * NSECPERSEC); ++ args.flags |= NTSYNC_WAIT_REALTIME; ++ } ++ ++ args.objs = (uintptr_t)objs; ++ args.count = count; ++ args.owner = GetCurrentThreadId(); ++ args.index = ~0u; ++ ++ if (alertable) ++ args.alert = get_inproc_alert_obj(); ++ ++ if (wait_any || count == 1) ++ request = NTSYNC_IOC_WAIT_ANY; ++ else ++ request = NTSYNC_IOC_WAIT_ALL; ++ ++ do ++ { ++ ret = ioctl( device, request, &args ); ++ } while (ret < 0 && errno == EINTR); ++ ++ if (!ret) ++ { ++ if (args.index == count) ++ { ++ static const LARGE_INTEGER timeout; ++ ++ ret = server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, &timeout ); ++ assert( ret == STATUS_USER_APC ); ++ return ret; ++ } ++ ++ return wait_any ? args.index : 0; ++ } ++ else if (errno == EOWNERDEAD) ++ return STATUS_ABANDONED + (wait_any ? args.index : 0); ++ else if (errno == ETIMEDOUT) ++ return STATUS_TIMEOUT; ++ else ++ return errno_to_status( errno ); ++} ++ ++static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any, ++ BOOLEAN alertable, const LARGE_INTEGER *timeout ) ++{ ++ struct inproc_sync_cache_entry stack_cache[64], *cache[64]; ++ int device, objs[64]; ++ HANDLE queue = NULL; ++ NTSTATUS ret; ++ DWORD i, j; ++ ++ if ((device = get_linux_sync_device()) < 0) ++ return STATUS_NOT_IMPLEMENTED; ++ ++ for (i = 0; i < count; ++i) ++ { ++ if ((ret = get_inproc_sync_obj( handles[i], 0, SYNCHRONIZE, &stack_cache[i], &cache[i] ))) ++ { ++ for (j = 0; j < i; ++j) ++ release_inproc_sync_obj( cache[j] ); ++ return ret; ++ } ++ if (cache[i]->type == INPROC_SYNC_QUEUE) ++ queue = handles[i]; ++ ++ objs[i] = cache[i]->fd; ++ } ++ ++ if (queue) select_queue(); ++ ++ ret = linux_wait_objs( device, count, objs, wait_any, alertable, timeout ); ++ ++ if (queue) unselect_queue( handles[ret] == queue ); ++ ++ for (i = 0; i < count; ++i) ++ release_inproc_sync_obj( cache[i] ); ++ ++ return ret; ++} ++ ++static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait, ++ BOOLEAN alertable, const LARGE_INTEGER *timeout ) ++{ ++ struct inproc_sync_cache_entry signal_stack_cache, *signal_cache; ++ struct inproc_sync_cache_entry wait_stack_cache, *wait_cache; ++ HANDLE queue = NULL; ++ NTSTATUS ret; ++ int device; ++ ++ if ((device = get_linux_sync_device()) < 0) ++ return STATUS_NOT_IMPLEMENTED; ++ ++ if ((ret = get_inproc_sync_obj( signal, 0, 0, &signal_stack_cache, &signal_cache ))) ++ return ret; ++ ++ switch (signal_cache->type) ++ { ++ case INPROC_SYNC_SEMAPHORE: ++ if (!(signal_cache->access & SEMAPHORE_MODIFY_STATE)) ++ { ++ release_inproc_sync_obj( signal_cache ); ++ return STATUS_ACCESS_DENIED; ++ } ++ break; ++ ++ case INPROC_SYNC_AUTO_EVENT: ++ case INPROC_SYNC_MANUAL_EVENT: ++ if (!(signal_cache->access & EVENT_MODIFY_STATE)) ++ { ++ release_inproc_sync_obj( signal_cache ); ++ return STATUS_ACCESS_DENIED; ++ } ++ break; ++ ++ case INPROC_SYNC_MUTEX: ++ break; ++ ++ default: ++ /* can't be signaled */ ++ release_inproc_sync_obj( signal_cache ); ++ return STATUS_OBJECT_TYPE_MISMATCH; ++ } ++ ++ if ((ret = get_inproc_sync_obj( wait, 0, SYNCHRONIZE, &wait_stack_cache, &wait_cache ))) ++ { ++ release_inproc_sync_obj( signal_cache ); ++ return ret; ++ } ++ ++ if (wait_cache->type == INPROC_SYNC_QUEUE) ++ queue = wait; ++ ++ switch (signal_cache->type) ++ { ++ case INPROC_SYNC_SEMAPHORE: ++ ret = linux_release_semaphore_obj( signal_cache->fd, 1, NULL ); ++ break; ++ ++ case INPROC_SYNC_AUTO_EVENT: ++ case INPROC_SYNC_MANUAL_EVENT: ++ ret = linux_set_event_obj( signal_cache->fd, NULL ); ++ break; ++ ++ case INPROC_SYNC_MUTEX: ++ ret = linux_release_mutex_obj( signal_cache->fd, NULL ); ++ break; ++ ++ default: ++ assert( 0 ); ++ break; ++ } ++ ++ if (!ret) ++ { ++ if (queue) select_queue(); ++ ret = linux_wait_objs( device, 1, &wait_cache->fd, TRUE, alertable, timeout ); ++ if (queue) unselect_queue( !ret ); ++ } ++ ++ release_inproc_sync_obj( signal_cache ); ++ release_inproc_sync_obj( wait_cache ); ++ return ret; ++} ++ ++#else ++ ++static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_query_semaphore( HANDLE handle, SEMAPHORE_BASIC_INFORMATION *info ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_set_event( HANDLE handle, LONG *prev_state ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_reset_event( HANDLE handle, LONG *prev_state ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_pulse_event( HANDLE handle, LONG *prev_state ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_query_event( HANDLE handle, EVENT_BASIC_INFORMATION *info ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_release_mutex( HANDLE handle, LONG *prev_count ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *info ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any, ++ BOOLEAN alertable, const LARGE_INTEGER *timeout ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait, ++ BOOLEAN alertable, const LARGE_INTEGER *timeout ) ++{ ++ return STATUS_NOT_IMPLEMENTED; ++} ++ ++#endif ++ ++ + /****************************************************************************** + * NtCreateSemaphore (NTDLL.@) + */ +@@ -364,6 +1081,12 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla + if (do_esync()) + return esync_query_semaphore( handle, info, ret_len ); + ++ if ((ret = inproc_query_semaphore( handle, out )) != STATUS_NOT_IMPLEMENTED) ++ { ++ if (!ret && ret_len) *ret_len = sizeof(SEMAPHORE_BASIC_INFORMATION); ++ return ret; ++ } ++ + SERVER_START_REQ( query_semaphore ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -394,6 +1117,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, ULONG *previous + + TRACE( "handle %p, count %u, prev_count %p\n", handle, (int)count, previous ); + ++ if ((ret = inproc_release_semaphore( handle, count, previous )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + SERVER_START_REQ( release_semaphore ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -497,6 +1223,9 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state ) + + TRACE( "handle %p, prev_state %p\n", handle, prev_state ); + ++ if ((ret = inproc_set_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -526,6 +1255,9 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state ) + + TRACE( "handle %p, prev_state %p\n", handle, prev_state ); + ++ if ((ret = inproc_reset_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -563,6 +1295,9 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state ) + + TRACE( "handle %p, prev_state %p\n", handle, prev_state ); + ++ if ((ret = inproc_pulse_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + SERVER_START_REQ( event_op ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -600,6 +1335,12 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class, + if (do_esync()) + return esync_query_event( handle, info, ret_len ); + ++ if ((ret = inproc_query_event( handle, out )) != STATUS_NOT_IMPLEMENTED) ++ { ++ if (!ret && ret_len) *ret_len = sizeof(EVENT_BASIC_INFORMATION); ++ return ret; ++ } ++ + SERVER_START_REQ( query_event ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -701,6 +1442,9 @@ NTSTATUS WINAPI NtReleaseMutant( HANDLE handle, LONG *prev_count ) + + TRACE( "handle %p, prev_count %p\n", handle, prev_count ); + ++ if ((ret = inproc_release_mutex( handle, prev_count )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + SERVER_START_REQ( release_mutex ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -737,6 +1481,12 @@ NTSTATUS WINAPI NtQueryMutant( HANDLE handle, MUTANT_INFORMATION_CLASS class, + if (do_esync()) + return esync_query_mutex( handle, info, ret_len ); + ++ if ((ret = inproc_query_mutex( handle, out )) != STATUS_NOT_IMPLEMENTED) ++ { ++ if (!ret && ret_len) *ret_len = sizeof(MUTANT_BASIC_INFORMATION); ++ return ret; ++ } ++ + SERVER_START_REQ( query_mutex ) + { + req->handle = wine_server_obj_handle( handle ); +@@ -1624,6 +2374,12 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO + TRACE( "}, timeout %s\n", debugstr_timeout(timeout) ); + } + ++ if ((ret = inproc_wait( count, handles, wait_any, alertable, timeout )) != STATUS_NOT_IMPLEMENTED) ++ { ++ TRACE( "-> %#x\n", ret ); ++ return ret; ++ } ++ + if (alertable) flags |= SELECT_ALERTABLE; + select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL; + for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] ); +@@ -1660,6 +2416,7 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait, + { + union select_op select_op; + UINT flags = SELECT_INTERRUPTIBLE; ++ NTSTATUS ret; + + if (do_fsync()) + return fsync_signal_and_wait( signal, wait, alertable, timeout ); +@@ -1671,6 +2428,9 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait, + + if (!signal) return STATUS_INVALID_HANDLE; + ++ if ((ret = inproc_signal_and_wait( signal, wait, alertable, timeout )) != STATUS_NOT_IMPLEMENTED) ++ return ret; ++ + if (alertable) flags |= SELECT_ALERTABLE; + select_op.signal_and_wait.op = SELECT_SIGNAL_AND_WAIT; + select_op.signal_and_wait.wait = wine_server_obj_handle( wait ); +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index 8c335cd1efd..02988a868f2 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -103,6 +103,7 @@ struct ntdll_thread_data + PRTL_THREAD_START_ROUTINE start; /* thread entry point */ + void *param; /* thread entry point parameter */ + void *jmp_buf; /* setjmp buffer for exception handling */ ++ int linux_alert_obj; /* fd for the linux in-process alert event */ + }; + + C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) ); +@@ -392,6 +393,7 @@ extern void call_raise_user_exception_dispatcher(void); + extern const char * wine_debuginfostr_pc(void *pc); + + #define TICKSPERSEC 10000000 ++#define NSECPERSEC 1000000000 + #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400) + + static inline ULONGLONG ticks_from_time_t( time_t time ) +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index 2af754736d1..46d5a76e090 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -4130,6 +4130,7 @@ static TEB *init_teb( void *ptr, BOOL is_wow ) + thread_data->reply_fd = -1; + thread_data->wait_fd[0] = -1; + thread_data->wait_fd[1] = -1; ++ thread_data->linux_alert_obj = -1; + list_add_head( &teb_list, &thread_data->entry ); + return teb; + } +-- +2.47.1 + + diff --git a/0007-ntsync/0026-ntdll-Use-server_wait_for_object-when-waiting-on-only-the-queue-object.patch b/0007-ntsync/0026-ntdll-Use-server_wait_for_object-when-waiting-on-only-the-queue-object.patch new file mode 100644 index 0000000..50df003 --- /dev/null +++ b/0007-ntsync/0026-ntdll-Use-server_wait_for_object-when-waiting-on-only-the-queue-object.patch @@ -0,0 +1,36 @@ +From 26271cca4f6e87c4c24f1b58e81a224539a2ee7d Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Tue, 20 Apr 2021 17:55:59 -0500 +Subject: [PATCH 26/32] ntdll: Use server_wait_for_object() when waiting on + only the queue object. + +--- + dlls/ntdll/unix/sync.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index a433ba456e4..79a11c84203 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -829,6 +829,17 @@ static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_an + objs[i] = cache[i]->fd; + } + ++ /* It's common to wait on the message queue alone. Some applications wait ++ * on it in fast paths, with a zero timeout. Since we take two server calls ++ * instead of one when going through inproc_wait(), and since we only need ++ * to go through that path if we're waiting on other objects, just delegate ++ * to the server if we're only waiting on the message queue. */ ++ if (count == 1 && queue) ++ { ++ release_inproc_sync_obj( cache[0] ); ++ return server_wait_for_object( handles[0], alertable, timeout ); ++ } ++ + if (queue) select_queue(); + + ret = linux_wait_objs( device, count, objs, wait_any, alertable, timeout ); +-- +2.47.1 + + diff --git a/0007-ntsync/0027-ntdll-Cache-in-process-synchronization-objects.patch b/0007-ntsync/0027-ntdll-Cache-in-process-synchronization-objects.patch new file mode 100644 index 0000000..c717be8 --- /dev/null +++ b/0007-ntsync/0027-ntdll-Cache-in-process-synchronization-objects.patch @@ -0,0 +1,333 @@ +From 5180717ae134b61bf80fd49dffa1853d9cace0d3 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Fri, 12 Mar 2021 23:04:17 +0200 +Subject: [PATCH 27/32] ntdll: Cache in-process synchronization objects. + +--- + dlls/ntdll/unix/server.c | 9 ++ + dlls/ntdll/unix/sync.c | 195 +++++++++++++++++++++++++++++++-- + dlls/ntdll/unix/unix_private.h | 4 + + 3 files changed, 197 insertions(+), 11 deletions(-) + +diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c +index d31d31be64f..b4e7902cf1b 100644 +--- a/dlls/ntdll/unix/server.c ++++ b/dlls/ntdll/unix/server.c +@@ -1807,12 +1807,17 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE + return result.dup_handle.status; + } + ++ /* hold fd_cache_mutex to prevent the fd from being added again between the ++ * call to remove_fd_from_cache and close_handle */ + server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); + + /* always remove the cached fd; if the server request fails we'll just + * retrieve it again */ + if (options & DUPLICATE_CLOSE_SOURCE) ++ { + fd = remove_fd_from_cache( source ); ++ close_inproc_sync_obj( source ); ++ } + + SERVER_START_REQ( dup_handle ) + { +@@ -1868,6 +1873,8 @@ NTSTATUS WINAPI NtClose( HANDLE handle ) + if (HandleToLong( handle ) >= ~5 && HandleToLong( handle ) <= ~0) + return STATUS_SUCCESS; + ++ /* hold fd_cache_mutex to prevent the fd from being added again between the ++ * call to remove_fd_from_cache and close_handle */ + server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); + + /* always remove the cached fd; if the server request fails we'll just +@@ -1880,6 +1887,8 @@ NTSTATUS WINAPI NtClose( HANDLE handle ) + if (do_esync()) + esync_close( handle ); + ++ close_inproc_sync_obj( handle ); ++ + SERVER_START_REQ( close_handle ) + { + req->handle = wine_server_obj_handle( handle ); +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index 79a11c84203..bb141da7610 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -325,6 +325,12 @@ static int get_linux_sync_device(void) + * it closes the handle; when all handles are closed, the server deletes the + * in-process synchronization object. + * ++ * We also need this for signal-and-wait. The signal and wait operations aren't ++ * atomic, but we can't perform the signal and then return STATUS_INVALID_HANDLE ++ * for the wait—we need to either do both operations or neither. That means we ++ * need to grab references to both objects, and prevent them from being ++ * destroyed before we're done with them. ++ * + * We want lookup of objects from the cache to be very fast; ideally, it should + * be lock-free. We achieve this by using atomic modifications to "refcount", + * and guaranteeing that all other fields are valid and correct *as long as* +@@ -368,13 +374,140 @@ static void release_inproc_sync_obj( struct inproc_sync_cache_entry *cache ) + + if (!refcount) + { +- NTSTATUS ret = NtClose( handle ); ++ NTSTATUS ret; ++ ++ /* we can't call NtClose here as we may be inside fd_cache_mutex */ ++ SERVER_START_REQ( close_handle ) ++ { ++ req->handle = wine_server_obj_handle( handle ); ++ ret = wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++ + assert( !ret ); + close( fd ); + } + } + + ++#define INPROC_SYNC_CACHE_BLOCK_SIZE (65536 / sizeof(struct inproc_sync_cache_entry)) ++#define INPROC_SYNC_CACHE_ENTRIES 128 ++ ++static struct inproc_sync_cache_entry *inproc_sync_cache[INPROC_SYNC_CACHE_ENTRIES]; ++static struct inproc_sync_cache_entry inproc_sync_cache_initial_block[INPROC_SYNC_CACHE_BLOCK_SIZE]; ++ ++static inline unsigned int inproc_sync_handle_to_index( HANDLE handle, unsigned int *entry ) ++{ ++ unsigned int idx = (wine_server_obj_handle(handle) >> 2) - 1; ++ *entry = idx / INPROC_SYNC_CACHE_BLOCK_SIZE; ++ return idx % INPROC_SYNC_CACHE_BLOCK_SIZE; ++} ++ ++ ++static struct inproc_sync_cache_entry *cache_inproc_sync_obj( HANDLE handle, obj_handle_t inproc_sync, int fd, ++ enum inproc_sync_type type, unsigned int access ) ++{ ++ unsigned int entry, idx = inproc_sync_handle_to_index( handle, &entry ); ++ struct inproc_sync_cache_entry *cache; ++ sigset_t sigset; ++ int refcount; ++ ++ if (entry >= INPROC_SYNC_CACHE_ENTRIES) ++ { ++ FIXME( "too many allocated handles, not caching %p\n", handle ); ++ return NULL; ++ } ++ ++ if (!inproc_sync_cache[entry]) /* do we need to allocate a new block of entries? */ ++ { ++ if (!entry) inproc_sync_cache[0] = inproc_sync_cache_initial_block; ++ else ++ { ++ static const size_t size = INPROC_SYNC_CACHE_BLOCK_SIZE * sizeof(struct inproc_sync_cache_entry); ++ void *ptr = anon_mmap_alloc( size, PROT_READ | PROT_WRITE ); ++ if (ptr == MAP_FAILED) return NULL; ++ if (InterlockedCompareExchangePointer( (void **)&inproc_sync_cache[entry], ptr, NULL )) ++ munmap( ptr, size ); /* someone beat us to it */ ++ } ++ } ++ ++ cache = &inproc_sync_cache[entry][idx]; ++ ++ /* Hold fd_cache_mutex instead of a separate mutex, to prevent the same ++ * race between this function and NtClose. That is, prevent the object from ++ * being cached again between close_inproc_sync_obj() and close_handle. */ ++ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); ++ ++ if (InterlockedCompareExchange( &cache->refcount, 0, 0 )) ++ { ++ /* We lost the race with another thread trying to cache this object, or ++ * the handle is currently being used for another object (i.e. it was ++ * closed and then reused). We have no way of knowing which, and in the ++ * latter case we can't cache this object until the old one is ++ * completely destroyed, so always return failure. */ ++ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); ++ return NULL; ++ } ++ ++ cache->handle = inproc_sync; ++ cache->fd = fd; ++ cache->type = type; ++ cache->access = access; ++ cache->closed = FALSE; ++ /* Make sure we set the other members before the refcount; this store needs ++ * release semantics [paired with the load in get_cached_inproc_sync_obj()]. ++ * Set the refcount to 2 (one for the handle, one for the caller). */ ++ refcount = InterlockedExchange( &cache->refcount, 2 ); ++ assert( !refcount ); ++ ++ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); ++ ++ return cache; ++} ++ ++ ++/* returns the previous value */ ++static inline LONG interlocked_inc_if_nonzero( LONG *dest ) ++{ ++ LONG val, tmp; ++ for (val = *dest;; val = tmp) ++ { ++ if (!val || (tmp = InterlockedCompareExchange( dest, val + 1, val )) == val) ++ break; ++ } ++ return val; ++} ++ ++ ++static struct inproc_sync_cache_entry *get_cached_inproc_sync_obj( HANDLE handle ) ++{ ++ unsigned int entry, idx = inproc_sync_handle_to_index( handle, &entry ); ++ struct inproc_sync_cache_entry *cache; ++ ++ if (entry >= INPROC_SYNC_CACHE_ENTRIES || !inproc_sync_cache[entry]) ++ return NULL; ++ ++ cache = &inproc_sync_cache[entry][idx]; ++ ++ /* this load needs acquire semantics [paired with the store in ++ * cache_inproc_sync_obj()] */ ++ if (!interlocked_inc_if_nonzero( &cache->refcount )) ++ return NULL; ++ ++ if (cache->closed) ++ { ++ /* The object is still being used, but "handle" has been closed. The ++ * handle value might have been reused for another object in the ++ * meantime, in which case we have to report that valid object, so ++ * force the caller to check the server. */ ++ release_inproc_sync_obj( cache ); ++ return NULL; ++ } ++ ++ return cache; ++} ++ ++ + static BOOL inproc_sync_types_match( enum inproc_sync_type a, enum inproc_sync_type b ) + { + if (a == b) return TRUE; +@@ -391,32 +524,53 @@ static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desire + struct inproc_sync_cache_entry *stack_cache, + struct inproc_sync_cache_entry **ret_cache ) + { +- struct inproc_sync_cache_entry *cache = stack_cache; +- int needs_close; ++ struct inproc_sync_cache_entry *cache; ++ obj_handle_t inproc_sync_handle; ++ enum inproc_sync_type type; ++ unsigned int access; ++ int fd, needs_close; + NTSTATUS ret; + +- *ret_cache = stack_cache; ++ /* try to find it in the cache already */ ++ if ((cache = get_cached_inproc_sync_obj( handle ))) ++ { ++ *ret_cache = cache; ++ return STATUS_SUCCESS; ++ } + ++ /* try to retrieve it from the server */ + SERVER_START_REQ( get_linux_sync_obj ) + { + req->handle = wine_server_obj_handle( handle ); + if (!(ret = wine_server_call( req ))) + { +- cache->handle = reply->handle; +- cache->access = reply->access; +- cache->type = reply->type; +- cache->refcount = 1; +- cache->closed = FALSE; ++ inproc_sync_handle = reply->handle; ++ access = reply->access; ++ type = reply->type; + } + } + SERVER_END_REQ; + + if (ret) return ret; + +- if ((ret = server_get_unix_fd( wine_server_ptr_handle( cache->handle ), +- 0, &cache->fd, &needs_close, NULL, NULL ))) ++ if ((ret = server_get_unix_fd( wine_server_ptr_handle( inproc_sync_handle ), ++ 0, &fd, &needs_close, NULL, NULL ))) + return ret; + ++ cache = cache_inproc_sync_obj( handle, inproc_sync_handle, fd, type, access ); ++ if (!cache) ++ { ++ cache = stack_cache; ++ cache->handle = inproc_sync_handle; ++ cache->fd = fd; ++ cache->type = type; ++ cache->access = access; ++ cache->closed = FALSE; ++ cache->refcount = 1; ++ } ++ ++ *ret_cache = cache; ++ + if (desired_type && !inproc_sync_types_match( cache->type, desired_type )) + { + release_inproc_sync_obj( cache ); +@@ -433,6 +587,21 @@ static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desire + } + + ++/* caller must hold fd_cache_mutex */ ++void close_inproc_sync_obj( HANDLE handle ) ++{ ++ struct inproc_sync_cache_entry *cache = get_cached_inproc_sync_obj( handle ); ++ ++ if (cache) ++ { ++ cache->closed = TRUE; ++ /* once for the reference we just grabbed, and once for the handle */ ++ release_inproc_sync_obj( cache ); ++ release_inproc_sync_obj( cache ); ++ } ++} ++ ++ + static NTSTATUS linux_release_semaphore_obj( int obj, ULONG count, ULONG *prev_count ) + { + NTSTATUS ret; +@@ -938,6 +1107,10 @@ static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait, + + #else + ++void close_inproc_sync_obj( HANDLE handle ) ++{ ++} ++ + static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count ) + { + return STATUS_NOT_IMPLEMENTED; +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index 02988a868f2..be6ee7be3e1 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -208,6 +208,8 @@ extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const W + extern NTSTATUS load_start_exe( WCHAR **image, void **module ); + extern void start_server( BOOL debug ); + ++extern pthread_mutex_t fd_cache_mutex; ++ + extern unsigned int server_call_unlocked( void *req_ptr ); + extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset ); + extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset ); +@@ -383,6 +385,8 @@ extern NTSTATUS wow64_wine_spawnvp( void *args ); + + extern void dbg_init(void); + ++extern void close_inproc_sync_obj( HANDLE handle ); ++ + extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ); + extern NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ); +-- +2.47.1 + + diff --git a/0007-ntsync/0028-server-Allow-disabling-in-process-synchronization-support.patch b/0007-ntsync/0028-server-Allow-disabling-in-process-synchronization-support.patch new file mode 100644 index 0000000..a269929 --- /dev/null +++ b/0007-ntsync/0028-server-Allow-disabling-in-process-synchronization-support.patch @@ -0,0 +1,31 @@ +From e50ade335386be619330ff9940bd9406e97333b7 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sat, 13 Mar 2021 16:20:30 -0600 +Subject: [PATCH 28/32] server: Allow disabling in-process synchronization + support. + +--- + server/inproc_sync.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index c50bbb52bbc..e708aefe249 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -128,6 +128,12 @@ static struct linux_device *get_linux_device(void) + struct linux_device *device; + int unix_fd; + ++ if (getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) )) ++ { ++ set_error( STATUS_NOT_IMPLEMENTED ); ++ return NULL; ++ } ++ + if (linux_device_object) + return (struct linux_device *)grab_object( linux_device_object ); + +-- +2.47.1 + + diff --git a/0007-ntsync/0029-server-Add-a-message-to-signal-that-in-proces-synchronization-is-indeed-active.patch b/0007-ntsync/0029-server-Add-a-message-to-signal-that-in-proces-synchronization-is-indeed-active.patch new file mode 100644 index 0000000..9c42ca5 --- /dev/null +++ b/0007-ntsync/0029-server-Add-a-message-to-signal-that-in-proces-synchronization-is-indeed-active.patch @@ -0,0 +1,26 @@ +From c83b4a3b9609f082ffebf4302187ec27e4c01fd1 Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Sun, 14 Mar 2021 11:08:02 -0500 +Subject: [PATCH 29/32] server: Add a message to signal that in-proces + synchronization is indeed active. + +--- + server/inproc_sync.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index e708aefe249..3951aa41e5b 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -157,6 +157,7 @@ static struct linux_device *get_linux_device(void) + return NULL; + } + ++ fprintf( stderr, "wine: using fast synchronization.\n" ); + linux_device_object = device; + return device; + } +-- +2.47.1 + + diff --git a/0007-ntsync/0030-extra-debugging.patch b/0007-ntsync/0030-extra-debugging.patch new file mode 100644 index 0000000..77ca891 --- /dev/null +++ b/0007-ntsync/0030-extra-debugging.patch @@ -0,0 +1,84 @@ +From e8725c4318528c4fea2ef66dea7534c35c1ad3ea Mon Sep 17 00:00:00 2001 +From: Elizabeth Figura +Date: Fri, 3 May 2024 14:35:50 -0400 +Subject: [PATCH 30/32] extra debugging + +--- + server/inproc_sync.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/server/inproc_sync.c b/server/inproc_sync.c +index 3951aa41e5b..2e0480e540b 100644 +--- a/server/inproc_sync.c ++++ b/server/inproc_sync.c +@@ -21,6 +21,7 @@ + #include "config.h" + + #include ++#include + #include + #include + +@@ -126,21 +127,34 @@ static enum server_fd_type inproc_sync_get_fd_type( struct fd *fd ) + static struct linux_device *get_linux_device(void) + { + struct linux_device *device; ++ static int initialized; + int unix_fd; + ++ if (initialized) ++ { ++ if (linux_device_object) ++ grab_object( linux_device_object ); ++ else ++ set_error( STATUS_NOT_IMPLEMENTED ); ++ return linux_device_object; ++ } ++ + if (getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) )) + { ++ static int once; + set_error( STATUS_NOT_IMPLEMENTED ); ++ if (!once++) fprintf(stderr, "ntsync is explicitly disabled.\n"); ++ initialized = 1; + return NULL; + } + +- if (linux_device_object) +- return (struct linux_device *)grab_object( linux_device_object ); +- + unix_fd = open( "/dev/ntsync", O_CLOEXEC | O_RDONLY ); + if (unix_fd == -1) + { ++ static int once; + file_set_error(); ++ if (!once++) fprintf(stderr, "Cannot open /dev/ntsync: %s\n", strerror(errno)); ++ initialized = 1; + return NULL; + } + +@@ -148,17 +162,20 @@ static struct linux_device *get_linux_device(void) + { + close( unix_fd ); + set_error( STATUS_NO_MEMORY ); ++ initialized = 1; + return NULL; + } + + if (!(device->fd = create_anonymous_fd( &inproc_sync_fd_ops, unix_fd, &device->obj, 0 ))) + { + release_object( device ); ++ initialized = 1; + return NULL; + } + + fprintf( stderr, "wine: using fast synchronization.\n" ); + linux_device_object = device; ++ initialized = 1; + return device; + } + +-- +2.47.1 + + diff --git a/0007-ntsync/0031-ntsync-disable-esync-and-fsync-when-ntsync-is-enabled.patch b/0007-ntsync/0031-ntsync-disable-esync-and-fsync-when-ntsync-is-enabled.patch new file mode 100644 index 0000000..ec0209b --- /dev/null +++ b/0007-ntsync/0031-ntsync-disable-esync-and-fsync-when-ntsync-is-enabled.patch @@ -0,0 +1,94 @@ +From f702acd9cd3f0a4718d97900bb3311708835e589 Mon Sep 17 00:00:00 2001 +From: Stelios Tsampas +Date: Sun, 15 Dec 2024 01:59:50 +0200 +Subject: [PATCH 31/32] ntsync: disable esync and fsync when ntsync is enabled + +--- + dlls/ntdll/unix/esync.c | 3 ++- + dlls/ntdll/unix/fsync.c | 3 ++- + server/esync.c | 3 ++- + server/fsync.c | 3 ++- + server/main.c | 3 +++ + 5 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c +index 3074f7c72ea..126ef27c752 100644 +--- a/dlls/ntdll/unix/esync.c ++++ b/dlls/ntdll/unix/esync.c +@@ -57,7 +57,8 @@ int do_esync(void) + static int do_esync_cached = -1; + + if (do_esync_cached == -1) +- do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC")) && !do_fsync(); ++ do_esync_cached = !(getenv("WINEESYNC") && !atoi(getenv("WINEESYNC"))) && !do_fsync() && ++ getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) ); + + return do_esync_cached; + #else +diff --git a/dlls/ntdll/unix/fsync.c b/dlls/ntdll/unix/fsync.c +index c3da44e4f26..f719c339783 100644 +--- a/dlls/ntdll/unix/fsync.c ++++ b/dlls/ntdll/unix/fsync.c +@@ -171,7 +171,8 @@ int do_fsync(void) + if (do_fsync_cached == -1) + { + syscall( __NR_futex_waitv, NULL, 0, 0, NULL, 0 ); +- do_fsync_cached = getenv("WINEFSYNC") && atoi(getenv("WINEFSYNC")) && errno != ENOSYS; ++ do_fsync_cached = errno != ENOSYS && !(getenv("WINEFSYNC") && !atoi(getenv("WINEFSYNC"))) && ++ getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) ); + } + + return do_fsync_cached; +diff --git a/server/esync.c b/server/esync.c +index 24f3d41ad77..97deecd2514 100644 +--- a/server/esync.c ++++ b/server/esync.c +@@ -51,7 +51,8 @@ int do_esync(void) + static int do_esync_cached = -1; + + if (do_esync_cached == -1) +- do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC")) && !do_fsync(); ++ do_esync_cached = !(getenv("WINEESYNC") && !atoi(getenv("WINEESYNC"))) && !do_fsync() && ++ getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) ); + + return do_esync_cached; + #else +diff --git a/server/fsync.c b/server/fsync.c +index d41fee58c0b..e1abfaae800 100644 +--- a/server/fsync.c ++++ b/server/fsync.c +@@ -59,7 +59,8 @@ int do_fsync(void) + if (do_fsync_cached == -1) + { + syscall( __NR_futex_waitv, 0, 0, 0, 0, 0); +- do_fsync_cached = getenv("WINEFSYNC") && atoi(getenv("WINEFSYNC")) && errno != ENOSYS; ++ do_fsync_cached = errno != ENOSYS && !(getenv("WINEFSYNC") && !atoi(getenv("WINEFSYNC"))) && ++ getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) ); + } + + return do_fsync_cached; +diff --git a/server/main.c b/server/main.c +index d0a0a4879b5..d0ac24b0a1f 100644 +--- a/server/main.c ++++ b/server/main.c +@@ -231,6 +231,8 @@ int main( int argc, char *argv[] ) + + sock_init(); + open_master_socket(); ++ if (getenv( "WINE_DISABLE_FAST_SYNC" ) && atoi( getenv( "WINE_DISABLE_FAST_SYNC" ) )) ++ { + + if (do_fsync()) + fsync_init(); +@@ -240,6 +242,7 @@ int main( int argc, char *argv[] ) + + if (!do_fsync() && !do_esync()) + fprintf( stderr, "wineserver: using server-side synchronization.\n" ); ++ } + + if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() ); + set_current_time(); +-- +2.47.1 + + diff --git a/0007-ntsync/0032-ntdll-Wait-for-thread-suspension-in-NtSuspendThread.patch b/0007-ntsync/0032-ntdll-Wait-for-thread-suspension-in-NtSuspendThread.patch new file mode 100644 index 0000000..e8b5599 --- /dev/null +++ b/0007-ntsync/0032-ntdll-Wait-for-thread-suspension-in-NtSuspendThread.patch @@ -0,0 +1,118 @@ +From bfebb2efea2c6059bb9c6323cd01615c6d7246b5 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Wed, 13 Mar 2024 18:44:31 -0600 +Subject: [PATCH] ntdll: Wait for thread suspension in NtSuspendThread(). + +--- + dlls/ntdll/unix/thread.c | 25 +++++++++++++++++++++---- + server/protocol.def | 6 ++++-- + server/thread.c | 28 ++++++++++++++++++++++++---- + 3 files changed, 49 insertions(+), 10 deletions(-) + +diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c +index 60c833b0320..19ce0fb28a3 100644 +--- a/dlls/ntdll/unix/thread.c ++++ b/dlls/ntdll/unix/thread.c +@@ -1611,19 +1611,36 @@ NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access, + /****************************************************************************** + * NtSuspendThread (NTDLL.@) + */ +-NTSTATUS WINAPI NtSuspendThread( HANDLE handle, ULONG *count ) ++NTSTATUS WINAPI NtSuspendThread( HANDLE handle, ULONG *ret_count ) + { +- unsigned int ret; ++ unsigned int ret, count = 0; ++ HANDLE wait_handle = NULL; + + SERVER_START_REQ( suspend_thread ) + { + req->handle = wine_server_obj_handle( handle ); +- if (!(ret = wine_server_call( req ))) ++ if (!(ret = wine_server_call( req )) || ret == STATUS_PENDING) + { +- if (count) *count = reply->count; ++ count = reply->count; ++ wait_handle = wine_server_ptr_handle( reply->wait_handle ); + } + } + SERVER_END_REQ; ++ ++ if (ret == STATUS_PENDING && wait_handle) ++ { ++ NtWaitForSingleObject( wait_handle, FALSE, NULL ); ++ ++ SERVER_START_REQ( suspend_thread ) ++ { ++ req->handle = wine_server_obj_handle( handle ); ++ req->waited_handle = wine_server_obj_handle( wait_handle ); ++ ret = wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++ } ++ ++ if (!ret && ret_count) *ret_count = count; + return ret; + } + +diff --git a/server/protocol.def b/server/protocol.def +index 13aea96e796..b26dbc79962 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -1107,9 +1107,11 @@ typedef struct + + /* Suspend a thread */ + @REQ(suspend_thread) +- obj_handle_t handle; /* thread handle */ ++ obj_handle_t handle; /* thread handle */ ++ obj_handle_t waited_handle; /* handle waited on */ + @REPLY +- int count; /* new suspend count */ ++ int count; /* new suspend count */ ++ obj_handle_t wait_handle; /* handle to wait on */ + @END + + +diff --git a/server/thread.c b/server/thread.c +index 56f57cefd8f..c41fd0a02dc 100644 +--- a/server/thread.c ++++ b/server/thread.c +@@ -1550,12 +1550,32 @@ DECL_HANDLER(suspend_thread) + { + struct thread *thread; + +- if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) ++ if (req->waited_handle) + { +- if (thread->state == TERMINATED) set_error( STATUS_ACCESS_DENIED ); +- else reply->count = suspend_thread( thread ); +- release_object( thread ); ++ struct context *context; ++ ++ if (!(context = (struct context *)get_handle_obj( current->process, req->waited_handle, ++ 0, &context_ops ))) ++ return; ++ close_handle( current->process, req->waited_handle ); /* avoid extra server call */ ++ set_error( context->status ); ++ release_object( context ); ++ return; + } ++ ++ if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return; ++ ++ if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED ); ++ else ++ { ++ reply->count = suspend_thread( thread ); ++ if (!get_error() && thread != current && thread->context && thread->context->status == STATUS_PENDING) ++ { ++ set_error( STATUS_PENDING ); ++ reply->wait_handle = alloc_handle( current->process, thread->context, SYNCHRONIZE, 0 ); ++ } ++ } ++ release_object( thread ); + } + + /* resume a thread */ +-- +GitLab + diff --git a/0007-ntsync/0033-ntdll-Use-server_wait_for_object-when-waiting-in-NtSuspendThread.patch b/0007-ntsync/0033-ntdll-Use-server_wait_for_object-when-waiting-in-NtSuspendThread.patch new file mode 100644 index 0000000..73484a6 --- /dev/null +++ b/0007-ntsync/0033-ntdll-Use-server_wait_for_object-when-waiting-in-NtSuspendThread.patch @@ -0,0 +1,26 @@ +From dc76375244b13b65297f46e5a0d315fe0e9df642 Mon Sep 17 00:00:00 2001 +From: Stelios Tsampas +Date: Sun, 22 Dec 2024 14:03:35 +0200 +Subject: [PATCH 32/32] ntdll: Use server_wait_for_object() when waiting in + NtSuspendThread + +--- + dlls/ntdll/unix/thread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c +index 8314d8800b0..e6ffb586015 100644 +--- a/dlls/ntdll/unix/thread.c ++++ b/dlls/ntdll/unix/thread.c +@@ -1644,7 +1644,7 @@ NTSTATUS WINAPI NtSuspendThread( HANDLE handle, ULONG *ret_count ) + + if (ret == STATUS_PENDING && wait_handle) + { +- NtWaitForSingleObject( wait_handle, FALSE, NULL ); ++ server_wait_for_object( wait_handle, FALSE, NULL ); + + SERVER_START_REQ( suspend_thread ) + { +-- +2.47.1 + diff --git a/0007-ntsync/0034-fixup-HACK-win32u-Always-call-get_message-request-af.patch b/0007-ntsync/0034-fixup-HACK-win32u-Always-call-get_message-request-af.patch new file mode 100644 index 0000000..344913b --- /dev/null +++ b/0007-ntsync/0034-fixup-HACK-win32u-Always-call-get_message-request-af.patch @@ -0,0 +1,51 @@ +From a3e8123c6f310525d453704b50b9fc2c993dd4a4 Mon Sep 17 00:00:00 2001 +From: Nobody +Date: Wed, 25 Dec 2024 00:46:37 -0800 +Subject: [PATCH] fixup! HACK: win32u: Always call get_message request after + waiting. + +--- + dlls/win32u/message.c | 2 +- + dlls/win32u/win32u_private.h | 13 +++++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c +index c379c87d916..7ae0a0cafe7 100644 +--- a/dlls/win32u/message.c ++++ b/dlls/win32u/message.c +@@ -2776,7 +2776,7 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter, BOOL waite + thread_info->client_info.msg_source = prev_source; + wake_mask = filter->mask & (QS_SENDMESSAGE | QS_SMRESULT); + +- if ((!waited && (NtGetTickCount() - thread_info->last_getmsg_time < 3000)) && /* avoid hung queue */ ++ if (((using_server_or_ntsync() || !waited) && (NtGetTickCount() - thread_info->last_getmsg_time < 3000)) && /* avoid hung queue */ + check_queue_bits( wake_mask, filter->mask, wake_mask | signal_bits, filter->mask | clear_bits, + &wake_bits, &changed_bits )) + res = STATUS_PENDING; +diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h +index 9689d78a929..84a98b0ecd9 100644 +--- a/dlls/win32u/win32u_private.h ++++ b/dlls/win32u/win32u_private.h +@@ -325,6 +325,19 @@ extern const struct user_driver_funcs *user_driver; + + extern ULONG_PTR zero_bits; + ++static inline BOOL using_server_or_ntsync(void) ++{ ++ static int server_or_nt_cached = -1; ++ if (server_or_nt_cached == -1) ++ { ++ BOOL do_ntsync = !(getenv("WINE_DISABLE_FAST_SYNC") && atoi(getenv("WINE_DISABLE_FAST_SYNC"))); ++ BOOL do_fsync = !(getenv("WINEFSYNC") && !atoi(getenv("WINEFSYNC")) && !do_ntsync); ++ BOOL do_esync = !(getenv("WINEESYNC") && !atoi(getenv("WINEESYNC")) && !do_fsync && !do_ntsync); ++ server_or_nt_cached = do_ntsync || !(do_fsync || do_esync); ++ } ++ return !!server_or_nt_cached; ++} ++ + static inline BOOL set_ntstatus( NTSTATUS status ) + { + if (status) RtlSetLastWin32Error( RtlNtStatusToDosError( status )); +-- +2.47.1 + diff --git a/0007-proton-esync-fsync/0260-fsync-remove-clock_gettime-syscall-from-get_wait_end.patch b/0007-proton-esync-fsync/0260-fsync-remove-clock_gettime-syscall-from-get_wait_end.patch deleted file mode 100644 index 18f28c8..0000000 --- a/0007-proton-esync-fsync/0260-fsync-remove-clock_gettime-syscall-from-get_wait_end.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 381dcb2145cf9d7ab7d7993eedd2bebdff8ca964 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Sun, 3 Nov 2024 21:01:53 -0800 -Subject: [PATCH 3/3] fsync: remove clock_gettime syscall from - get_wait_end_time - ---- - dlls/ntdll/unix/fsync.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/dlls/ntdll/unix/fsync.c b/dlls/ntdll/unix/fsync.c -index 90ed801f11e..87bc12662ad 100644 ---- a/dlls/ntdll/unix/fsync.c -+++ b/dlls/ntdll/unix/fsync.c -@@ -54,6 +54,8 @@ - #include "unix_private.h" - #include "fsync.h" - -+#include -+ - WINE_DEFAULT_DEBUG_CHANNEL(fsync); - - #include "pshpack4.h" -@@ -87,7 +89,7 @@ static LONGLONG nt_time_from_ts( struct timespec *ts ) - return ticks_from_time_t( ts->tv_sec ) + (ts->tv_nsec + 50) / 100; - } - --static void get_wait_end_time( const LARGE_INTEGER **timeout, struct timespec64 *end, clockid_t *clock_id ) -+static inline void get_wait_end_time( const LARGE_INTEGER **timeout, struct timespec64 *end, clockid_t *clock_id ) - { - ULONGLONG nt_end; - -@@ -100,20 +102,26 @@ static void get_wait_end_time( const LARGE_INTEGER **timeout, struct timespec64 - - if ((*timeout)->QuadPart > 0) - { -- nt_end = (*timeout)->QuadPart; -+ nt_end = (*timeout)->QuadPart - (SECS_1601_TO_1970 * TICKSPERSEC); - *clock_id = CLOCK_REALTIME; - } - else - { -- struct timespec ts; -+ /* remove syscall, rely on fast USD updates (patch) -+ * copied from kernelbase/sync.c QueryInterruptTime */ -+ ULONG high, low; - -- clock_gettime( CLOCK_MONOTONIC, &ts ); -- nt_end = nt_time_from_ts( &ts ) - (*timeout)->QuadPart; -+ do -+ { -+ high = user_shared_data->InterruptTime.High1Time; -+ low = user_shared_data->InterruptTime.LowPart; -+ } -+ while (high != user_shared_data->InterruptTime.High2Time); -+ -+ nt_end = ((ULONGLONG)high << 32 | low) - (*timeout)->QuadPart; - *clock_id = CLOCK_MONOTONIC; - } -- -- nt_end -= SECS_1601_TO_1970 * TICKSPERSEC; -- end->tv_sec = nt_end / (ULONGLONG)TICKSPERSEC; -+ end->tv_sec = nt_end / (ULONGLONG)TICKSPERSEC; - end->tv_nsec = (nt_end % TICKSPERSEC) * 100; - } - --- -2.47.0 - diff --git a/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch b/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch deleted file mode 100644 index 81e726d..0000000 --- a/0013-server-optimization/0001-misc/ps0057-ntdll-Implement-dynamic-spinning.patch +++ /dev/null @@ -1,121 +0,0 @@ -From: William Horvath -Date: Sat, 7 Dec 2024 16:59:04 -0800 -Subject: [PATCH v2] ntdll: Implement dynamic spinning. - -Original by Jangwoon Kim: https://list.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.org/thread/K7KUZUHQQ43AA2M7SZOQWY3W5G45QCCY/#K7KUZUHQQ43AA2M7SZOQWY3W5G45QCCY - -Previously, InitializeCriticalSectionEx with -RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN worked as semi-stub. - -This patch implements dynamic spinning. -Specifically, 32th bit from the right (starting with zero index) -indicates whether it is dynamically spinning critical section. - -v2: Enable dynamic spinning by default on Windows >= 8, which seems to be what Windows does - (https://stackoverflow.com/questions/54765280/windows-critical-section-how-to-disable-spinning-completely) - - Default spincount to 8 if unspecified, it will dynamically adjust pretty quickly - - 4096 seems to be used by Windows (https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsectionandspincount), - so that should be a safe maximum - -Co-authored-by: Jangwoong Kim <6812skiii@gmail.com> ---- - dlls/ntdll/sync.c | 54 ++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 46 insertions(+), 8 deletions(-) - -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -42,6 +42,13 @@ - WINE_DEFAULT_DEBUG_CHANNEL(sync); - WINE_DECLARE_DEBUG_CHANNEL(relay); - -+#define IS_DYNAMIC_SPIN crit->SpinCount >> 31 == 1 ? TRUE : FALSE -+#define MAX_ADAPTIVE_SPIN_COUNT 4096 -+#define DEFAULT_ADAPTIVE_SPIN_COUNT 8 -+#ifndef min -+#define min(a,b) (((a) < (b)) ? (a) : (b)) -+#endif -+ - static const char *debugstr_timeout( const LARGE_INTEGER *timeout ) - { - if (!timeout) return "(infinite)"; -@@ -220,7 +227,11 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION * - */ - NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULONG spincount, ULONG flags ) - { -- if (flags & (RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN|RTL_CRITICAL_SECTION_FLAG_STATIC_INIT)) -+ if (NtCurrentTeb()->Peb->OSMajorVersion > 6 || -+ (NtCurrentTeb()->Peb->OSMajorVersion == 6 && NtCurrentTeb()->Peb->OSMinorVersion >= 2)) -+ flags |= RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN; -+ -+ if (flags & RTL_CRITICAL_SECTION_FLAG_STATIC_INIT) - FIXME("(%p,%lu,0x%08lx) semi-stub\n", crit, spincount, flags); - - /* FIXME: if RTL_CRITICAL_SECTION_FLAG_STATIC_INIT is given, we should use -@@ -250,8 +261,15 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULON - crit->RecursionCount = 0; - crit->OwningThread = 0; - crit->LockSemaphore = 0; -+ spincount = spincount & ~0x80000000; - if (NtCurrentTeb()->Peb->NumberOfProcessors <= 1) spincount = 0; -- crit->SpinCount = spincount & ~0x80000000; -+ else if (flags & RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN) -+ { -+ spincount = min(spincount == 0 ? DEFAULT_ADAPTIVE_SPIN_COUNT : spincount, MAX_ADAPTIVE_SPIN_COUNT); -+ /* 31th bit (from right starting with 0) indicates whether it is dynamically spinning CS */ -+ spincount |= ((ULONG)1 << 31); -+ } -+ crit->SpinCount = spincount; - return STATUS_SUCCESS; - } - -@@ -353,19 +371,39 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) - */ - NTSTATUS WINAPI RtlEnterCriticalSection( RTL_CRITICAL_SECTION *crit ) - { -- if (crit->SpinCount) -+ if (crit->SpinCount & ~0x80000000) - { - ULONG count; - - if (RtlTryEnterCriticalSection( crit )) return STATUS_SUCCESS; -- for (count = crit->SpinCount; count > 0; count--) -+ if (IS_DYNAMIC_SPIN) - { -- if (crit->LockCount > 0) break; /* more than one waiter, don't bother spinning */ -- if (crit->LockCount == -1) /* try again */ -+ ULONG max_count = min(MAX_ADAPTIVE_SPIN_COUNT, (crit->SpinCount & ~0x80000000) * 2); -+ for (count = 0; count <= max_count; count++) - { -- if (InterlockedCompareExchange( &crit->LockCount, 0, -1 ) == -1) goto done; -+ if (crit->LockCount == -1) -+ { -+ if (InterlockedCompareExchange( &crit->LockCount, 0, -1 ) == -1) -+ { -+ crit->SpinCount += ((LONG)count - (LONG)(crit->SpinCount & ~0x80000000)) / 10; -+ goto done; -+ } -+ } -+ YieldProcessor(); -+ } -+ crit->SpinCount += ((LONG)count - (LONG)(crit->SpinCount & ~0x80000000)) / 10; -+ } -+ else -+ { -+ for (count = (crit->SpinCount & ~0x80000000); count > 0; count--) -+ { -+ if (crit->LockCount > 0) break; /* more than one waiter, don't bother spinning */ -+ if (crit->LockCount == -1) /* try again */ -+ { -+ if (InterlockedCompareExchange( &crit->LockCount, 0, -1 ) == -1) goto done; -+ } -+ YieldProcessor(); - } -- YieldProcessor(); - } - } - --- -0.0.0 - diff --git a/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch b/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch index 59cca18..245dc3f 100644 --- a/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch +++ b/0013-server-optimization/0001-misc/ps0248-ntdll-server-Write-system-handle-info-directly-to-.patch @@ -263,7 +263,7 @@ index 11111111111..11111111111 100644 struct handle_table *table = process->handles; struct handle_entry *entry; - struct handle_info *handle; - unsigned int i; + int i; if (!table) @@ -855,20 +979,21 @@ static int enum_handles( struct process *process, void *user ) diff --git a/0013-server-optimization/0001-misc/ps0741-ntdll-Make-server_select-a-memory-barrier.patch b/0013-server-optimization/0001-misc/ps0741-ntdll-Make-server_select-a-memory-barrier.patch new file mode 100644 index 0000000..d6bdc03 --- /dev/null +++ b/0013-server-optimization/0001-misc/ps0741-ntdll-Make-server_select-a-memory-barrier.patch @@ -0,0 +1,26 @@ +From c0a9e5a830d878468c8a6450588c732d4d6b6b90 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Fri, 2 Sep 2022 22:06:44 +0200 +Subject: [PATCH] ntdll: Make server_select a memory barrier. + +--- + dlls/ntdll/unix/server.c | 3 +++ + 1 files changed, 3 insertions(+) + +diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c +index 51a83f472e1..362c7793cbc 100644 +--- a/dlls/ntdll/unix/server.c ++++ b/dlls/ntdll/unix/server.c +@@ -602,6 +602,9 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT + sigset_t old_set; + int signaled; + data_size_t reply_size; ++ /* ensure writes so far are visible to other threads */ ++ MemoryBarrier(); ++ + struct + { + union apc_call call; +-- +GitLab + diff --git a/0013-server-optimization/0001-misc/ps3504-p0002-ntdll-An-implementation-of-SRWLOCK-that-closer-.patch b/0013-server-optimization/0001-misc/ps3504-p0002-ntdll-An-implementation-of-SRWLOCK-that-closer-.patch index 58f6b63..39d9b4a 100644 --- a/0013-server-optimization/0001-misc/ps3504-p0002-ntdll-An-implementation-of-SRWLOCK-that-closer-.patch +++ b/0013-server-optimization/0001-misc/ps3504-p0002-ntdll-An-implementation-of-SRWLOCK-that-closer-.patch @@ -474,7 +474,7 @@ index fa64917029a..281d7943d03 100644 + * Returns TRUE if the lock is acquired, FALSE otherwise. */ -void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) -+#ifdef __GNUC__ ++#if defined (__GNUC__) || defined(__clang__) +__attribute__((force_align_arg_pointer)) +#endif +static BOOLEAN srwlock_wait(RTL_SRWLOCK *lock, DWORD waiter_state, diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0001-server-ntdll-Create-shared-memory-for-every.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0001-server-ntdll-Create-shared-memory-for-every.patch deleted file mode 100644 index 7871d36..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0001-server-ntdll-Create-shared-memory-for-every.patch +++ /dev/null @@ -1,388 +0,0 @@ -From 0ad5a65f071a1e759b852eb82da66ec1e18cc72b Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Sun, 31 Jul 2022 15:09:23 +0200 -Subject: [PATCH 1/8] server,ntdll: Create shared memory for every thread. - ---- - dlls/ntdll/unix/server.c | 65 +++++++++++++++++++++++++++++++++- - dlls/ntdll/unix/unix_private.h | 17 +++++++++ - dlls/ntdll/unix/virtual.c | 4 +++ - server/file.h | 4 +++ - server/mapping.c | 16 +++++++++ - server/protocol.def | 4 +++ - server/thread.c | 27 ++++++++++++++ - server/thread.h | 17 +++++++++ - 8 files changed, 153 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/server.c -+++ b/dlls/ntdll/unix/server.c -@@ -1662,6 +1662,13 @@ size_t server_init_process(void) - struct sigaction sig_act; - size_t info_size; - DWORD pid, tid; -+ sigset_t sigset; -+#ifdef __linux__ -+ int has_request_shm = 0; -+ obj_handle_t fd_handle; -+ int request_shm_fd = -1; -+ void *request_shm = MAP_FAILED; -+#endif - - server_pid = -1; - if (env_socket) -@@ -1724,6 +1731,7 @@ size_t server_init_process(void) - - reply_pipe = init_thread_pipe(); - -+ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); - SERVER_START_REQ( init_first_thread ) - { - req->unix_pid = getpid(); -@@ -1738,9 +1746,18 @@ size_t server_init_process(void) - peb->SessionId = reply->session_id; - info_size = reply->info_size; - server_start_time = reply->server_start; -+#ifdef __linux__ -+ has_request_shm = reply->has_request_shm; -+ if (has_request_shm) -+ { -+ request_shm_fd = receive_fd( &fd_handle ); -+ assert( fd_handle == tid ); -+ } -+#endif - supported_machines_count = wine_server_reply_size( reply ) / sizeof(*supported_machines); - } - SERVER_END_REQ; -+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); - close( reply_pipe ); - - if (ret) server_protocol_error( "init_first_thread failed with status %x\n", ret ); -@@ -1771,9 +1788,25 @@ size_t server_init_process(void) - set_thread_id( NtCurrentTeb(), pid, tid ); - - for (i = 0; i < supported_machines_count; i++) -- if (supported_machines[i] == current_machine) return info_size; -+ if (supported_machines[i] == current_machine) -+ goto map_request_shm; - - fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine ); -+ -+map_request_shm: -+#ifdef __linux__ -+ if (!has_request_shm) return info_size; -+ -+ request_shm = mmap( NULL, REQUEST_SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, request_shm_fd, 0 ); -+ if (request_shm != MAP_FAILED) -+ { -+ ntdll_get_thread_data()->request_shm_fd = request_shm_fd; -+ ntdll_get_thread_data()->request_shm = request_shm; -+ } -+ else -+ close( request_shm_fd ); -+#endif -+ return info_size; - } - - -@@ -1834,10 +1867,18 @@ void server_init_thread( void *entry_point, BOOL *suspend ) - { - void *teb; - int reply_pipe = init_thread_pipe(); -+ sigset_t sigset; -+#ifdef __linux__ -+ int has_request_shm = 0; -+ obj_handle_t fd_handle; -+ int request_shm_fd = -1; -+ void *request_shm; -+#endif - - /* always send the native TEB */ - if (!(teb = NtCurrentTeb64())) teb = NtCurrentTeb(); - -+ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); - SERVER_START_REQ( init_thread ) - { - req->unix_tid = get_unix_tid(); -@@ -1847,9 +1888,31 @@ void server_init_thread( void *entry_point, BOOL *suspend ) - req->wait_fd = ntdll_get_thread_data()->wait_fd[1]; - wine_server_call( req ); - *suspend = reply->suspend; -+#ifdef __linux__ -+ has_request_shm = reply->has_request_shm; -+ if (has_request_shm) -+ { -+ request_shm_fd = receive_fd( &fd_handle ); -+ assert( fd_handle == GetCurrentThreadId() ); -+ } -+#endif - } - SERVER_END_REQ; -+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); - close( reply_pipe ); -+ -+#ifdef __linux__ -+ if (!has_request_shm) return; -+ -+ request_shm = mmap( NULL, REQUEST_SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, request_shm_fd, 0 ); -+ if (request_shm != MAP_FAILED) -+ { -+ ntdll_get_thread_data()->request_shm_fd = request_shm_fd; -+ ntdll_get_thread_data()->request_shm = request_shm; -+ } -+ else -+ close( request_shm_fd ); -+#endif - } - - -diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/unix_private.h -+++ b/dlls/ntdll/unix/unix_private.h -@@ -81,6 +81,19 @@ static inline BOOL is_old_wow64(void) - return !is_win64 && wow_peb; - } - -+#ifdef __linux__ -+struct request_shm -+{ -+ int futex; /* signaling futex */ -+ int pad; -+ union -+ { -+ union generic_request req; /* request structure */ -+ union generic_reply reply; /* reply structure */ -+ } u; -+}; -+#endif -+ - /* thread private data, stored in NtCurrentTeb()->GdiTebBatch */ - struct ntdll_thread_data - { -@@ -91,6 +104,10 @@ struct ntdll_thread_data - int request_fd; /* fd for sending server requests */ - int reply_fd; /* fd for receiving server replies */ - int wait_fd[2]; /* fd for sleeping server requests */ -+#ifdef __linux__ -+ int request_shm_fd; /* request shared memory fd */ -+ volatile struct request_shm *request_shm; /* shared memory for sending and receiving server requests/replies */ -+#endif - BOOL allow_writes; /* ThreadAllowWrites flags */ - pthread_t pthread_id; /* pthread thread id */ - struct list entry; /* entry in TEB list */ -diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/virtual.c -+++ b/dlls/ntdll/unix/virtual.c -@@ -3704,6 +3704,10 @@ static TEB *init_teb( void *ptr, BOOL is_wow ) - thread_data->reply_fd = -1; - thread_data->wait_fd[0] = -1; - thread_data->wait_fd[1] = -1; -+#ifdef __linux__ -+ thread_data->request_shm_fd = -1; -+ thread_data->request_shm = NULL; -+#endif - list_add_head( &teb_list, &thread_data->entry ); - return teb; - } -diff --git a/server/file.h b/server/file.h -index 11111111111..11111111111 100644 ---- a/server/file.h -+++ b/server/file.h -@@ -30,6 +30,7 @@ struct mapping; - struct async_queue; - struct completion; - struct reserve; -+struct request_shm; - - /* server-side representation of I/O status block */ - struct iosb -@@ -214,6 +215,10 @@ assert( __seq == __obj->seq ); \ - __WINE_ATOMIC_STORE_RELEASE( &__obj->seq, &__end ); \ - } while(0) - -+#ifdef __linux__ -+extern int create_request_shm( int *fd, struct request_shm **ptr ); -+#endif -+ - /* device functions */ - - extern struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name, -diff --git a/server/mapping.c b/server/mapping.c -index 11111111111..11111111111 100644 ---- a/server/mapping.c -+++ b/server/mapping.c -@@ -1309,6 +1309,22 @@ struct object *create_shared_mapping( struct object *root, const struct unicode_ - return &mapping->obj; - } - -+#ifdef __linux__ -+int create_request_shm( int *fd, struct request_shm **ptr ) -+{ -+ if ((*fd = create_temp_file( REQUEST_SHM_SIZE )) == -1) return 0; -+ -+ *ptr = mmap( NULL, REQUEST_SHM_SIZE, PROT_WRITE, MAP_SHARED, *fd, 0 ); -+ if (*ptr == MAP_FAILED) -+ { -+ *ptr = NULL; -+ set_error( STATUS_NO_MEMORY ); -+ return 0; -+ } -+ return 1; -+} -+#endif -+ - /* create a file mapping */ - DECL_HANDLER(create_mapping) - { -diff --git a/server/protocol.def b/server/protocol.def -index 11111111111..11111111111 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -46,6 +46,8 @@ typedef unsigned __int64 client_ptr_t; - typedef unsigned __int64 affinity_t; - typedef client_ptr_t mod_handle_t; - -+#define REQUEST_SHM_SIZE (1 * 1024 * 1024) -+ - struct request_header - { - int req; /* request code */ -@@ -1056,6 +1058,7 @@ struct directory_entry - timeout_t server_start; /* server start time */ - unsigned int session_id; /* process session id */ - data_size_t info_size; /* total size of startup info */ -+ int has_request_shm; /* is request shared memory supported? */ - VARARG(machines,ushorts); /* array of supported machines */ - @END - -@@ -1069,6 +1072,7 @@ struct directory_entry - client_ptr_t entry; /* entry point (in thread address space) */ - @REPLY - int suspend; /* is thread suspended? */ -+ int has_request_shm; /* is request shared memory supported? */ - @END - - -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -374,6 +375,10 @@ static inline void init_thread_structure( struct thread *thread ) - thread->request_fd = NULL; - thread->reply_fd = NULL; - thread->wait_fd = NULL; -+#ifdef __linux__ -+ thread->request_shm_fd = -1; -+ thread->request_shm = NULL; -+#endif - thread->state = RUNNING; - thread->exit_code = 0; - thread->priority = 0; -@@ -585,6 +590,14 @@ struct thread *create_thread( int fd, struct process *process, const struct secu - } - } - -+#ifdef __linux__ -+ if (!create_request_shm( &thread->request_shm_fd, (struct request_shm**)&thread->request_shm )) -+ { -+ release_object( thread ); -+ return NULL; -+ } -+#endif -+ - if (do_esync()) - { - thread->esync_fd = esync_create_fd( 0, 0 ); -@@ -652,6 +665,10 @@ static void cleanup_thread( struct thread *thread ) - if (thread->request_fd) release_object( thread->request_fd ); - if (thread->reply_fd) release_object( thread->reply_fd ); - if (thread->wait_fd) release_object( thread->wait_fd ); -+#ifdef __linux__ -+ if (thread->request_shm_fd != -1) close( thread->request_shm_fd ); -+ if (thread->request_shm) munmap( (void*)thread->request_shm, REQUEST_SHM_SIZE ); -+#endif - cleanup_clipboard_thread(thread); - destroy_thread_windows( thread ); - free_msg_queue( thread ); -@@ -675,6 +692,10 @@ static void cleanup_thread( struct thread *thread ) - thread->request_fd = NULL; - thread->reply_fd = NULL; - thread->wait_fd = NULL; -+#ifdef __linux__ -+ thread->request_shm_fd = -1; -+ thread->request_shm = NULL; -+#endif - thread->desktop = 0; - thread->desc = NULL; - thread->desc_len = 0; -@@ -1997,8 +2018,11 @@ DECL_HANDLER(init_first_thread) - reply->session_id = process->session_id; - reply->info_size = get_process_startup_info_size( process ); - reply->server_start = server_start_time; -+ reply->has_request_shm = current->request_shm_fd != -1; - set_reply_data( supported_machines, - min( supported_machines_count * sizeof(unsigned short), get_reply_max_size() )); -+ if (reply->has_request_shm) -+ send_client_fd( current->process, current->request_shm_fd, reply->tid ); - } - - /* initialize a new thread */ -@@ -2025,6 +2049,9 @@ DECL_HANDLER(init_thread) - set_thread_affinity( current, current->affinity ); - - reply->suspend = (current->suspend || current->process->suspend || current->context != NULL); -+ reply->has_request_shm = current->request_shm_fd != -1; -+ if (reply->has_request_shm) -+ send_client_fd( current->process, current->request_shm_fd, get_thread_id( current ) ); - } - - /* terminate a thread */ -diff --git a/server/thread.h b/server/thread.h -index 11111111111..11111111111 100644 ---- a/server/thread.h -+++ b/server/thread.h -@@ -46,6 +46,19 @@ struct inflight_fd - }; - #define MAX_INFLIGHT_FDS 16 /* max number of fds in flight per thread */ - -+#ifdef __linux__ -+struct request_shm -+{ -+ int futex; /* signaling futex */ -+ int pad; -+ union -+ { -+ union generic_request req; /* request structure */ -+ union generic_reply reply; /* reply structure */ -+ } u; -+}; -+#endif -+ - struct thread - { - struct object obj; /* object header */ -@@ -77,6 +90,10 @@ struct thread - struct fd *request_fd; /* fd for receiving client requests */ - struct fd *reply_fd; /* fd to send a reply to a client */ - struct fd *wait_fd; /* fd to use to wake a sleeping client */ -+#ifdef __linux__ -+ int request_shm_fd; /* request shared memory fd */ -+ volatile struct request_shm *request_shm; /* shared memory for receiving and sending client requests/replies */ -+#endif - enum run_state state; /* running state */ - int exit_code; /* thread exit code */ - int unix_pid; /* Unix pid of client */ --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0002-server-ntdll-Send-and-receive-server-request.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0002-server-ntdll-Send-and-receive-server-request.patch deleted file mode 100644 index 64c299d..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0002-server-ntdll-Send-and-receive-server-request.patch +++ /dev/null @@ -1,768 +0,0 @@ -From bdb5a922391cb54fc7db0b7ef5aad9f25c3f714b Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Sun, 7 Aug 2022 21:19:26 +0200 -Subject: [PATCH 2/8] server,ntdll: Send and receive server requests through - shared memory. - ---- - dlls/ntdll/unix/server.c | 92 ++++++++++++++++++++++++++++++++ - server/Makefile.in | 2 +- - server/fd.c | 81 ++++++++++++++++++++++++++++ - server/file.h | 5 ++ - server/request.c | 98 ++++++++++++++++++++++++++++++++++ - server/request.h | 1 + - server/thread.c | 111 ++++++++++++++++++++++++++++++++++++++- - server/thread.h | 1 + - 8 files changed, 388 insertions(+), 3 deletions(-) - -diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/server.c -+++ b/dlls/ntdll/unix/server.c -@@ -196,6 +196,78 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err ) - } - - -+#ifdef __linux__ -+ -+#define FUTEX_WAIT 0 -+#define FUTEX_WAKE 1 -+ -+/*********************************************************************** -+ * send_request_shm -+ * -+ * Send a request to the server using shared memory. -+ */ -+static unsigned int send_request_shm( const struct __server_request_info *req ) -+{ -+ volatile struct request_shm *request_shm = ntdll_get_thread_data()->request_shm; -+ unsigned int i; -+ -+ memcpy( (void*)&request_shm->u.req, &req->u.req, sizeof(req->u.req) ); -+ if (req->u.req.request_header.request_size) -+ { -+ char *ptr = (char*)(request_shm + 1); -+ for (i = 0; i < req->data_count; i++) -+ { -+ memcpy( ptr, req->data[i].ptr, req->data[i].size ); -+ ptr += req->data[i].size; -+ } -+ } -+ -+ while (InterlockedCompareExchange( (void*)&request_shm->futex, 1, 0 ) != 0) -+ YieldProcessor(); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); -+ return STATUS_SUCCESS; -+} -+ -+ -+static void read_reply_data( void *buffer, size_t size ); -+ -+/*********************************************************************** -+ * wait_reply_shm -+ * -+ * Wait for a reply from the server using shared memory. -+ */ -+static inline unsigned int wait_reply_shm( struct __server_request_info *req ) -+{ -+ volatile struct request_shm *request_shm = ntdll_get_thread_data()->request_shm; -+ char *data_ptr = (char*)(request_shm + 1) + req->u.req.request_header.request_size; -+ unsigned int copy_limit = (char*)request_shm + REQUEST_SHM_SIZE - data_ptr; -+ int val; -+ -+ while ((val = request_shm->futex) != 0) -+ { -+ if (val == -1) -+ abort_thread(0); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ } -+ -+ memcpy( &req->u.reply, (void*)&request_shm->u.reply, sizeof(req->u.reply) ); -+ if (req->u.reply.reply_header.reply_size) -+ { -+ if (req->u.reply.reply_header.reply_size > copy_limit) -+ { -+ memcpy( req->reply_data, data_ptr, copy_limit ); -+ read_reply_data( (char*)req->reply_data + copy_limit, -+ req->u.reply.reply_header.reply_size - copy_limit ); -+ } -+ else -+ memcpy( req->reply_data, data_ptr, req->u.reply.reply_header.reply_size ); -+ } -+ return req->u.reply.reply_header.error; -+} -+ -+#endif /* defined(__linux__) */ -+ -+ - /*********************************************************************** - * send_request - * -@@ -302,6 +374,20 @@ static inline unsigned int wait_reply( struct __server_request_info *req ) - } - - -+#ifdef __linux__ -+ -+unsigned int server_call_unlocked_shm( void *req_ptr ) -+{ -+ struct __server_request_info * const req = req_ptr; -+ unsigned int ret; -+ -+ if ((ret = send_request_shm( req ))) return ret; -+ return wait_reply_shm( req ); -+} -+ -+#endif -+ -+ - /*********************************************************************** - * server_call_unlocked - */ -@@ -310,6 +396,12 @@ unsigned int server_call_unlocked( void *req_ptr ) - struct __server_request_info * const req = req_ptr; - unsigned int ret; - -+#ifdef __linux__ -+ if (ntdll_get_thread_data()->request_shm && -+ sizeof(req->u.req) + req->u.req.request_header.request_size < REQUEST_SHM_SIZE) -+ return server_call_unlocked_shm( req_ptr ); -+#endif -+ - if ((ret = send_request( req ))) return ret; - return wait_reply( req ); - } -diff --git a/server/Makefile.in b/server/Makefile.in -index 11111111111..11111111111 100644 ---- a/server/Makefile.in -+++ b/server/Makefile.in -@@ -52,7 +52,7 @@ SOURCES = \ - wineserver.man.in \ - winstation.c - --UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) -+UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(PTHREAD_LIBS) - - unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${nlsdir}`\" - -diff --git a/server/fd.c b/server/fd.c -index 11111111111..11111111111 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -160,6 +161,7 @@ struct fd - unsigned int signaled :1; /* is the fd signaled? */ - unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */ - int poll_index; /* index of fd in poll array */ -+ int poll_generation; /* generation that this fd was added to the poll array in */ - struct async_queue read_q; /* async readers of this fd */ - struct async_queue write_q; /* async writers of this fd */ - struct async_queue wait_q; /* other async waiters of this fd */ -@@ -470,6 +472,10 @@ static void set_user_shared_data_time(void) - user_shared_data->QpcBias = qpc_bias; - } - -+pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; -+int poll_exit_pipe[2]; -+struct fd *poll_exit_fd; -+ - void set_current_time(void) - { - static const timeout_t ticks_1601_to_1970 = (timeout_t)86400 * (369 * 365 + 89) * TICKS_PER_SEC; -@@ -565,6 +571,7 @@ static int nb_users; /* count of array entries actually i - static int active_users; /* current number of active users */ - static int allocated_users; /* count of allocated entries in the array */ - static struct fd **freelist; /* list of free entries in the array */ -+unsigned long poll_generation; /* current poll array generation */ - - static int get_next_timeout(void); - -@@ -643,20 +650,27 @@ static inline void main_loop_epoll(void) - - if (epoll_fd == -1) return; - -+ pthread_mutex_lock( &global_lock ); - while (active_users) - { -+ unsigned long generation; -+ - timeout = get_next_timeout(); - - if (!active_users) break; /* last user removed by a timeout */ - if (epoll_fd == -1) break; /* an error occurred with epoll */ - -+ generation = poll_generation; -+ pthread_mutex_unlock( &global_lock ); - ret = epoll_wait( epoll_fd, events, ARRAY_SIZE( events ), timeout ); -+ pthread_mutex_lock( &global_lock ); - set_current_time(); - - /* put the events into the pollfd array first, like poll does */ - for (i = 0; i < ret; i++) - { - int user = events[i].data.u32; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - pollfd[user].revents = events[i].events; - } - -@@ -664,9 +678,11 @@ static inline void main_loop_epoll(void) - for (i = 0; i < ret; i++) - { - int user = events[i].data.u32; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - if (pollfd[user].revents) fd_poll_event( poll_users[user], pollfd[user].revents ); - } - } -+ pthread_mutex_unlock( &global_lock ); - } - - #elif defined(HAVE_KQUEUE) -@@ -737,13 +753,18 @@ static inline void main_loop_epoll(void) - - if (kqueue_fd == -1) return; - -+ pthread_mutex_lock( &global_lock ); - while (active_users) - { -+ unsigned long generation; -+ - timeout = get_next_timeout(); - - if (!active_users) break; /* last user removed by a timeout */ - if (kqueue_fd == -1) break; /* an error occurred with kqueue */ - -+ generation = poll_generation; -+ pthread_mutex_unlock( &global_lock ); - if (timeout != -1) - { - struct timespec ts; -@@ -753,6 +774,7 @@ static inline void main_loop_epoll(void) - ret = kevent( kqueue_fd, NULL, 0, events, ARRAY_SIZE( events ), &ts ); - } - else ret = kevent( kqueue_fd, NULL, 0, events, ARRAY_SIZE( events ), NULL ); -+ pthread_mutex_lock( &global_lock ); - - set_current_time(); - -@@ -760,11 +782,13 @@ static inline void main_loop_epoll(void) - for (i = 0; i < ret; i++) - { - long user = (long)events[i].udata; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - pollfd[user].revents = 0; - } - for (i = 0; i < ret; i++) - { - long user = (long)events[i].udata; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - if (events[i].filter == EVFILT_READ) pollfd[user].revents |= POLLIN; - else if (events[i].filter == EVFILT_WRITE) pollfd[user].revents |= POLLOUT; - if (events[i].flags & EV_EOF) pollfd[user].revents |= POLLHUP; -@@ -775,10 +799,12 @@ static inline void main_loop_epoll(void) - for (i = 0; i < ret; i++) - { - long user = (long)events[i].udata; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - if (pollfd[user].revents) fd_poll_event( poll_users[user], pollfd[user].revents ); - pollfd[user].revents = 0; - } - } -+ pthread_mutex_unlock( &global_lock ); - } - - #elif defined(USE_EVENT_PORTS) -@@ -839,14 +865,19 @@ static inline void main_loop_epoll(void) - - if (port_fd == -1) return; - -+ pthread_mutex_lock( &global_lock ); - while (active_users) - { -+ unsigned long generation; -+ - timeout = get_next_timeout(); - nget = 1; - - if (!active_users) break; /* last user removed by a timeout */ - if (port_fd == -1) break; /* an error occurred with event completion */ - -+ generation = poll_generation; -+ pthread_mutex_unlock( &global_lock ); - if (timeout != -1) - { - struct timespec ts; -@@ -856,6 +887,7 @@ static inline void main_loop_epoll(void) - ret = port_getn( port_fd, events, ARRAY_SIZE( events ), &nget, &ts ); - } - else ret = port_getn( port_fd, events, ARRAY_SIZE( events ), &nget, NULL ); -+ pthread_mutex_lock( &global_lock ); - - if (ret == -1) break; /* an error occurred with event completion */ - -@@ -865,6 +897,7 @@ static inline void main_loop_epoll(void) - for (i = 0; i < nget; i++) - { - long user = (long)events[i].portev_user; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - pollfd[user].revents = events[i].portev_events; - } - -@@ -872,6 +905,7 @@ static inline void main_loop_epoll(void) - for (i = 0; i < nget; i++) - { - long user = (long)events[i].portev_user; -+ if (user >= nb_users || pollfd[user].fd == -1 || poll_users[user]->poll_generation > generation) continue; - if (pollfd[user].revents) fd_poll_event( poll_users[user], pollfd[user].revents ); - /* if we are still interested, reassociate the fd */ - if (pollfd[user].fd != -1) { -@@ -879,6 +913,7 @@ static inline void main_loop_epoll(void) - } - } - } -+ pthread_mutex_unlock( &global_lock ); - } - - #else /* HAVE_KQUEUE */ -@@ -927,6 +962,7 @@ static int add_poll_user( struct fd *fd ) - pollfd[ret].events = 0; - pollfd[ret].revents = 0; - poll_users[ret] = fd; -+ fd->poll_generation = ++poll_generation; - active_users++; - return ret; - } -@@ -1012,30 +1048,66 @@ static int get_next_timeout(void) - return ret; - } - -+static void poll_exit_poll_event( struct fd *fd, int event ) -+{ -+ char dummy; -+ read( fd->unix_fd, &dummy, sizeof(dummy) ); -+} -+ -+static const struct fd_ops poll_exit_fd_ops = -+{ -+ NULL, /* get_poll_events */ -+ poll_exit_poll_event, /* poll_event */ -+ NULL, /* flush */ -+ NULL, /* get_fd_type */ -+ NULL, /* ioctl */ -+ NULL, /* queue_async */ -+ NULL /* reselect_async */ -+}; -+ -+static int create_poll_exit_fd( void ) -+{ -+ if (pipe( poll_exit_pipe )) return 0; -+ poll_exit_fd = create_anonymous_fd( &poll_exit_fd_ops, poll_exit_pipe[0], NULL, 0 ); -+ if (!poll_exit_fd) return 0; -+ set_fd_events( poll_exit_fd, POLLIN ); -+ return 1; -+} -+ -+ - /* server main poll() loop */ - void main_loop(void) - { - int i, ret, timeout; - -+ if (!create_poll_exit_fd()) return; -+ - set_current_time(); - server_start_time = current_time; - - main_loop_epoll(); - /* fall through to normal poll loop */ - -+ pthread_mutex_lock( &global_lock ); - while (active_users) - { -+ unsigned long generation; -+ - timeout = get_next_timeout(); - - if (!active_users) break; /* last user removed by a timeout */ - -+ generation = poll_generation; -+ pthread_mutex_unlock( &global_lock ); - ret = poll( pollfd, nb_users, timeout ); -+ pthread_mutex_lock( &global_lock ); - set_current_time(); - - if (ret > 0) - { - for (i = 0; i < nb_users; i++) - { -+ if (pollfd[i].fd == -1 || poll_users[i]->poll_generation > generation) continue; - if (pollfd[i].revents) - { - fd_poll_event( poll_users[i], pollfd[i].revents ); -@@ -1044,6 +1116,14 @@ void main_loop(void) - } - } - } -+ pthread_mutex_unlock( &global_lock ); -+} -+ -+/* global lock must be held */ -+void force_exit_poll( void ) -+{ -+ static char zero; -+ write( poll_exit_pipe[1], &zero, sizeof(zero) ); - } - - -@@ -1768,6 +1848,8 @@ void set_fd_events( struct fd *fd, int events ) - int user = fd->poll_index; - assert( poll_users[user] == fd ); - -+ fd->poll_generation = ++poll_generation; -+ - set_fd_epoll_events( fd, user, events ); - - if (events == -1) /* stop waiting on this fd completely */ -diff --git a/server/file.h b/server/file.h -index 11111111111..11111111111 100644 ---- a/server/file.h -+++ b/server/file.h -@@ -21,6 +21,7 @@ - #ifndef __WINE_SERVER_FILE_H - #define __WINE_SERVER_FILE_H - -+#include - #include - #include - -@@ -80,6 +81,9 @@ struct fd_ops - - /* file descriptor functions */ - -+extern pthread_mutex_t global_lock; -+extern unsigned long poll_generation; -+ - extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user, - unsigned int options ); - extern struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name, -@@ -133,6 +137,7 @@ extern void no_fd_queue_async( struct fd *fd, struct async *async, int type, int - extern void default_fd_queue_async( struct fd *fd, struct async *async, int type, int count ); - extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); - extern void main_loop(void); -+extern void force_exit_poll(void); - extern void remove_process_locks( struct process *process ); - - static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get_fd( obj ); } -diff --git a/server/request.c b/server/request.c -index 11111111111..11111111111 100644 ---- a/server/request.c -+++ b/server/request.c -@@ -261,6 +261,104 @@ void write_reply( struct thread *thread ) - fatal_protocol_error( thread, "reply write: %s\n", strerror( errno )); - } - -+/* send a reply to the current thread */ -+void send_reply_shm( union generic_reply *reply, struct request_shm *request_shm, data_size_t req_data_size ) -+{ -+ char *data_ptr = (char*)(request_shm + 1) + req_data_size; -+ unsigned int copy_limit = (char*)request_shm + REQUEST_SHM_SIZE - data_ptr; -+ int ret; -+ -+ /* fixed data is already written */ -+ if (!current->reply_size) -+ return; -+ -+ if (current->reply_size <= copy_limit) -+ { -+ memcpy( data_ptr, current->reply_data, current->reply_size ); -+ if (current->reply_data != current->rep_data) free( current->reply_data ); -+ current->reply_data = NULL; -+ return; -+ } -+ -+ memcpy( data_ptr, current->reply_data, copy_limit ); -+ current->reply_towrite = current->reply_size - copy_limit; -+ -+ if ((ret = write( get_unix_fd( current->reply_fd ), -+ (char *)current->reply_data + current->reply_size - current->reply_towrite, -+ current->reply_towrite )) >= 0) -+ { -+ if (!(current->reply_towrite -= ret)) -+ { -+ if (current->reply_data != current->rep_data) free( current->reply_data ); -+ current->reply_data = NULL; -+ } -+ else -+ { -+ /* couldn't write it all, wait for POLLOUT */ -+ set_fd_events( current->reply_fd, POLLOUT ); -+ set_fd_events( current->request_fd, 0 ); -+ } -+ return; -+ } -+ if (errno == EPIPE) -+ kill_thread( current, 0 ); /* normal death */ -+ else if (errno != EWOULDBLOCK && (EWOULDBLOCK == EAGAIN || errno != EAGAIN)) -+ fatal_protocol_error( current, "reply write: %s\n", strerror( errno )); -+} -+ -+/* call a request handler using shared memory */ -+static void call_req_handler_shm( struct thread *thread, struct request_shm *request_shm ) -+{ -+ enum request req = thread->req.request_header.req; -+ data_size_t data_size = thread->req.request_header.request_size; -+ -+ current = thread; -+ current->reply_size = 0; -+ clear_error(); -+ memset( &request_shm->u.reply, 0, sizeof(request_shm->u.reply) ); -+ -+ if (debug_level) trace_request(); -+ -+ if (req < REQ_NB_REQUESTS) -+ req_handlers[req]( ¤t->req, &request_shm->u.reply ); -+ else -+ set_error( STATUS_NOT_IMPLEMENTED ); -+ -+ if (current) -+ { -+ if (current->reply_fd) -+ { -+ request_shm->u.reply.reply_header.error = current->error; -+ request_shm->u.reply.reply_header.reply_size = current->reply_size; -+ if (debug_level) trace_reply( req, &request_shm->u.reply ); -+ send_reply_shm( &request_shm->u.reply, request_shm, data_size ); -+ } -+ else -+ { -+ current->exit_code = 1; -+ kill_thread( current, 1 ); /* no way to continue without reply fd */ -+ } -+ } -+ current = NULL; -+} -+ -+/* read a request from a thread using shared memory */ -+void read_request_shm( struct thread *thread, struct request_shm *request_shm ) -+{ -+ void *orig_req_data = thread->req_data; -+ data_size_t data_size; -+ -+ memcpy( &thread->req, &request_shm->u.req, sizeof(thread->req) ); -+ data_size = thread->req.request_header.request_size; -+ if (data_size) -+ thread->req_data = request_shm + 1; -+ -+ call_req_handler_shm( thread, request_shm ); -+ -+ if (data_size) -+ thread->req_data = orig_req_data; -+} -+ - /* send a reply to the current thread */ - void send_reply( union generic_reply *reply ) - { -diff --git a/server/request.h b/server/request.h -index 11111111111..11111111111 100644 ---- a/server/request.h -+++ b/server/request.h -@@ -52,6 +52,7 @@ extern const struct object_attributes *get_req_object_attributes( const struct s - extern const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ); - extern int receive_fd( struct process *process ); - extern int send_client_fd( struct process *process, int fd, obj_handle_t handle ); -+extern void read_request_shm( struct thread *thread, struct request_shm *request_shm ); - extern void read_request( struct thread *thread ); - extern void write_reply( struct thread *thread ); - extern timeout_t monotonic_counter(void); -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -44,6 +45,9 @@ - #ifdef HAVE_SYS_RESOURCE_H - #include - #endif -+#ifdef HAVE_SYS_SYSCALL_H -+#include -+#endif - - #include "ntstatus.h" - #define WIN32_NO_STATUS -@@ -378,6 +382,7 @@ static inline void init_thread_structure( struct thread *thread ) - #ifdef __linux__ - thread->request_shm_fd = -1; - thread->request_shm = NULL; -+ thread->request_shm_thread_running = 0; - #endif - thread->state = RUNNING; - thread->exit_code = 0; -@@ -446,6 +451,86 @@ static struct context *create_thread_context( struct thread *thread ) - } - - -+#ifdef __linux__ -+ -+static void handle_shm_request( struct thread *thread, struct request_shm *request_shm ) -+{ -+ set_current_time(); -+ read_request_shm( thread, request_shm ); -+} -+ -+ -+#define FUTEX_WAIT 0 -+#define FUTEX_WAKE 1 -+ -+static void *request_shm_thread(void *param) -+{ -+ struct thread *thread = param; -+ int request_shm_fd; -+ volatile struct request_shm *request_shm; -+ unsigned long generation = 0; -+ -+ pthread_mutex_lock( &global_lock ); -+ request_shm_fd = thread->request_shm_fd; -+ request_shm = thread->request_shm; -+ pthread_mutex_unlock( &global_lock ); -+ -+ for (;;) -+ { -+ int val; -+ -+ while ((val = request_shm->futex) != 1) -+ { -+ if (val == -1) -+ goto done; -+ else if (val != 0) -+ fatal_protocol_error( thread, "unknown futex state %d\n", val ); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ } -+ -+ pthread_mutex_lock( &global_lock ); -+ generation = poll_generation; -+ -+ val = request_shm->futex; -+ if (val != 1) -+ { -+ if (val != -1) -+ fatal_protocol_error( thread, "unknown futex state %d\n", val ); -+ goto done_locked; -+ } -+ -+ __asm__ __volatile__ ("" ::: "memory"); -+ handle_shm_request( thread, (struct request_shm *)request_shm ); -+ __asm__ __volatile__ ("" ::: "memory"); -+ -+ request_shm_fd = thread->request_shm_fd; -+ request_shm = thread->request_shm; -+ if (!request_shm_fd || !request_shm) -+ goto done_locked; -+ val = __sync_val_compare_and_swap( &request_shm->futex, 1, 0 ); -+ if (val != 1 && val != -1) -+ fatal_protocol_error( thread, "unknown futex state %d\n", val ); -+ pthread_mutex_unlock( &global_lock ); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); -+ if (poll_generation != generation) -+ force_exit_poll(); -+ } -+ -+done: -+ pthread_mutex_lock( &global_lock ); -+done_locked: -+ if (request_shm_fd != -1) close( request_shm_fd ); -+ if (request_shm) munmap( (void*)request_shm, REQUEST_SHM_SIZE ); -+ release_object( thread ); -+ pthread_mutex_unlock( &global_lock ); -+ if (poll_generation != generation) -+ force_exit_poll(); -+ return NULL; -+} -+ -+#endif /* defined(__linux__) */ -+ -+ - static struct context *create_thread_context( struct thread *thread ) - { - struct context *context; -@@ -504,6 +589,9 @@ struct thread *create_thread( int fd, struct process *process, const struct secu - struct desktop *desktop; - struct thread *thread; - int request_pipe[2]; -+#ifdef __linux__ -+ pthread_t pthread; -+#endif - - if (memory_barrier_obj) - grab_object( &memory_barrier_obj->obj ); -@@ -596,6 +684,16 @@ struct thread *create_thread( int fd, struct process *process, const struct secu - release_object( thread ); - return NULL; - } -+ -+ grab_object( thread ); -+ if (pthread_create( &pthread, NULL, request_shm_thread, thread )) -+ { -+ release_object( thread ); -+ release_object( thread ); -+ return NULL; -+ } -+ pthread_detach( pthread ); -+ thread->request_shm_thread_running = 1; - #endif - - if (do_fsync()) -@@ -666,8 +764,16 @@ static void cleanup_thread( struct thread *thread ) - if (thread->reply_fd) release_object( thread->reply_fd ); - if (thread->wait_fd) release_object( thread->wait_fd ); - #ifdef __linux__ -- if (thread->request_shm_fd != -1) close( thread->request_shm_fd ); -- if (thread->request_shm) munmap( (void*)thread->request_shm, REQUEST_SHM_SIZE ); -+ if (thread->request_shm) -+ { -+ __atomic_exchange_n( &thread->request_shm->futex, -1, __ATOMIC_SEQ_CST ); -+ syscall( __NR_futex, &thread->request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); -+ } -+ if (!thread->request_shm_thread_running) -+ { -+ if (thread->request_shm_fd != -1) close( thread->request_shm_fd ); -+ if (thread->request_shm) munmap( (void*)thread->request_shm, REQUEST_SHM_SIZE ); -+ } - #endif - cleanup_clipboard_thread(thread); - destroy_thread_windows( thread ); -@@ -695,6 +801,7 @@ static void cleanup_thread( struct thread *thread ) - #ifdef __linux__ - thread->request_shm_fd = -1; - thread->request_shm = NULL; -+ thread->request_shm_thread_running = 0; - #endif - thread->desktop = 0; - thread->desc = NULL; -diff --git a/server/thread.h b/server/thread.h -index 11111111111..11111111111 100644 ---- a/server/thread.h -+++ b/server/thread.h -@@ -93,6 +93,7 @@ struct thread - #ifdef __linux__ - int request_shm_fd; /* request shared memory fd */ - volatile struct request_shm *request_shm; /* shared memory for receiving and sending client requests/replies */ -+ int request_shm_thread_running; - #endif - enum run_state state; /* running state */ - int exit_code; /* thread exit code */ --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0003-server-Write-reply-data-directly-to-shared-m.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0003-server-Write-reply-data-directly-to-shared-m.patch deleted file mode 100644 index a64e364..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0003-server-Write-reply-data-directly-to-shared-m.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 50a1e01f2af43c2e8600bd0b16406b19a1e38909 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Sat, 6 Aug 2022 20:29:00 +0200 -Subject: [PATCH 3/8] server: Write reply data directly to shared memory if - possible. - ---- - server/request.c | 35 ++++++++++++++++++++++++----------- - server/thread.c | 28 ++++++++++++++++++++++++++-- - server/thread.h | 1 + - 3 files changed, 51 insertions(+), 13 deletions(-) - -diff --git a/server/request.c b/server/request.c -index 11111111111..11111111111 100644 ---- a/server/request.c -+++ b/server/request.c -@@ -162,10 +162,23 @@ void fatal_error( const char *err, ... ) - exit(1); - } - -+int reply_in_shm; -+ - /* allocate the reply data */ - void *set_reply_data_size( data_size_t size ) - { - assert( size <= get_reply_max_size() ); -+ if (current->request_shm && reply_in_shm) -+ { -+ char *data_ptr = (char*)(current->request_shm + 1) + current->req.request_header.request_size; -+ unsigned int size_limit = (char*)current->request_shm + REQUEST_SHM_SIZE - data_ptr; -+ if (size_limit >= size) -+ { -+ current->reply_data = data_ptr; -+ current->reply_size = size; -+ return current->reply_data; -+ } -+ } - if (size > current->rep_data_size) - { - if (current->rep_data) free(current->rep_data); -@@ -247,8 +260,7 @@ void write_reply( struct thread *thread ) - { - if (!(thread->reply_towrite -= ret)) - { -- if (thread->reply_data != thread->rep_data) free( thread->reply_data ); -- thread->reply_data = NULL; -+ cleanup_thread_reply_data( thread ); - /* sent everything, can go back to waiting for requests */ - set_fd_events( thread->request_fd, POLLIN ); - set_fd_events( thread->reply_fd, 0 ); -@@ -272,11 +284,14 @@ void send_reply_shm( union generic_reply *reply, struct request_shm *request_shm - if (!current->reply_size) - return; - -+ if ((char*)current->reply_data >= (char*)request_shm && -+ (char*)current->reply_data < (char*)request_shm + REQUEST_SHM_SIZE) -+ return; -+ - if (current->reply_size <= copy_limit) - { - memcpy( data_ptr, current->reply_data, current->reply_size ); -- if (current->reply_data != current->rep_data) free( current->reply_data ); -- current->reply_data = NULL; -+ cleanup_thread_reply_data( current ); - return; - } - -@@ -288,10 +303,7 @@ void send_reply_shm( union generic_reply *reply, struct request_shm *request_shm - current->reply_towrite )) >= 0) - { - if (!(current->reply_towrite -= ret)) -- { -- if (current->reply_data != current->rep_data) free( current->reply_data ); -- current->reply_data = NULL; -- } -+ cleanup_thread_reply_data( current ); - else - { - /* couldn't write it all, wait for POLLOUT */ -@@ -352,10 +364,12 @@ void read_request_shm( struct thread *thread, struct request_shm *request_shm ) - data_size = thread->req.request_header.request_size; - if (data_size) - thread->req_data = request_shm + 1; -+ reply_in_shm = 1; - - call_req_handler_shm( thread, request_shm ); - -- if (data_size) -+ reply_in_shm = 0; -+ if (data_size && thread->req_data == request_shm + 1) - thread->req_data = orig_req_data; - } - -@@ -382,8 +396,7 @@ void send_reply( union generic_reply *reply ) - return; - } - -- if (current->reply_data != current->rep_data) free( current->reply_data ); -- current->reply_data = NULL; -+ cleanup_thread_reply_data( current ); - return; - - error: -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -742,6 +742,30 @@ static struct fast_sync *thread_get_fast_sync( struct object *obj ) - return thread->fast_sync; - } - -+void cleanup_thread_reply_data( struct thread *thread ) -+{ -+ if (thread->reply_data == thread->rep_data) -+ return; -+ -+ if (thread->request_shm && -+ (char*)thread->reply_data >= (char*)thread->request_shm && -+ (char*)thread->reply_data < (char*)thread->request_shm + REQUEST_SHM_SIZE) -+ return; -+ -+ free( thread->reply_data ); -+ thread->reply_data = NULL; -+} -+ -+void cleanup_thread_req_data( struct thread *thread ) -+{ -+ if (thread->request_shm && -+ (char*)thread->req_data >= (char*)thread->request_shm && -+ (char*)thread->req_data < (char*)thread->request_shm + REQUEST_SHM_SIZE) -+ return; -+ -+ free( thread->req_data ); -+} -+ - /* cleanup everything that is no longer needed by a dead thread */ - /* used by destroy_thread and kill_thread */ - static void cleanup_thread( struct thread *thread ) -@@ -757,9 +781,9 @@ static void cleanup_thread( struct thread *thread ) - } - clear_apc_queue( &thread->system_apc ); - clear_apc_queue( &thread->user_apc ); -- free( thread->req_data ); -+ cleanup_thread_req_data( thread ); - free( thread->rep_data ); -- if (thread->reply_data != thread->rep_data) free( thread->reply_data ); -+ cleanup_thread_reply_data( thread ); - if (thread->request_fd) release_object( thread->request_fd ); - if (thread->reply_fd) release_object( thread->reply_fd ); - if (thread->wait_fd) release_object( thread->wait_fd ); -diff --git a/server/thread.h b/server/thread.h -index 11111111111..11111111111 100644 ---- a/server/thread.h -+++ b/server/thread.h -@@ -132,6 +132,7 @@ extern struct thread *current; - - extern struct thread *create_thread( int fd, struct process *process, - const struct security_descriptor *sd ); -+extern void cleanup_thread_reply_data( struct thread *thread ); - extern struct thread *get_thread_from_id( thread_id_t id ); - extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int access ); - extern struct thread *get_thread_from_tid( int tid ); --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0004-HACK-ntdll-server-Spin-instead-of-wait-for-f.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0004-HACK-ntdll-server-Spin-instead-of-wait-for-f.patch deleted file mode 100644 index 88b40b4..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0004-HACK-ntdll-server-Spin-instead-of-wait-for-f.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d658f3e6d8d379d428f60d3f7156f2a09e76db18 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Mon, 8 Aug 2022 20:19:28 +0200 -Subject: [PATCH 4/8] HACK: ntdll,server: Spin instead of wait for futex - ---- - dlls/ntdll/unix/server.c | 3 ++- - server/thread.c | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/server.c -+++ b/dlls/ntdll/unix/server.c -@@ -247,7 +247,8 @@ static inline unsigned int wait_reply_shm( struct __server_request_info *req ) - { - if (val == -1) - abort_thread(0); -- syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ //syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ YieldProcessor(); - } - - memcpy( &req->u.reply, (void*)&request_shm->u.reply, sizeof(req->u.reply) ); -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -511,7 +511,7 @@ static void *request_shm_thread(void *param) - if (val != 1 && val != -1) - fatal_protocol_error( thread, "unknown futex state %d\n", val ); - pthread_mutex_unlock( &global_lock ); -- syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); -+ //syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); - if (poll_generation != generation) - force_exit_poll(); - } --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0005-HACK-server-Do-not-use-an-atomic-instruction.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0005-HACK-server-Do-not-use-an-atomic-instruction.patch deleted file mode 100644 index 809bc25..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0005-HACK-server-Do-not-use-an-atomic-instruction.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 481c3131ad21fc62f45dc4b7c421926805d95285 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Mon, 15 Aug 2022 21:03:25 +0200 -Subject: [PATCH 5/8] HACK: server: Do not use an atomic instruction to reset - futex. - ---- - server/thread.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -507,8 +507,11 @@ static void *request_shm_thread(void *param) - request_shm = thread->request_shm; - if (!request_shm_fd || !request_shm) - goto done_locked; -- val = __sync_val_compare_and_swap( &request_shm->futex, 1, 0 ); -- if (val != 1 && val != -1) -+ __sync_synchronize(); -+ val = request_shm->futex; -+ if (val == 1) -+ request_shm->futex = 0; -+ else if (val != -1) - fatal_protocol_error( thread, "unknown futex state %d\n", val ); - pthread_mutex_unlock( &global_lock ); - //syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0006-HACK-server-Spin-on-the-request-futex-for-a-.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0006-HACK-server-Spin-on-the-request-futex-for-a-.patch deleted file mode 100644 index dfd1e3e..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0006-HACK-server-Spin-on-the-request-futex-for-a-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b7a8b42e4aa284288672c04ade38e5c50f918b52 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Mon, 15 Aug 2022 21:04:27 +0200 -Subject: [PATCH 6/8] HACK: server: Spin on the request futex for a little bit - after completing a request. - ---- - server/thread.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -478,14 +479,20 @@ static void *request_shm_thread(void *param) - for (;;) - { - int val; -+ int spincount = 2000; - -+ if ((val = request_shm->futex) != 1) -+ sched_yield(); - while ((val = request_shm->futex) != 1) - { - if (val == -1) - goto done; - else if (val != 0) - fatal_protocol_error( thread, "unknown futex state %d\n", val ); -- syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ if (spincount == 0) -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ else -+ --spincount; - } - - pthread_mutex_lock( &global_lock ); --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0007-STAGING-server-Propagate-main-thread-schedul.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0007-STAGING-server-Propagate-main-thread-schedul.patch deleted file mode 100644 index 637c3a5..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0007-STAGING-server-Propagate-main-thread-schedul.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e59d96f59742a9074ae44576aa350764f50675dd Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Fri, 20 Jan 2023 18:31:18 +0100 -Subject: [PATCH 7/8] STAGING: server: Propagate main thread scheduling priority to - shm request threads. - ---- - server/thread.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -601,6 +601,8 @@ struct thread *create_thread( int fd, struct process *process, const struct secu - int request_pipe[2]; - #ifdef __linux__ - pthread_t pthread; -+ int policy; -+ struct sched_param param; - #endif - - if (memory_barrier_obj) -@@ -702,6 +704,9 @@ struct thread *create_thread( int fd, struct process *process, const struct secu - release_object( thread ); - return NULL; - } -+ if (!pthread_getschedparam( pthread_self(), &policy, ¶m ) && (policy || param.sched_priority)) -+ if (pthread_setschedparam( pthread, policy | SCHED_RESET_ON_FORK, ¶m )) -+ pthread_setschedparam( pthread, policy, ¶m ); - pthread_detach( pthread ); - thread->request_shm_thread_running = 1; - #endif --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0008-HACK-ntdll-Track-spin-timeout-counts-and-sto.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0008-HACK-ntdll-Track-spin-timeout-counts-and-sto.patch deleted file mode 100644 index 2e5e5e8..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0008-HACK-ntdll-Track-spin-timeout-counts-and-sto.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 40145ff85b39d69a0a53a8534e2431d75b51a765 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Sat, 24 Jun 2023 16:34:51 +0200 -Subject: [PATCH 8/8] HACK: ntdll: Track spin timeout counts and stop spinning - after a certain number of timeouts. - ---- - dlls/ntdll/unix/server.c | 27 +++++++++++++++++++++++++-- - server/thread.c | 2 +- - 2 files changed, 26 insertions(+), 3 deletions(-) - -diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/server.c -+++ b/dlls/ntdll/unix/server.c -@@ -231,6 +231,9 @@ static unsigned int send_request_shm( const struct __server_request_info *req ) - - static void read_reply_data( void *buffer, size_t size ); - -+unsigned int request_spin_timeout_count[REQ_NB_REQUESTS]; -+unsigned int request_spin_success_count[REQ_NB_REQUESTS]; -+ - /*********************************************************************** - * wait_reply_shm - * -@@ -241,16 +244,36 @@ static inline unsigned int wait_reply_shm( struct __server_request_info *req ) - volatile struct request_shm *request_shm = ntdll_get_thread_data()->request_shm; - char *data_ptr = (char*)(request_shm + 1) + req->u.req.request_header.request_size; - unsigned int copy_limit = (char*)request_shm + REQUEST_SHM_SIZE - data_ptr; -+ enum request req_nr = req->u.req.request_header.req; -+ unsigned int spincount = 8000; - int val; - -- while ((val = request_shm->futex) != 0) -+ if ((request_spin_timeout_count[req_nr] * 64) > request_spin_success_count[req_nr] + 2048) -+ goto no_spin; -+ -+ while (spincount > 0 && (val = request_shm->futex) != 0) - { - if (val == -1) - abort_thread(0); -- //syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ spincount--; - YieldProcessor(); - } - -+ if (spincount) -+ InterlockedIncrement( &request_spin_success_count[req_nr] ); -+ else -+ { -+ InterlockedIncrement( &request_spin_timeout_count[req_nr] ); -+ -+ no_spin:; -+ while ((val = request_shm->futex) != 0) -+ { -+ if (val == -1) -+ abort_thread(0); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAIT, val, NULL, NULL, 0 ); -+ } -+ } -+ - memcpy( &req->u.reply, (void*)&request_shm->u.reply, sizeof(req->u.reply) ); - if (req->u.reply.reply_header.reply_size) - { -diff --git a/server/thread.c b/server/thread.c -index 11111111111..11111111111 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -521,7 +521,7 @@ static void *request_shm_thread(void *param) - else if (val != -1) - fatal_protocol_error( thread, "unknown futex state %d\n", val ); - pthread_mutex_unlock( &global_lock ); -- //syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); -+ syscall( __NR_futex, &request_shm->futex, FUTEX_WAKE, 1, NULL, NULL, 0 ); - if (poll_generation != generation) - force_exit_poll(); - } --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/ps0435-p0009-HACK-ntdll-Use-mwaitx-if-available.patch b/0013-server-optimization/0002-threaded-server/ps0435-p0009-HACK-ntdll-Use-mwaitx-if-available.patch deleted file mode 100644 index ab0f5ea..0000000 --- a/0013-server-optimization/0002-threaded-server/ps0435-p0009-HACK-ntdll-Use-mwaitx-if-available.patch +++ /dev/null @@ -1,118 +0,0 @@ -From dfd4f6e375524b320e7bbb892b42bc22ab5fac0a Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Thu, 3 Aug 2023 22:10:18 +0200 -Subject: [PATCH 9/9] HACK: ntdll: Use mwaitx if available. - ---- - dlls/ntdll/unix/server.c | 88 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - -diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c -index 11111111111..11111111111 100644 ---- a/dlls/ntdll/unix/server.c -+++ b/dlls/ntdll/unix/server.c -@@ -229,6 +229,84 @@ static unsigned int send_request_shm( const struct __server_request_info *req ) - } - - -+#if defined(__x86_64__) || defined(__i386__) -+ -+#if __GNUC__ > 8 || (__GNUC__ == 8 && __GNUC_MINOR__ >= 3) -+#define __asm_inline__ __inline__ -+#else -+#define __asm_inline__ -+#endif -+ -+static inline int mwaitx_supported(void) -+{ -+ static int supported; -+ if (!supported) -+ { -+ unsigned int eax, ecx; -+ __asm__ __volatile__ ( -+ "cpuid" -+ : "=a" (eax), "=c" (ecx) -+ : "a" (0x80000001U) -+ : "ebx", "edx" -+ ); -+ if (ecx & (1U << 29)) -+ supported = 3; -+ else -+ supported = 2; -+ } -+ return supported & 1; -+} -+ -+#define DEFINE_MWAITX(name, type) \ -+ void name(type *addr, type value, unsigned int timeout) \ -+ { \ -+ if (*addr != value) \ -+ return; \ -+ __asm__ __asm_inline__ __volatile__ ( \ -+ ".byte 0x0f,0x01,0xfa" /* monitorx */ \ -+ : "+m" (*(volatile type*)addr) \ -+ : "a" (addr), "c" (0x0U), "d" (0x0U) \ -+ ); \ -+ if (__builtin_expect(*addr != value, 0)) \ -+ return; \ -+ if (__builtin_constant_p(timeout) && timeout == 0) \ -+ { \ -+ __asm__ __volatile__ ( \ -+ ".byte 0x0f,0x01,0xfb" /* mwaitx */ \ -+ : "+m" (*(volatile type*)addr) \ -+ : "a" (0xF0U), "c" (0x0U) \ -+ ); \ -+ } \ -+ else \ -+ { \ -+ __asm__ __volatile__ ( \ -+ ".byte 0x0f,0x01,0xfb" /* mwaitx */ \ -+ : "+m" (*(volatile type*)addr) \ -+ : "a" (0xF0U), "b" (timeout), "c" (0x2U) \ -+ ); \ -+ } \ -+ } -+ -+#else -+ -+#define mwaitx_supported() 0 -+ -+#define DEFINE_MWAITX(name, type) \ -+ static inline void name(type *addr, type value, unsigned int timeout) {} -+ -+#endif -+ -+static inline DEFINE_MWAITX(mwaitxc, unsigned char) -+static inline DEFINE_MWAITX(mwaitxs, unsigned short) -+static inline DEFINE_MWAITX(mwaitx, unsigned int) -+static inline DEFINE_MWAITX(mwaitxl, unsigned long long) -+static inline DEFINE_MWAITX(mwaitxll, unsigned long long) -+#define mwaitx8(a,v) mwaitxc(a,v) -+#define mwaitx16(a,v) mwaitxs(a,v) -+#define mwaitx32(a,v) mwaitx(a,v) -+#define mwaitx64(a,v) mwaitxll(a,v) -+ -+ - static void read_reply_data( void *buffer, size_t size ); - - unsigned int request_spin_timeout_count[REQ_NB_REQUESTS]; -@@ -251,6 +329,16 @@ static inline unsigned int wait_reply_shm( struct __server_request_info *req ) - if ((request_spin_timeout_count[req_nr] * 64) > request_spin_success_count[req_nr] + 2048) - goto no_spin; - -+ if (mwaitx_supported()) -+ { -+ if ((val = request_shm->futex) != 0) -+ mwaitx(&request_shm->futex, val, 10000U); -+ if (request_shm->futex != 0) -+ spincount = 400; -+ else -+ spincount = 1; -+ } -+ - while (spincount > 0 && (val = request_shm->futex) != 0) - { - if (val == -1) --- -0.0.0 - diff --git a/0013-server-optimization/0002-threaded-server/server-Set-a-proper-thread-description-for-each-requ.patch b/0013-server-optimization/0002-threaded-server/server-Set-a-proper-thread-description-for-each-requ.patch deleted file mode 100644 index 0c2d2a7..0000000 --- a/0013-server-optimization/0002-threaded-server/server-Set-a-proper-thread-description-for-each-requ.patch +++ /dev/null @@ -1,213 +0,0 @@ -From ae28b0be95145cd7fa3471c338a4cf5c1fd94932 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Thu, 19 Sep 2024 11:39:32 -0700 -Subject: [PATCH] server: Set each wineserver thread's description also when - thread->desc is set. - ---- - server/thread.c | 77 +++++++++++++++++++++++++++++++++++++++++++ - server/thread.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 163 insertions(+), 1 deletion(-) - -diff --git a/server/thread.c b/server/thread.c -index edd65ae3a68..de6b02a19d4 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -1077,6 +1077,79 @@ int set_thread_priority( struct thread* thread, int priority_class, int priority - return 0; /* ignore errors for now */ - } - -+#define MAX_THREAD_NAME_LENGTH 16 -+#define MAX_RETRIES 5 -+#define RETRY_DELAY_US 1000 -+ -+static void set_shm_thread_name(const WCHAR *desc, size_t desc_len) -+{ -+ if (!desc || desc_len == 0 || desc_len > 1024) -+ return; -+ -+ char converted_name[MAX_THREAD_NAME_LENGTH]; -+ int conversion_result = __utf8_wcstombs(converted_name, sizeof(converted_name) - 1, desc, desc_len); -+ -+ if (conversion_result != STATUS_SUCCESS && conversion_result != STATUS_BUFFER_TOO_SMALL) -+ return; -+ -+ converted_name[sizeof(converted_name) - 1] = '\0'; -+ -+ /* remove any partial UTF-8 character at the end */ -+ size_t i = strnlen(converted_name, sizeof(converted_name) - 1); -+ while (i > 0 && (converted_name[i - 1] & 0xC0) == 0x80) -+ i--; -+ converted_name[i] = '\0'; -+ -+ /* name empty after conversion */ -+ if (converted_name[0] == '\0') -+ return; -+ -+ pid_t tid = gettid(); -+ -+ if (tid == 0) { -+ if (debug_level) -+ fprintf(stderr, "failed to get thread ID for tid %d\n", tid); -+ return; -+ } -+ -+ char path[64]; -+ snprintf(path, sizeof(path), "/proc/self/task/%d/comm", tid); -+ -+ int retries = 0; -+ while (retries < MAX_RETRIES) -+ { -+ int fd = open(path, O_WRONLY); -+ if (fd != -1) -+ { -+ ssize_t written = write(fd, converted_name, strlen(converted_name)); -+ close(fd); -+ -+ if (written > 0) -+ { -+ if (debug_level) -+ fprintf(stderr, "successfully wrote '%s' to %s for tid %d\n", -+ converted_name, path, (unsigned long)tid); -+ return; -+ } -+ } -+ -+ if (errno != ENOENT) -+ { -+ if (debug_level) -+ fprintf(stderr, "failed to write '%s' to %s for tid %d: %s\n", -+ converted_name, path, tid, strerror(errno)); -+ return; -+ } -+ -+ usleep(RETRY_DELAY_US); -+ retries++; -+ } -+ -+ if (debug_level) -+ fprintf(stderr, "failed to write '%s' to %s for tid %d after %d retries\n", -+ converted_name, path, tid, MAX_RETRIES); -+} -+ - /* set all information about a thread */ - static void set_thread_info( struct thread *thread, - const struct set_thread_info_request *req ) -@@ -1114,6 +1187,9 @@ static void set_thread_info( struct thread *thread, - free( thread->desc ); - thread->desc = desc; - thread->desc_len = desc_len; -+#ifdef __linux__ -+ set_shm_thread_name(thread->desc, thread->desc_len); -+#endif - } - } - else -diff --git a/server/thread.h b/server/thread.h -index 21dfbba321f..7e57d3d2bbb 100644 ---- a/server/thread.h -+++ b/server/thread.h -@@ -22,7 +22,8 @@ - #define __WINE_SERVER_THREAD_H - - #include "object.h" -- -+#include "ntstatus.h" -+#define WIN32_NO_STATUS - /* thread structure */ - - struct process; -@@ -47,6 +48,90 @@ struct inflight_fd - #define MAX_INFLIGHT_FDS 16 /* max number of fds in flight per thread */ - - #ifdef __linux__ -+ -+#define HIGH_SURROGATE_START 0xd800 -+#define HIGH_SURROGATE_END 0xdbff -+#define LOW_SURROGATE_START 0xdc00 -+#define LOW_SURROGATE_END 0xdfff -+ -+#define IS_HIGH_SURROGATE(ch) ((ch) >= HIGH_SURROGATE_START && (ch) <= HIGH_SURROGATE_END) -+#define IS_LOW_SURROGATE(ch) ((ch) >= LOW_SURROGATE_START && (ch) <= LOW_SURROGATE_END) -+#define IS_SURROGATE_PAIR(high,low) (IS_HIGH_SURROGATE(high) && IS_LOW_SURROGATE(low)) -+ -+/* copied from dlls/ntdll/locale_private.h */ -+static inline int __get_utf16( const WCHAR *src, unsigned int srclen, unsigned int *ch ) -+{ -+ if (IS_HIGH_SURROGATE( src[0] )) -+ { -+ if (srclen <= 1) return 0; -+ if (!IS_LOW_SURROGATE( src[1] )) return 0; -+ *ch = 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff); -+ return 2; -+ } -+ if (IS_LOW_SURROGATE( src[0] )) return 0; -+ *ch = src[0]; -+ return 1; -+} -+ -+/* copied from dlls/ntdll/locale_private.h */ -+static inline NTSTATUS __utf8_wcstombs( char *dst, unsigned int dstlen, const WCHAR *src, unsigned int srclen ) -+{ -+ char *end; -+ unsigned int val; -+ NTSTATUS status = 0; -+ -+ for (end = dst + dstlen; srclen; srclen--, src++) -+ { -+ WCHAR ch = *src; -+ -+ if (ch < 0x80) /* 0x00-0x7f: 1 byte */ -+ { -+ if (dst > end - 1) break; -+ *dst++ = ch; -+ continue; -+ } -+ if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ -+ { -+ if (dst > end - 2) break; -+ dst[1] = 0x80 | (ch & 0x3f); -+ ch >>= 6; -+ dst[0] = 0xc0 | ch; -+ dst += 2; -+ continue; -+ } -+ if (!__get_utf16( src, srclen, &val )) -+ { -+ val = 0xfffd; -+ status = STATUS_SOME_NOT_MAPPED; -+ } -+ if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ -+ { -+ if (dst > end - 3) break; -+ dst[2] = 0x80 | (val & 0x3f); -+ val >>= 6; -+ dst[1] = 0x80 | (val & 0x3f); -+ val >>= 6; -+ dst[0] = 0xe0 | val; -+ dst += 3; -+ } -+ else /* 0x10000-0x10ffff: 4 bytes */ -+ { -+ if (dst > end - 4) break; -+ dst[3] = 0x80 | (val & 0x3f); -+ val >>= 6; -+ dst[2] = 0x80 | (val & 0x3f); -+ val >>= 6; -+ dst[1] = 0x80 | (val & 0x3f); -+ val >>= 6; -+ dst[0] = 0xf0 | val; -+ dst += 4; -+ src++; -+ srclen--; -+ } -+ } -+ if (srclen) status = STATUS_BUFFER_TOO_SMALL; -+ return status; -+} - struct request_shm - { - int futex; /* signaling futex */ --- -2.46.1 - diff --git a/0013-server-optimization/0004-time-wait/0006-server-Use-clock_gettime-for-set_current_time-if-ava.patch b/0013-server-optimization/0004-time-wait/0006-server-Use-clock_gettime-for-set_current_time-if-ava.patch index a684a9c..5e17b94 100644 --- a/0013-server-optimization/0004-time-wait/0006-server-Use-clock_gettime-for-set_current_time-if-ava.patch +++ b/0013-server-optimization/0004-time-wait/0006-server-Use-clock_gettime-for-set_current_time-if-ava.patch @@ -42,7 +42,7 @@ index c565b524d58..43bed51d5b0 100644 + /* Somehow, the clock_gettime path revealed a memory ordering bug + * that either didn't ever occur, or only rarely did, with the gettimeofday path + */ -+ __atomic_signal_fence(__ATOMIC_SEQ_CST); ++ // __atomic_signal_fence(__ATOMIC_SEQ_CST); + monotonic_time = monotonic_counter(); if (user_shared_data) set_user_shared_data_time(); diff --git a/0013-server-optimization/0004-time-wait/0007-server-Use-a-dedicated-thread-for-user_shared_data-t.patch b/0013-server-optimization/0004-time-wait/0007-server-Use-a-dedicated-thread-for-user_shared_data-t.patch deleted file mode 100644 index 5077d1f..0000000 --- a/0013-server-optimization/0004-time-wait/0007-server-Use-a-dedicated-thread-for-user_shared_data-t.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 469ed056f7fe7f24dd1d6991798716286d8de3e5 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Tue, 5 Nov 2024 08:19:04 -0800 -Subject: [PATCH] server: Use a dedicated thread for user_shared_data time - updates. - -Inspired by a patch by Torge Matthies. ---- - server/Makefile.in | +- - server/fd.c | 87 +++++++++++++++++++++++++++++++++++++++++++++-------- - 2 files changed, 75 insertions(+), 14 deletions(-) - -# diff --git a/server/Makefile.in b/server/Makefile.in -# index d6e422c7bc1..dbaa215a422 100644 -# --- a/server/Makefile.in -# +++ b/server/Makefile.in -# @@ -50,6 +50,6 @@ SOURCES = \ -# wineserver.man.in \ -# winstation.c - -# -UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) -# +UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(PTHREAD_LIBS) - -# unicode_EXTRADEFS = -DBINDIR="\"${bindir}\"" -DDATADIR="\"${datadir}\"" -diff --git a/server/fd.c b/server/fd.c -index 80bf84b5ac0..8538c0e711f 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -344,6 +345,8 @@ static file_pos_t max_unix_offset = OFF_T_MAX; - /****************************************************************/ - /* timeouts support */ - -+#define TICKS_PER_100US 1000 -+ - struct timeout_user - { - struct list entry; /* entry in sorted timeout list */ -@@ -359,7 +362,19 @@ timeout_t monotonic_time; - - struct hypervisor_shared_data *hypervisor_shared_data = NULL; - struct _KUSER_SHARED_DATA *user_shared_data = NULL; --static const int user_shared_data_timeout = 16; -+ -+static const int user_shared_data_timeout_ticks = TICKS_PER_100US; /* 0.1 ms */ -+ -+static inline void ticks_to_timespec(timeout_t ticks, struct timespec *ts) -+{ -+ ts->tv_sec = ticks / TICKS_PER_SEC; -+ ts->tv_nsec = (ticks % TICKS_PER_SEC) * 100; -+} -+ -+static inline timeout_t timespec_to_ticks(const struct timespec *ts) -+{ -+ return (timeout_t)ts->tv_sec * TICKS_PER_SEC + ts->tv_nsec / 100; -+} - - /* 128-bit multiply a by b and return the high 64 bits, same as __umulh */ - static UINT64 multiply_tsc(UINT64 a, UINT64 b) -@@ -391,8 +406,12 @@ static void atomic_store_long(volatile LONG *ptr, LONG value) - #endif - } - --static void set_user_shared_data_time(void) -+static void set_user_shared_data_time(timeout_t current_time, timeout_t monotonic_time) - { -+ /* Adding a compensation offset for the USD update interval -+ * to try to workaround consumers reading stale values and being behind real QPC (maybe not) */ -+ // current_time += user_shared_data_timeout_ticks; -+ // monotonic_time += user_shared_data_timeout_ticks; - timeout_t tick_count = monotonic_time / 10000; - static timeout_t last_timezone_update; - timeout_t timezone_bias; -@@ -459,7 +478,7 @@ static void set_user_shared_data_time(void) - user_shared_data->QpcBias = qpc_bias; - } - --void set_current_time(void) -+static void get_current_time(timeout_t *current_time, timeout_t *monotonic_time) - { - static const timeout_t ticks_1601_to_1970 = (timeout_t)86400 * (369 * 365 + 89) * TICKS_PER_SEC; - -@@ -469,22 +488,21 @@ void set_current_time(void) - timeout_t seconds = (timeout_t)ts.tv_sec * TICKS_PER_SEC; - timeout_t nanoseconds = (timeout_t)(ts.tv_nsec / 100); - -- current_time = seconds + nanoseconds + ticks_1601_to_1970; -+ *current_time = seconds + nanoseconds + ticks_1601_to_1970; - #else - struct timeval now; - gettimeofday(&now, NULL); - timeout_t seconds = (timeout_t)now.tv_sec * TICKS_PER_SEC; - timeout_t microseconds = (timeout_t)now.tv_usec * 10; - -- current_time = seconds + microseconds + ticks_1601_to_1970; -+ *current_time = seconds + microseconds + ticks_1601_to_1970; - #endif -- /* Somehow, the clock_gettime path revealed a memory ordering bug -- * that either didn't ever occur, or only rarely did, with the gettimeofday path -- */ -- __atomic_signal_fence(__ATOMIC_SEQ_CST); -+ *monotonic_time = monotonic_counter(); -+} - -- monotonic_time = monotonic_counter(); -- if (user_shared_data) set_user_shared_data_time(); -+void set_current_time(void) -+{ -+ get_current_time(¤t_time, &monotonic_time); - } - - /* add a timeout user */ -@@ -574,6 +592,7 @@ static int allocated_users; /* count of allocated entries in the - static struct fd **freelist; /* list of free entries in the array */ - - static int get_next_timeout(void); -+static void *update_user_shared_data_time_thread(void *param); - - static inline void fd_poll_event( struct fd *fd, int event ) - { -@@ -658,7 +677,6 @@ static inline void main_loop_epoll(void) - pthread_mutex_unlock( &global_lock ); - ret = epoll_wait( epoll_fd, events, ARRAY_SIZE( events ), timeout ); - pthread_mutex_lock( &global_lock ); -- set_current_time(); - - /* put the events into the pollfd array first, like poll does */ - for (i = 0; i < ret; i++) -@@ -956,7 +974,8 @@ static void remove_poll_user( struct fd *fd, int user ) - /* process pending timeouts and return the time until the next timeout, in milliseconds */ - static int get_next_timeout(void) - { -- int ret = user_shared_data ? user_shared_data_timeout : -1; -+ /* can't set lower than 1ms, but don't set infinite timeout to workaround misbehaving programs */ -+ int ret = user_shared_data ? 1 : -1; - - if (!list_empty( &abs_timeout_list ) || !list_empty( &rel_timeout_list )) - { -@@ -1019,6 +1038,45 @@ static int get_next_timeout(void) - return ret; - } - -+static void *update_user_shared_data_time_thread(void *param) -+{ -+ struct timespec ts; -+ timeout_t next_update_time; -+ -+ get_current_time(¤t_time, &monotonic_time); -+ next_update_time = monotonic_time + user_shared_data_timeout_ticks; -+ -+ while (active_users) -+ { -+ ticks_to_timespec(next_update_time, &ts); -+ -+ while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL) == EINTR); -+ -+ get_current_time(¤t_time, &monotonic_time); -+ set_user_shared_data_time(current_time, monotonic_time); -+ -+ next_update_time += user_shared_data_timeout_ticks; -+ -+ if (next_update_time <= monotonic_time) -+ next_update_time = monotonic_time + user_shared_data_timeout_ticks; -+ } -+ return NULL; -+} -+ -+static void start_user_shared_data_time_thread(void) -+{ -+ pthread_t pthread; -+ int policy; -+ struct sched_param param; -+ if (pthread_create( &pthread, NULL, update_user_shared_data_time_thread, NULL )) -+ fatal_error( "failed to create time update thread\n" ); -+ if (!pthread_getschedparam( pthread_self(), &policy, ¶m ) && (policy || param.sched_priority)) -+ if (pthread_setschedparam( pthread, policy | SCHED_RESET_ON_FORK, ¶m )) -+ pthread_setschedparam( pthread, policy, ¶m ); -+ pthread_setname_np( pthread, "usd_time_thread" ); -+ pthread_detach( pthread ); -+} -+ - /* server main poll() loop */ - void main_loop(void) - { -@@ -1027,6 +1085,9 @@ void main_loop(void) - set_current_time(); - server_start_time = current_time; - -+ set_user_shared_data_time(current_time, monotonic_time); -+ start_user_shared_data_time_thread(); -+ - main_loop_epoll(); - /* fall through to normal poll loop */ - --- -2.47.0 - diff --git a/0013-server-optimization/0004-time-wait/0008-win32u-Use-fast-user_shared_data-to-check-for-driver.patch b/0013-server-optimization/0004-time-wait/0008-win32u-Use-fast-user_shared_data-to-check-for-driver.patch deleted file mode 100644 index 9728b7c..0000000 --- a/0013-server-optimization/0004-time-wait/0008-win32u-Use-fast-user_shared_data-to-check-for-driver.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 169689879e09c0666f2d9edf55ef2054084bd1b8 Mon Sep 17 00:00:00 2001 -From: William Horvath -Date: Mon, 16 Dec 2024 05:22:34 -0800 -Subject: [PATCH] win32u: Use fast user_shared_data to check for driver updates - at 10khz. - ---- - dlls/win32u/message.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c -index 59ea115d260..48771f74bdf 100644 ---- a/dlls/win32u/message.c -+++ b/dlls/win32u/message.c -@@ -26,6 +26,8 @@ - #endif - - #include -+#include "winternl.h" -+#include "ddk/wdm.h" - #include "ntstatus.h" - #define WIN32_NO_STATUS - #include "win32u_private.h" -@@ -40,6 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg); - WINE_DECLARE_DEBUG_CHANNEL(key); - WINE_DECLARE_DEBUG_CHANNEL(relay); - -+static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000; -+ - #define MAX_WINPROC_RECURSION 64 - - #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE -@@ -3064,9 +3068,7 @@ static HANDLE get_server_queue_handle(void) - /* monotonic timer tick for throttling driver event checks */ - static inline LONGLONG get_driver_check_time(void) - { -- LARGE_INTEGER counter, freq; -- NtQueryPerformanceCounter( &counter, &freq ); -- return counter.QuadPart * 8000 / freq.QuadPart; /* 8kHz */ -+ return user_shared_data->InterruptTime.LowPart / 1000; - } - - /* check for driver events if we detect that the app is not properly consuming messages */ --- -2.47.1 - diff --git a/0013-server-optimization/0004-time-wait/9200-optimize-timegettime.patch b/0013-server-optimization/0004-time-wait/9200-optimize-timegettime.patch deleted file mode 100644 index a5add38..0000000 --- a/0013-server-optimization/0004-time-wait/9200-optimize-timegettime.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/dlls/winmm/time.c b/dlls/winmm/time.c -index 11111111111..11111111111 100644 ---- a/dlls/winmm/time.c -+++ b/dlls/winmm/time.c -@@ -27,6 +27,8 @@ - #include "windef.h" - #include "winbase.h" - #include "mmsystem.h" -+#include "winternl.h" -+#include "ddk/wdm.h" - - #include "winemm.h" - -@@ -34,6 +36,8 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mmtime); - -+static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000; -+ - typedef struct tagWINE_TIMERENTRY { - UINT wDelay; - UINT wResol; -@@ -254,13 +258,7 @@ MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize) - */ - DWORD WINAPI timeGetTime(void) - { -- static LARGE_INTEGER freq; -- LARGE_INTEGER now; -- -- if (!freq.QuadPart) QueryPerformanceFrequency(&freq); -- QueryPerformanceCounter(&now); -- -- return (now.QuadPart * 1000) / freq.QuadPart; -+ return user_shared_data->TickCount.LowPart; - } - - /************************************************************************** diff --git a/0013-server-optimization/0007-priority/0001-server-Implement-thread-priorities-on-Linux.patch b/0013-server-optimization/0007-priority/0001-server-Implement-thread-priorities-on-Linux.patch index 0ec4507..76f3893 100644 --- a/0013-server-optimization/0007-priority/0001-server-Implement-thread-priorities-on-Linux.patch +++ b/0013-server-optimization/0007-priority/0001-server-Implement-thread-priorities-on-Linux.patch @@ -82,9 +82,9 @@ diff --git a/server/thread.c b/server/thread.c index 11111111111..11111111111 100644 --- a/server/thread.c +++ b/server/thread.c -@@ -43,6 +43,12 @@ - #ifdef HAVE_SYS_SYSCALL_H - #include +@@ -37,6 +37,12 @@ + #define _WITH_CPU_SET_T + #include #endif +#ifdef HAVE_SYS_TIME_H +#include @@ -95,7 +95,7 @@ index 11111111111..11111111111 100644 #include "ntstatus.h" #define WIN32_NO_STATUS -@@ -273,6 +279,7 @@ static inline void init_thread_structure( struct thread *thread ) +@@ -257,6 +263,7 @@ static inline void init_thread_structure( struct thread *thread ) thread->state = RUNNING; thread->exit_code = 0; thread->priority = 0; @@ -103,7 +103,7 @@ index 11111111111..11111111111 100644 thread->suspend = 0; thread->dbg_hidden = 0; thread->desktop_users = 0; -@@ -839,9 +846,145 @@ affinity_t get_thread_affinity( struct thread *thread ) +@@ -677,31 +684,151 @@ affinity_t get_thread_affinity( struct thread *thread ) return mask; } @@ -186,7 +186,6 @@ index 11111111111..11111111111 100644 + return 0; +} +#endif -+ + #define THREAD_PRIORITY_REALTIME_HIGHEST 6 #define THREAD_PRIORITY_REALTIME_LOWEST -7 @@ -245,11 +244,9 @@ index 11111111111..11111111111 100644 + return 0; /* ignore errors for now */ +} + -+ - #define MAX_THREAD_NAME_LENGTH 16 - #define MAX_RETRIES 5 - #define RETRY_DELAY_US 1000 -@@ -921,22 +1064,8 @@ static void set_thread_info( struct thread *thread, + /* set all information about a thread */ + static void set_thread_info( struct thread *thread, + const struct set_thread_info_request *req ) { if (req->mask & SET_THREAD_INFO_PRIORITY) { @@ -274,7 +271,7 @@ index 11111111111..11111111111 100644 } if (req->mask & SET_THREAD_INFO_AFFINITY) { -@@ -1862,6 +1991,7 @@ DECL_HANDLER(init_thread) +@@ -1584,6 +1711,7 @@ DECL_HANDLER(init_thread) init_thread_context( current ); generate_debug_event( current, DbgCreateThreadStateChange, &req->entry ); diff --git a/0013-server-optimization/0007-priority/0002-server-Fallback-to-RTKIT-for-thread-priorities.patch b/0013-server-optimization/0007-priority/0002-server-Fallback-to-RTKIT-for-thread-priorities.patch index 1ae9a39..79397fd 100644 --- a/0013-server-optimization/0007-priority/0002-server-Fallback-to-RTKIT-for-thread-priorities.patch +++ b/0013-server-optimization/0007-priority/0002-server-Fallback-to-RTKIT-for-thread-priorities.patch @@ -28,9 +28,9 @@ index 11111111111..11111111111 100644 wineserver.man.in \ winstation.c --UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(PTHREAD_LIBS) +-UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) +UNIX_CFLAGS = $(DBUS_CFLAGS) -+UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(PTHREAD_LIBS) $(DBUS_LIBS) ++UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(DBUS_LIBS) unicode_EXTRADEFS = -DBINDIR="\"${bindir}\"" -DDATADIR="\"${datadir}\"" diff --git a/server/thread.c b/server/thread.c diff --git a/0015-bernhard-asan/0028-include-Terminate-buffer-in-wine_dbg_vsprintf.patch b/0015-bernhard-asan/0028-include-Terminate-buffer-in-wine_dbg_vsprintf.patch new file mode 100644 index 0000000..04fe91b --- /dev/null +++ b/0015-bernhard-asan/0028-include-Terminate-buffer-in-wine_dbg_vsprintf.patch @@ -0,0 +1,88 @@ +From 39a8d5a692688e7f3f712f7227931f3bab384aeb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 22:45:47 +0100 +Subject: [PATCH 28/86] include: Terminate buffer in wine_dbg_vsprintf. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M oleaut32.dll -p dlls/oleaut32/tests/x86_64-windows/oleaut32_test.exe vartest && touch dlls/oleaut32/tests/x86_64-windows/vartest.ok +================================================================= +==1688==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fe748 at pc 0x6ffff88f06e9 bp 0x7ffffe1fdd70 sp 0x7ffffe1fddb8 +READ of size 201 at 0x7ffffe1fe748 thread T0 +050c:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff88f06e8 in strlen /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:425:5 + #1 0x6ffff82eca6d in __wine_dbg_strdup /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\thread.c:128:16 + #2 0x000140207700 in wine_dbg_vsprintf /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:138:12 + #3 0x000140207700 in wine_dbg_sprintf /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:148:11 + #4 0x000140207293 in wine_dbgstr_variant /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h + #5 0x000140208cda in test_var_call2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/oleaut32/tests/vartest.c:543:53 + #6 0x00014018396d in test_VarSub /home/bernhard/data/entwicklung/2024/wine\wine/dlls/oleaut32/tests/vartest.c:3332:5 + #7 0x00014018396d in func_vartest /home/bernhard/data/entwicklung/2024/wine\wine/dlls/oleaut32/tests/vartest.c:9767:3 + #8 0x0001402a1e63 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #9 0x0001402a1e63 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #10 0x0001402a3d8f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #11 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #12 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fe748 is located in stack of thread T0 at offset 232 in frame + #0 0x0001402075cf in wine_dbg_sprintf /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:143 + + This frame has 2 object(s): + [32, 232) 'buffer.i' (line 135) + [304, 312) 'args' (line 145) <== Memory access at offset 232 partially underflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\thread.c:128:16 in __wine_dbg_strdup +Shadow bytes around the buggy address: + 0x7ffffe1fe480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe600: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1fe680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fe700: 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 + 0x7ffffe1fe780: f2 f2 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 + 0x7ffffe1fe800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe880: 00 00 00 00 f1 f1 f1 f1 00 00 00 f2 f2 f2 f2 f2 + 0x7ffffe1fe900: 00 00 00 f2 f2 f2 f2 f2 00 00 00 f3 f3 f3 f3 f3 + 0x7ffffe1fe980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1688==ABORTING +050c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:312775: dlls/oleaut32/tests/x86_64-windows/vartest.ok] Fehler 1 +--- + include/wine/debug.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/wine/debug.h b/include/wine/debug.h +index 3e0912de801..fd1345fbd33 100644 +--- a/include/wine/debug.h ++++ b/include/wine/debug.h +@@ -134,7 +134,8 @@ static inline const char * __wine_dbg_cdecl wine_dbg_vsprintf( const char *forma + { + char buffer[200]; + +- vsnprintf( buffer, sizeof(buffer), format, args ); ++ vsnprintf( buffer, sizeof(buffer) - 1, format, args ); ++ buffer[sizeof(buffer) - 1] = '\0'; + return __wine_dbg_strdup( buffer ); + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0029-crypt32-tests-str-wine_dbgstr_a-wine_dbgstr_an.-ASan.patch b/0015-bernhard-asan/0029-crypt32-tests-str-wine_dbgstr_a-wine_dbgstr_an.-ASan.patch new file mode 100644 index 0000000..e214410 --- /dev/null +++ b/0015-bernhard-asan/0029-crypt32-tests-str-wine_dbgstr_a-wine_dbgstr_an.-ASan.patch @@ -0,0 +1,80 @@ +From 2fe5b0659ed00e4144f2d71c639555099d58a7ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 11:18:08 +0100 +Subject: [PATCH 29/86] crypt32/tests: str: wine_dbgstr_a - wine_dbgstr_an. + (ASan) + +================================================================= +==1288==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fd790 at pc 0x00014015a789 bp 0x7ffffe1fcce0 sp 0x7ffffe1fcd28 +READ of size 1 at 0x7ffffe1fd790 thread T0 +04f4:fixme:dbghelp:elf_search_auxv can't find symbol in module +04f4:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007EBA5AE30B80,symt:0000000000000000) in ctx(00007EBA5CBC18E0,L"crypt32_test") + #0 0x00014015a788 in wine_dbgstr_an Z:\home\bernhard\data\entwicklung\2024\wine\wine\include\wine\debug.h:218 + #1 0x000140159ec9 in test_NameToStrConversionA_ Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:482 + #2 0x000140152699 in func_str Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:1228 + #3 0x00014015ec41 in main+0x541 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\crypt32\tests\x86_64-windows\crypt32_test.exe+0x14015ec41) + #4 0x000140160b4f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #5 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #6 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fd790 is located in stack of thread T0 at offset 2032 in frame + #0 0x0001401596ff in test_NameToStrConversionA_ Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:464 + + This frame has 1 object(s): + [32, 2032) 'buffer' (line 465) <== Memory access at offset 2032 overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\include\wine\debug.h:218 in wine_dbgstr_an +Shadow bytes around the buggy address: + 0x7ffffe1fd500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fd780: 00 00[f3]f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 + 0x7ffffe1fd800: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd900: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1fd980: f8 f2 f8 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fda00: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1288==ABORTING +make: *** [Makefile:37447: dlls/crypt32/tests/x86_64-windows/str.ok] Fehler 1 +--- + dlls/crypt32/tests/str.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c +index 1f65234f400..9ce1821e2b6 100644 +--- a/dlls/crypt32/tests/str.c ++++ b/dlls/crypt32/tests/str.c +@@ -479,7 +479,7 @@ static void test_NameToStrConversionA_(unsigned int line, PCERT_NAME_BLOB pName, + memset(buffer, 0xcc, sizeof(buffer)); + retlen = CertNameToStrA(X509_ASN_ENCODING, pName, dwStrType, buffer, 0); + ok(retlen == len, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); +- ok((unsigned char)buffer[0] == 0xcc, "line %u: got %s\n", line, wine_dbgstr_a(buffer)); ++ ok((unsigned char)buffer[0] == 0xcc, "line %u: got %s\n", line, wine_dbgstr_an(buffer, ARRAY_SIZE(buffer))); + } + + static BYTE encodedSimpleCN[] = { +-- +2.47.1 + diff --git a/0015-bernhard-asan/0030-crypt32-tests-wine_dbgstr_w-wine_dbgstr_wn.-ASan.patch b/0015-bernhard-asan/0030-crypt32-tests-wine_dbgstr_w-wine_dbgstr_wn.-ASan.patch new file mode 100644 index 0000000..61d28f9 --- /dev/null +++ b/0015-bernhard-asan/0030-crypt32-tests-wine_dbgstr_w-wine_dbgstr_wn.-ASan.patch @@ -0,0 +1,81 @@ +From 43c6109aac798f15944788f98d7f626daa0e94bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 11:21:12 +0100 +Subject: [PATCH 30/86] crypt32/tests: wine_dbgstr_w - wine_dbgstr_wn. (ASan) + +crypt32:str + +================================================================= +==1600==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fd780 at pc 0x0001401592ee bp 0x7ffffe1fc500 sp 0x7ffffe1fc548 +READ of size 2 at 0x7ffffe1fd780 thread T0 +063c:fixme:dbghelp:elf_search_auxv can't find symbol in module +063c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F18BABF0B80,symt:0000000000000000) in ctx(00007F18BC9818E0,L"crypt32_test") + #0 0x0001401592ed in wine_dbgstr_wn Z:\home\bernhard\data\entwicklung\2024\wine\wine\include\wine\debug.h:262 + #1 0x00014015b2b6 in test_NameToStrConversionW_ Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:646 + #2 0x000140152ee8 in func_str Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:1228 + #3 0x00014015ec41 in main+0x541 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\crypt32\tests\x86_64-windows\crypt32_test.exe+0x14015ec41) + #4 0x000140160b4f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #5 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #6 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fd780 is located in stack of thread T0 at offset 4032 in frame + #0 0x00014015a9af in test_NameToStrConversionW_ Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\tests\str.c:624 + + This frame has 1 object(s): + [32, 4032) 'buffer' (line 626) <== Memory access at offset 4032 overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\include\wine\debug.h:262 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1fd500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fd780:[f3]f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 + 0x7ffffe1fd800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd900: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1fd980: f8 f2 f8 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fda00: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1600==ABORTING +make: *** [Makefile:37447: dlls/crypt32/tests/x86_64-windows/str.ok] Fehler 1 +--- + dlls/crypt32/tests/str.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c +index 9ce1821e2b6..589e6de2463 100644 +--- a/dlls/crypt32/tests/str.c ++++ b/dlls/crypt32/tests/str.c +@@ -643,7 +643,7 @@ static void test_NameToStrConversionW_(unsigned int line, PCERT_NAME_BLOB pName, + memset(buffer, 0xcc, sizeof(buffer)); + retlen = CertNameToStrW(X509_ASN_ENCODING, pName, dwStrType, buffer, 0); + ok(retlen == len, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); +- ok(buffer[0] == 0xcccc, "line %u: got %s\n", line, wine_dbgstr_w(buffer)); ++ ok(buffer[0] == 0xcccc, "line %u: got %s\n", line, wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer))); + } + + static void test_CertNameToStrW(void) +-- +2.47.1 + diff --git a/0015-bernhard-asan/0031-imm32-tests-debugstr_w-debugstr_wn.patch b/0015-bernhard-asan/0031-imm32-tests-debugstr_w-debugstr_wn.patch new file mode 100644 index 0000000..36c3e8c --- /dev/null +++ b/0015-bernhard-asan/0031-imm32-tests-debugstr_w-debugstr_wn.patch @@ -0,0 +1,87 @@ +From c862f7fc1570ceb0d22ae675434ed06903359bf9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Fri, 6 Dec 2024 16:36:58 +0100 +Subject: [PATCH 31/86] imm32/tests: debugstr_w - debugstr_wn + +imm32:imm32 + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/imm32/tests/x86_64-windows/imm32_test.exe imm32 +... +imm32.c:3214: Test marked todo: unexpected call ImeDestroy +0024:fixme:imm:ImeEscape himc 0000000000000000, escape 0, data 0000000000000000 stub! +0024:fixme:imm:ImeEscape himc 0000000000000000, escape 0, data 0000000000000000 stub! +================================================================= +==32==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1f7de0 at pc 0x000140082d41 bp 0x7ffffe1f76a0 sp 0x7ffffe1f76e8 +READ of size 2 at 0x7ffffe1f7de0 thread T0 +012c:fixme:file:server_get_file_info Unsupported info class e + #0 0x000140082d40 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x000140082d40 in debugstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:521:65 + #2 0x0001400422fe in test_ImmEscape /home/bernhard/data/entwicklung/2024/wine\wine/dlls/imm32/tests/imm32.c:4205:74 + #3 0x00014000c199 in func_imm32 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/imm32/tests/imm32.c:8071:5 + #4 0x00014009bff3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00014009ba3b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #6 0x00014009d96f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1f7de0 is located in stack of thread T0 at offset 1056 in frame + #0 0x000140040f8f in test_ImmEscape /home/bernhard/data/entwicklung/2024/wine\wine/dlls/imm32/tests/imm32.c:4146 + + This frame has 2 object(s): + [32, 1056) 'bufferW' (line 4159) <== Memory access at offset 1056 overflows this variable + [1184, 1696) 'bufferA' (line 4160) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1f7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1f7d80: 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2 + 0x7ffffe1f7e00: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 + 0x7ffffe1f7e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f7f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f8000: 00 00 00 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==32==ABORTING +--- + dlls/imm32/tests/imm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c +index db73463ef49..6e50e614b6b 100644 +--- a/dlls/imm32/tests/imm32.c ++++ b/dlls/imm32/tests/imm32.c +@@ -4202,7 +4202,7 @@ static void test_ImmEscape( BOOL unicode ) + } + else + { +- ok( !memcmp( bufferW, "ImeEscape", 10 ), "got bufferW %s\n", debugstr_w(bufferW) ); ++ ok( !memcmp( bufferW, "ImeEscape", 10 ), "got bufferW %s\n", debugstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); + ok_eq( 0xcdcd, bufferW[5], WORD, "%#x" ); + } + CHECK_CALLED( ImeEscape ); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0032-kernel32-tests-locale-debugstr_w-debugstr_wn.patch b/0015-bernhard-asan/0032-kernel32-tests-locale-debugstr_w-debugstr_wn.patch new file mode 100644 index 0000000..f2ea626 --- /dev/null +++ b/0015-bernhard-asan/0032-kernel32-tests-locale-debugstr_w-debugstr_wn.patch @@ -0,0 +1,89 @@ +From f00087b24d33a17502f111079f005085ccbc67b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 4 Dec 2024 22:46:55 +0100 +Subject: [PATCH 32/86] kernel32/tests: locale: debugstr_w - debugstr_wn. + +kernel32_test.exe locale + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/kernel32/tests/x86_64-windows/kernel32_test.exe locale +... +================================================================= +==1628==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1f4090 at pc 0x0001402ca8ce bp 0x7ffffe1f3a80 sp 0x7ffffe1f3ac8 +READ of size 2 at 0x7ffffe1f4090 thread T0 +0670:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001402ca8cd in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x0001402adb10 in debugstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:521:65 + #2 0x0001402adb10 in test_LocaleNameToLCID /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:3256:53 + #3 0x00014027ae4b in func_locale /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:8699:3 + #4 0x0001404d7f01 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001404d7f01 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001404d9eef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1f4090 is located in stack of thread T0 at offset 784 in frame + #0 0x0001402a89df in test_LocaleNameToLCID /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:2946 + + This frame has 7 object(s): + [32, 36) 'lcid' (line 2947) + [48, 218) 'buffer' (line 2950) + [288, 458) 'expbuff' (line 2951) + [528, 784) 'buffer627' (line 3175) <== Memory access at offset 784 overflows this variable + [848, 1104) 'expect628' (line 3175) + [1168, 1184) 'str' (line 3176) + [1200, 1204) 'lcid1012' (line 3271) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1f3e00: 00 00 00 00 00 00 00 00 00 00 00 02 f2 f2 f2 f2 + 0x7ffffe1f3e80: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f3f00: 00 00 00 00 00 00 00 00 00 02 f2 f2 f2 f2 f2 f2 + 0x7ffffe1f3f80: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f4000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1f4080: 00 00[f2]f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 + 0x7ffffe1f4100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f4180: 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 + 0x7ffffe1f4200: f2 f2 00 00 f2 f2 f8 f3 00 00 00 00 00 00 00 00 + 0x7ffffe1f4280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f4300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1628==ABORTING +--- + dlls/kernel32/tests/locale.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c +index 625a2ceac2b..8681736a4cc 100644 +--- a/dlls/kernel32/tests/locale.c ++++ b/dlls/kernel32/tests/locale.c +@@ -3253,7 +3253,7 @@ static void test_LocaleNameToLCID(void) + ok( status == STATUS_BUFFER_TOO_SMALL, "wrong error %lx\n", status ); + ok( str.Length == 0xbeef, "wrong len %u\n", str.Length ); + ok( str.MaximumLength == 5 * sizeof(WCHAR), "wrong len %u\n", str.MaximumLength ); +- ok( buffer[0] == 0xcccc, "wrong name %s\n", debugstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "wrong name %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer)) ); + + memset( &str, 0xcc, sizeof(str) ); + status = pRtlLcidToLocaleName( MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &str, 0, 1 ); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0033-kernel32-tests-locale-debugstr_w-debugstr_wn.patch b/0015-bernhard-asan/0033-kernel32-tests-locale-debugstr_w-debugstr_wn.patch new file mode 100644 index 0000000..e62f922 --- /dev/null +++ b/0015-bernhard-asan/0033-kernel32-tests-locale-debugstr_w-debugstr_wn.patch @@ -0,0 +1,199 @@ +From e91f435f305e72c86c6f8a1744d61303717ae932 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 4 Dec 2024 22:49:20 +0100 +Subject: [PATCH 33/86] kernel32/tests: locale: debugstr_w - debugstr_wn. + +kernel32_test.exe locale + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/kernel32/tests/x86_64-windows/kernel32_test.exe locale +... +================================================================= +==1748==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1f58da at pc 0x0001402ca8ce bp 0x7ffffe1f4000 sp 0x7ffffe1f4048 +READ of size 2 at 0x7ffffe1f58da thread T0 +06e8:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001402ca8cd in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x00014028a4d3 in debugstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:521:65 + #2 0x00014028a4d3 in test_ResolveLocaleName /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:6042:60 + #3 0x00014028a4d3 in func_locale /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:8714:3 + #4 0x0001404d7f01 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001404d7f01 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001404d9eef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1f58da is located in stack of thread T0 at offset 5434 in frame + #0 0x000140264a7f in func_locale /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:8664 + + This frame has 117 object(s): + [32, 1032) 'buffer.i3963' (line 3811) + [1168, 2168) 'buff1.i' (line 3819) + [2304, 3304) 'buff2.i' (line 3820) + [3440, 3696) 'buf.i3926' (line 3442) + [3760, 3824) 'reg_name.i' (line 8219) + [3856, 3920) 'buf.i3810' (line 8219) + [3952, 4016) 'set_name.i' (line 8219) + [4048, 4112) 'nation.i' (line 8219) + [4144, 4208) 'region.i' (line 8219) + [4240, 4244) 'size.i3811' (line 8221) + [4256, 4260) 'type.i3812' (line 8221) + [4272, 4280) 'key.i3813' (line 8225) + [4304, 4312) 'addr.i' (line 8171) + [4336, 4344) 'addr2.i' (line 8171) + [4368, 4372) 'lcid.i3591' (line 8173) + [4384, 4392) 'size.i3592' (line 8174) + [4416, 4432) 'src.i3515' (line 7722) + [4448, 4464) 'buffer.i3516' (line 7722) + [4480, 4484) 'found.i' (line 7093) + [4496, 4500) 'count.i3040' (line 6876) + [4512, 4516) 'size.i3041' (line 6876) + [4528, 4532) 'size_id.i3042' (line 6876) + [4544, 4548) 'size_name.i' (line 6876) + [4560, 4564) 'count.i' (line 6800) + [4576, 4580) 'size.i' (line 6800) + [4592, 4596) 'size_id.i' (line 6800) + [4608, 4736) 'buffer.i2658' (line 6505) + [4768, 4788) 'buffA.i' (line 6158) + [4832, 4872) 'buffW.i' (line 6159) + [4912, 4922) 'test1.i' (line 6071) + [4944, 4954) 'test2.i' (line 6072) + [4976, 4988) 'test3.i' (line 6073) + [5008, 5016) 'null1.i' (line 6074) + [5040, 5048) 'null2.i' (line 6075) + [5072, 5086) 'bills1.i' (line 6076) + [5104, 5116) 'bills2.i' (line 6077) + [5136, 5148) 'coop1.i' (line 6078) + [5168, 5178) 'coop2.i' (line 6079) + [5200, 5204) 'nonascii1.i' (line 6080) + [5216, 5220) 'nonascii2.i' (line 6081) + [5232, 5234) 'ch1.i' (line 6082) + [5248, 5250) 'ch2.i' (line 6082) + [5264, 5434) 'buffer.i2117' (line 6021) <== Memory access at offset 5434 overflows this variable + [5504, 5674) 'system.i' (line 6021) + [5744, 9776) 'test_data.i282.i' (line 5661) + [9904, 11952) 'buf.i283.i' (line 5690) + [12080, 16448) 'test_data.i253.i' (line 5616) + [16704, 18752) 'buf.i254.i' (line 5645) + [18880, 25760) 'test_data.i.i' (line 5498) + [26016, 28064) 'buf.i.i' (line 5537) + [28192, 28196) 'len.i.i' (line 5604) + [28208, 30256) 'buffer.i1771' (line 5740) + [30384, 33968) 'columns.i' (line 5741) + [34096, 34608) 'dst.i1772' (line 5741) + [34672, 34712) 'types.i' (line 5378) + [34752, 34756) 'ch.i' (line 5379) + [34768, 34928) 'buffer.i1615' (line 4763) + [34992, 34994) 'type.i' (line 4060) + [35008, 35520) 'src.i1064' (line 4062) + [35584, 36096) 'dst.i1065' (line 4062) + [36160, 36162) 'wch.i' (line 4289) + [36176, 36432) 'src.i' (line 3851) + [36496, 36752) 'dst.i' (line 3851) + [36816, 37328) 'buf.i957' (line 2879) + [37392, 37904) 'buf.i940' (line 2854) + [37968, 38224) 'buf.i833' (line 2347) + [38288, 38544) 'buf2.i' (line 2347) + [38608, 38620) 'locale.i804' (line 2294) + [38640, 38688) 'si.i' (line 2056) + [38720, 38724) 'old_prot.i' (line 2057) + [38736, 38992) 'a.i' (line 1904) + [39056, 39340) 'cpinfo.i' (line 1906) + [39408, 39448) 'format.i567' (line 1653) + [39488, 39744) 'buffer.i568' (line 1659) + [39808, 39872) 'grouping.i' (line 1411) + [39904, 39920) 't1000.i' (line 1411) + [39936, 39952) 'dec.i' (line 1411) + [39968, 39984) 'frac.i' (line 1411) + [40000, 40016) 'lzero.i' (line 1411) + [40032, 40160) 'buffer.i484' (line 1412) + [40192, 40232) 'format.i485' (line 1413) + [40272, 40400) 'buffer.i435' (line 1238) + [40432, 40480) 'format.i' (line 1239) + [40512, 40528) 'curtime.i402' (line 1128) + [40544, 40800) 'buffer.i403' (line 1129) + [40864, 40880) 'curtime.i367' (line 1040) + [40896, 41152) 'buffer.i368' (line 1041) + [41216, 41232) 'curtime.i300' (line 895) + [41248, 41376) 'buffer.i301' (line 899) + [41408, 41536) 'Expected.i' (line 899) + [41568, 41578) 'short_day.i' (line 900) + [41600, 41610) 'month.i' (line 900) + [41632, 41642) 'genitive_month.i' (line 900) + [41664, 41680) 'curtime.i234' (line 723) + [41696, 41952) 'buffer.i235' (line 724) + [42016, 42032) 'curtime.i' (line 535) + [42048, 42176) 'buffer.i197' (line 537) + [42208, 42368) 'bufferW.i151' (line 5814) + [42432, 42592) 'buffer2.i' (line 5814) + [42656, 42660) 'val.i152' (line 5833) + [42672, 42832) 'bufferW.i' (line 394) + [42896, 43056) 'buffer2W.i' (line 394) + [43120, 43200) 'bufferA.i' (line 395) + [43232, 43236) 'val.i114' (line 396) + [43248, 43376) 'buffer.i77' (line 265) + [43408, 43536) 'expected.i' (line 266) + [43568, 43572) 'val.i' (line 267) + [43584, 43840) 'buf.i49' (line 4906) + [43904, 44416) 'bufW.i' (line 5014) + [44480, 44736) 'buf.i22' (line 5039) + [44800, 45056) 'buf.i' (line 4986) + [45120, 45376) 'data.i' (line 8584) + [45440, 45610) 'locale.i' (line 8585) + [45680, 45936) 'key.i' (line 8586) + [46000, 46008) 'end.i' (line 8588) + [46032, 47056) 'buffer.i' (line 8588) + [47184, 47192) 'argv' (line 8665) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1f5600: f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 + 0x7ffffe1f5680: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f2 f2 f8 f8 + 0x7ffffe1f5700: f2 f2 f8 f8 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f8 + 0x7ffffe1f5780: f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f8 f2 f2 f8 f2 + 0x7ffffe1f5800: f8 f2 f8 f2 f8 f2 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1f5880: 00 00 00 00 00 00 00 00 00 00 00[02]f2 f2 f2 f2 + 0x7ffffe1f5900: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f5980: 00 00 00 00 00 00 00 00 00 02 f2 f2 f2 f2 f2 f2 + 0x7ffffe1f5a00: f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1f5a80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1f5b00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1748==ABORTING +--- + dlls/kernel32/tests/locale.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c +index 8681736a4cc..2911513a90e 100644 +--- a/dlls/kernel32/tests/locale.c ++++ b/dlls/kernel32/tests/locale.c +@@ -6039,7 +6039,7 @@ static void test_ResolveLocaleName(void) + else + { + ok( !ret || broken( ret == 1 ) /* win7 */, +- "%s: got %s\n", debugstr_w(tests[i].name), debugstr_w(buffer) ); ++ "%s: got %s\n", debugstr_w(tests[i].name), debugstr_wn(buffer, ARRAY_SIZE(buffer)) ); + if (!ret) + ok( GetLastError() == ERROR_INVALID_PARAMETER, + "%s: wrong error %lu\n", debugstr_w(tests[i].name), GetLastError() ); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0034-kernel32-tests-locale-lstrlenW-wcsnlen-wine_dbgstr_w.patch b/0015-bernhard-asan/0034-kernel32-tests-locale-lstrlenW-wcsnlen-wine_dbgstr_w.patch new file mode 100644 index 0000000..3fc2cce --- /dev/null +++ b/0015-bernhard-asan/0034-kernel32-tests-locale-lstrlenW-wcsnlen-wine_dbgstr_w.patch @@ -0,0 +1,96 @@ +From fd1ccdc108c24eed3ad58ea159a16297f6128111 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 4 Dec 2024 22:58:46 +0100 +Subject: [PATCH 34/86] kernel32/tests: locale: lstrlenW - wcsnlen / + wine_dbgstr_w - wine_dbgstr_wn. + +kernel32_test.exe locale + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/kernel32/tests/x86_64-windows/kernel32_test.exe locale +... +================================================================= +==1772==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1d1b40 at pc 0x0001402c22a7 bp 0x7ffffe1d17e0 sp 0x7ffffe1d1828 +READ of size 2 at 0x7ffffe1d1b40 thread T0 +0700:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001402c22a6 in lstrlenW /home/bernhard/data/entwicklung/2024/wine\wine/include/winbase.h:2920:12 + #1 0x0001402c22a6 in test_NormalizeString /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:7401:54 + #2 0x000140295848 in func_locale /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:8725:3 + #3 0x0001404d7f01 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001404d7f01 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #5 0x0001404d9eef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1d1b40 is located in stack of thread T0 at offset 608 in frame + #0 0x0001402bbe3f in test_NormalizeString /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/locale.c:7212 + + This frame has 10 object(s): + [32, 40) 'end.i2278' (line 7198) + [64, 72) 'end.i' (line 7198) + [96, 608) 'dst' (line 7358) <== Memory access at offset 608 overflows this variable + [672, 673) 'ret' (line 7359) + [688, 692) 'dstlen' (line 7361) + [704, 1728) 'buffer' (line 7620) + [1856, 1862) 'str745' (line 7621) + [1888, 1952) 'srcW' (line 7621) + [1984, 2048) 'dstW' (line 7621) + [2080, 2336) 'resW' (line 7621) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/winbase.h:2920:12 in lstrlenW +Shadow bytes around the buggy address: + 0x7ffffe1d1880: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1d1900: f8 f2 f2 f2 f8 f2 f2 f2 00 00 00 00 00 00 00 00 + 0x7ffffe1d1980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1d1a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1d1a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1d1b00: 00 00 00 00 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1d1b80: 01 f2 04 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1d1c00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1d1c80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1d1d00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1d1d80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1772==ABORTING +--- + dlls/kernel32/tests/locale.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c +index 2911513a90e..b95e2788ce9 100644 +--- a/dlls/kernel32/tests/locale.c ++++ b/dlls/kernel32/tests/locale.c +@@ -7398,10 +7398,10 @@ static void test_NormalizeString(void) + memset(dst, 0xcc, sizeof(dst)); + dstlen = pNormalizeString( norm_forms[i], ptest->str, lstrlenW(ptest->str), dst, dstlen ); + ok(dstlen == lstrlenW( ptest->expected[i] ), "%s:%d: Copied length differed: was %d, should be %d\n", +- wine_dbgstr_w(ptest->str), i, dstlen, lstrlenW( dst )); ++ wine_dbgstr_w(ptest->str), i, dstlen, (int)wcsnlen( dst, ARRAY_SIZE(dst) )); + str_cmp = wcsncmp( ptest->expected[i], dst, dstlen ); + ok( str_cmp == 0, "%s:%d: string incorrect got %s expect %s\n", wine_dbgstr_w(ptest->str), i, +- wine_dbgstr_w(dst), wine_dbgstr_w(ptest->expected[i]) ); ++ wine_dbgstr_wn(dst, ARRAY_SIZE(dst)), wine_dbgstr_wn(ptest->expected[i], ARRAY_SIZE(&ptest->expected[i])) ); + + if (pRtlNormalizeString) + { +-- +2.47.1 + diff --git a/0015-bernhard-asan/0035-kernel32-tests-actctx-wine_dbgstr_w-wine_dbgstr_wn.patch b/0015-bernhard-asan/0035-kernel32-tests-actctx-wine_dbgstr_w-wine_dbgstr_wn.patch new file mode 100644 index 0000000..3d7b551 --- /dev/null +++ b/0015-bernhard-asan/0035-kernel32-tests-actctx-wine_dbgstr_w-wine_dbgstr_wn.patch @@ -0,0 +1,236 @@ +From 61a1c68ef4b37c9f7f9b39d4fceb35dcbd5bd4b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 15:55:58 +0100 +Subject: [PATCH 35/86] kernel32/tests: actctx: wine_dbgstr_w - wine_dbgstr_wn. + +================================================================= +==1356==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1f9a00 at pc 0x000140020e71 bp 0x7ffffe1f9580 sp 0x7ffffe1f95c8 +READ of size 2 at 0x7ffffe1f9a00 thread T0 +0790:fixme:file:server_get_file_info Unsupported info class e + #0 0x000140020e70 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x00014000b78f in wine_dbgstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:305:12 + #2 0x00014000b78f in test_settings /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/actctx.c:3432:42 + #3 0x00014000b78f in func_actctx /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/actctx.c:4436:5 + #4 0x0001404d7f21 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001404d7f21 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001404d9f0f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1f9a00 is located in stack of thread T0 at offset 192 in frame + #0 0x00014000100f in func_actctx /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/actctx.c:4399 + + This frame has 69 object(s): + [32, 192) 'buffer.i377' (line 3396) <== Memory access at offset 192 overflows this variable + [256, 264) 'size.i378' (line 3397) + [288, 356) 'buffer.i' (line 3278) + [400, 408) 'size.i' (line 3279) + [432, 692) 'cmdline.i' (line 2697) + [768, 1028) 'path.i289' (line 2698) + [1104, 1112) 'argv.i' (line 2699) + [1136, 1160) 'pi.i' (line 2700) + [1200, 1304) 'si.i' (line 2701) + [1344, 1352) 'now.i' (line 2703) + [1376, 1392) 'basicinfo.i' (line 3102) + [1408, 1416) 'cookie.i259' (line 3103) + [1440, 1448) 'current.i' (line 3104) + [1472, 1480) 'cookie.i' (line 2666) + [1504, 2024) 'tmp_path.i.i' (line 646) + [2160, 2164) 'size.i.i' (line 647) + [2176, 2696) 'tmp_manifest_pathname.i' (line 3065) + [2832, 2888) 'actctx.i185' (line 3067) + [2928, 3188) 'path.i736.i' (line 2774) + [3264, 3524) 'path.i732.i' (line 2774) + [3600, 3860) 'path.i646.i' (line 2774) + [3936, 4196) 'path.i642.i' (line 2774) + [4272, 4532) 'path.i.i143' (line 2774) + [4608, 4868) 'path.i144' (line 2814) + [4944, 5204) 'dir.i' (line 2814) + [5280, 5540) 'dll.i' (line 2814) + [5616, 5876) 'source.i' (line 2814) + [5952, 6472) 'pathW.i' (line 2815) + [6608, 7128) 'dirW.i' (line 2815) + [7264, 7784) 'sourceW.i' (line 2815) + [7920, 7976) 'actctx.i145' (line 2816) + [8016, 8072) 'ctxW.i' (line 2817) + [8112, 8168) 'actctx.i.i' (line 1125) + [8208, 8728) 'path.i.i' (line 1127) + [8864, 8920) 'actctx.i' (line 1145) + [8960, 9480) 'path.i' (line 1147) + [9616, 10640) 'manifest_exe.i.i' (line 4186) + [10768, 11792) 'manifest_dll.i.i' (line 4186) + [11920, 12090) 'locale_name.i.i' (line 4187) + [12160, 12170) 'langs_arr.i.i' (line 4188) + [12192, 12336) 'specs.i.i' (line 4217) + [12400, 12920) 'pathbuf.i' (line 4349) + [13056, 13112) 'ctx.i52' (line 4351) + [13152, 13208) 'ctx.i' (line 4330) + [13248, 13520) 'path_manifest.i.i' (line 3792) + [13584, 13844) 'path_tmp.i131.i' (line 3793) + [13920, 14180) 'path_msvcp.i.i' (line 3795) + [14256, 14516) 'path_msvcr.i.i' (line 3795) + [14592, 14648) 'context.i.i' (line 3796) + [14688, 14696) 'cookie.i132.i' (line 3797) + [14720, 15888) 'dll.i106.i' (line 3753) + [16016, 16287) 'path_dll_local.i107.i' (line 3754) + [16352, 16612) 'path_tmp.i.i' (line 3755) + [16688, 17856) 'dll.i29.i' (line 3712) + [17984, 18255) 'path_dll_local.i30.i' (line 3713) + [18320, 18580) 'path_application.i31.i' (line 3714) + [18656, 18916) 'path1.i32.i' (line 3716) + [18992, 19252) 'path2.i33.i' (line 3716) + [19328, 20496) 'dll.i.i' (line 3672) + [20624, 20895) 'path_dll_local.i.i' (line 3673) + [20960, 21220) 'path_application.i.i' (line 3674) + [21296, 21556) 'path1.i5.i' (line 3676) + [21632, 21892) 'path2.i6.i' (line 3676) + [21968, 23136) 'dll_1.i.i' (line 3644) + [23264, 24432) 'dll_2.i.i' (line 3645) + [24560, 24820) 'path1.i.i' (line 3646) + [24896, 25156) 'path2.i.i' (line 3646) + [25232, 25240) 'handle.i' (line 2557) + [25264, 25272) 'argv' (line 4401) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1f9780: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f9800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f9880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1f9900: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 + 0x7ffffe1f9980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1f9a00:[f2]f2 f2 f2 f2 f2 f2 f2 00 f2 f2 f2 f8 f8 f8 f8 + 0x7ffffe1f9a80: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f2 f2 f2 f8 f8 + 0x7ffffe1f9b00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1f9b80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 + 0x7ffffe1f9c00: f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1f9c80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1356==ABORTING +0790:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:200848: dlls/kernel32/tests/x86_64-windows/actctx.ok] Fehler 1 +--- + dlls/kernel32/tests/actctx.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c +index b6f43b12f1a..a51c3c8db8b 100644 +--- a/dlls/kernel32/tests/actctx.c ++++ b/dlls/kernel32/tests/actctx.c +@@ -3421,7 +3421,7 @@ static void test_settings(void) + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, NULL, dpiAwareW, buffer, 80, &size ); + ok( ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == lstrlenW( buffer ) + 1, "wrong len %Iu\n", size ); + SetLastError( 0xdeadbeef ); + size = 0xdead; +@@ -3429,20 +3429,20 @@ static void test_settings(void) + ret = pQueryActCtxSettingsW( 0, handle, NULL, dummyW, buffer, 80, &size ); + ok( !ret, "QueryActCtxSettingsW succeeded\n" ); + ok( GetLastError() == ERROR_SXS_KEY_NOT_FOUND, "wrong error %lu\n", GetLastError() ); +- ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, namespace2005W, dpiAwareW, buffer, 80, &size ); + ok( ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == ARRAY_SIZE(trueW), "wrong len %Iu\n", size ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, namespace2005W, dpiAwareW, buffer, lstrlenW(trueW) + 1, &size ); + ok( ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == ARRAY_SIZE(trueW), "wrong len %Iu\n", size ); + SetLastError( 0xdeadbeef ); + size = 0xdead; +@@ -3451,21 +3451,21 @@ static void test_settings(void) + ok( !ret, "QueryActCtxSettingsW succeeded\n" ); + ok( GetLastError() == ERROR_SXS_KEY_NOT_FOUND || broken( GetLastError() == ERROR_INVALID_PARAMETER ), + "wrong error %lu\n", GetLastError() ); +- ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, NULL, dpiAwarenessW, buffer, lstrlenW(trueW) + 1, &size ); + ok( !ret, "QueryActCtxSettingsW succeeded\n" ); + ok( GetLastError() == ERROR_SXS_KEY_NOT_FOUND, "wrong error %lu\n", GetLastError() ); +- ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, namespace2005W, dpiAwarenessW, buffer, lstrlenW(trueW) + 1, &size ); + ok( !ret, "QueryActCtxSettingsW succeeded\n" ); + ok( GetLastError() == ERROR_SXS_KEY_NOT_FOUND, "wrong error %lu\n", GetLastError() ); +- ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); +@@ -3474,16 +3474,16 @@ static void test_settings(void) + "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); + if (ret) + { +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == ARRAY_SIZE(trueW), "wrong len %Iu\n", size ); + } +- else ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ else ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + SetLastError( 0xdeadbeef ); + size = 0xdead; + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, NULL, dpiAwareW, buffer, lstrlenW(trueW), &size ); + ok( ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == ARRAY_SIZE(trueW), "wrong len %Iu\n", size ); + SetLastError( 0xdeadbeef ); + size = 0xdead; +@@ -3491,7 +3491,7 @@ static void test_settings(void) + ret = pQueryActCtxSettingsW( 0, handle, NULL, dpiAwareW, buffer, lstrlenW(trueW) - 1, &size ); + ok( !ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); + ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %lu\n", GetLastError() ); +- ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( buffer[0] == 0xcccc, "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == ARRAY_SIZE(trueW), "wrong len %Iu\n", size ); + ReleaseActCtx(handle); + +@@ -3507,7 +3507,7 @@ static void test_settings(void) + memset( buffer, 0xcc, sizeof(buffer) ); + ret = pQueryActCtxSettingsW( 0, handle, NULL, dpiAwareW, buffer, 80, &size ); + ok( ret, "QueryActCtxSettingsW failed err %lu\n", GetLastError() ); +- ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_w(buffer) ); ++ ok( !lstrcmpW( buffer, trueW ), "got %s\n", wine_dbgstr_wn(buffer, ARRAY_SIZE(buffer)) ); + ok( size == lstrlenW( buffer ) + 1, "wrong len %Iu\n", size ); + ReleaseActCtx(handle); + } +-- +2.47.1 + diff --git a/0015-bernhard-asan/0036-msvcp140-tests-wine_dbgstr_w-wine_dbgstr_wn.patch b/0015-bernhard-asan/0036-msvcp140-tests-wine_dbgstr_w-wine_dbgstr_wn.patch new file mode 100644 index 0000000..69ccff1 --- /dev/null +++ b/0015-bernhard-asan/0036-msvcp140-tests-wine_dbgstr_w-wine_dbgstr_wn.patch @@ -0,0 +1,146 @@ +From 409beef4d2b146238e98dd3617b4129cdae7bd29 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 21:23:44 +0100 +Subject: [PATCH 36/86] msvcp140/tests: wine_dbgstr_w - wine_dbgstr_wn. + +================================================================= +==540==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1feeb0 at pc 0x00014001f331 bp 0x7ffffe1f96a0 sp 0x7ffffe1f96e8 +READ of size 2 at 0x7ffffe1feeb0 thread T0 +0200:fixme:file:server_get_file_info Unsupported info class e + #0 0x00014001f330 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x00014001f330 in wine_dbgstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:305:12 + #2 0x000140006b13 in test_to_wide /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcp140/tests/msvcp140.c:751:17 + #3 0x000140006b13 in func_msvcp140 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcp140/tests/msvcp140.c:1756:5 + #4 0x000140021bf3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00014002163b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #6 0x00014002356f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1feeb0 is located in stack of thread T0 at offset 21456 in frame + #0 0x00014000100f in func_msvcp140 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcp140/tests/msvcp140.c:1746 + + This frame has 66 object(s): + [32, 332) 'buffer.i.i.i' + [400, 920) 'wpath.i' (line 1708) + [1056, 1064) 'mtx.i1406' (line 1677) + [1088, 1608) 'origin_path.i1231' (line 1616) + [1744, 2264) 'temp_path.i1232' (line 1616) + [2400, 2560) 'threads.i' (line 1533) + [2624, 2640) 'xt.i' (line 1534) + [2656, 2672) 'before.i' (line 1534) + [2688, 2704) 'after.i' (line 1534) + [2720, 2760) 'cm.i' (line 1535) + [2800, 2808) 'cnd.i' (line 1537) + [2832, 2840) 'mtx.i' (line 1538) + [2864, 2880) 'byval-temp.i1128' (line 1563) + [2896, 2912) 'byval-temp58.i' (line 1591) + [2928, 2944) 'byval-temp85.i' (line 1607) + [2960, 3480) 'temp_path.i1078' (line 1442) + [3616, 4136) 'current_path.i1079' (line 1442) + [4272, 4528) 'buf.i' (line 1351) + [4592, 4848) 'buf_fm.i' (line 1351) + [4912, 4920) 'lwt.i' (line 1268) + [4944, 5464) 'temp_path.i819' (line 1270) + [5600, 6120) 'origin_path.i820' (line 1270) + [6256, 6308) 'info1.i' (line 1190) + [6352, 6404) 'info2.i' (line 1190) + [6448, 6968) 'temp_path.i628' (line 1191) + [7104, 7624) 'current_path.i629' (line 1191) + [7760, 8282) 'path.i' (line 1165) + [8416, 8936) 'temp_path.i596' (line 1165) + [9072, 9592) 'temp_path.i519' (line 1104) + [9728, 10248) 'current_path.i520' (line 1104) + [10384, 10904) 'first_file_name.i' (line 1005) + [11040, 11560) 'dest.i' (line 1005) + [11696, 12216) 'longer_path.i' (line 1005) + [12352, 12872) 'origin_path.i408' (line 1006) + [13008, 13528) 'temp_path.i409' (line 1006) + [13664, 13668) 'type.i' (line 1008) + [13680, 13684) 'err.i' (line 1009) + [13696, 13700) 'perms.i' (line 883) + [13712, 14232) 'sys_path.i' (line 887) + [14368, 14888) 'origin_path.i353' (line 887) + [15024, 15544) 'temp_path.i354' (line 887) + [15680, 16200) 'temp_path.i314' (line 846) + [16336, 16856) 'current_path.i315' (line 846) + [16992, 17512) 'origin_path.i316' (line 846) + [17648, 18168) 'temp_path.i288' (line 824) + [18304, 18824) 'current_path.i' (line 824) + [18960, 19480) 'origin_path.i289' (line 824) + [19616, 20136) 'temp_path.i' (line 760) + [20272, 20792) 'origin_path.i' (line 760) + [20928, 21456) 'dst.i160' (line 716) <== Memory access at offset 21456 overflows this variable + [21584, 22112) 'compare.i161' (line 717) + [22240, 22503) 'longstr.i162' (line 720) + [22576, 22840) 'dst.i' (line 670) + [22912, 23176) 'compare.i' (line 671) + [23248, 23774) 'longstr.i' (line 674) + [23904, 23928) 'chore.i' (line 614) + [23968, 23992) 'old_chore.i' (line 614) + [24032, 24048) 'logger.i' (line 537) + [24064, 24072) 'cc.i' (line 475) + [24096, 24144) 'function_vtbl.i' (line 478) + [24176, 24240) 'function.i' (line 486) + [24272, 24336) 'byval-temp.i' (line 511) + [24368, 24432) 'byval-temp88.i' (line 517) + [24464, 24528) 'byval-temp109.i' (line 523) + [24560, 24624) 'byval-temp130.i' (line 529) + [24656, 24672) 'tcc.i' (line 452) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1fec00: f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fec80: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fed00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fed80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fee00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fee80: 00 00 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fef00: f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff100: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==540==ABORTING +0200:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:252429: dlls/msvcp140/tests/x86_64-windows/msvcp140.ok] Fehler 1 +--- + dlls/msvcp140/tests/msvcp140.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c +index 128ea20add2..5e062f27939 100644 +--- a/dlls/msvcp140/tests/msvcp140.c ++++ b/dlls/msvcp140/tests/msvcp140.c +@@ -748,7 +748,7 @@ static void test_to_wide(void) + expected = MultiByteToWideChar(CP_ACP, 0, longstr, -1, compare, MAX_PATH); + ok(ret == expected, "Got unexpected result %d, expected %d, length %u\n", ret, expected, i); + ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, length %u\n", +- wine_dbgstr_w(dst), i); ++ wine_dbgstr_wn(dst, ARRAY_SIZE(dst)), i); + } + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0037-ntdll-tests-wine_dbgstr_w-wine_dbgstr_wn.patch b/0015-bernhard-asan/0037-ntdll-tests-wine_dbgstr_w-wine_dbgstr_wn.patch new file mode 100644 index 0000000..f585d52 --- /dev/null +++ b/0015-bernhard-asan/0037-ntdll-tests-wine_dbgstr_w-wine_dbgstr_wn.patch @@ -0,0 +1,92 @@ +From a2753160949fd62293160b65dee35b88d0a5f157 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 21:35:18 +0100 +Subject: [PATCH 37/86] ntdll/tests: wine_dbgstr_w - wine_dbgstr_wn + +================================================================= +==904==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fe0e0 at pc 0x000140218eae bp 0x7ffffe1fdc00 sp 0x7ffffe1fdc48 +READ of size 2 at 0x7ffffe1fe0e0 thread T0 +02a4:fixme:file:server_get_file_info Unsupported info class e + #0 0x000140218ead in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x0001402178d7 in wine_dbgstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:305:12 + #2 0x0001402178d7 in _test_file_name /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/pipe.c:1939:80 + #3 0x0001401f300c in test_file_info /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/pipe.c:2426:5 + #4 0x0001401f300c in func_pipe /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/pipe.c:3204:5 + #5 0x000140366881 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x000140366881 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #7 0x00014036880f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fe0e0 is located in stack of thread T0 at offset 544 in frame + #0 0x00014021738f in _test_file_name /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/pipe.c:1922 + + This frame has 2 object(s): + [32, 544) 'buffer' (line 1923) <== Memory access at offset 544 overflows this variable + [608, 624) 'iosb' (line 1925) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1fde00: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fde80: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 + 0x7ffffe1fdf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fdf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fe080: 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2 + 0x7ffffe1fe100: f2 f2 f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 + 0x7ffffe1fe180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe280: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1fe300: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==904==ABORTING +02a4:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:299065: dlls/ntdll/tests/x86_64-windows/pipe.ok] Fehler 1 +--- + dlls/ntdll/tests/pipe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c +index df693d07cbd..fe398fde4f0 100644 +--- a/dlls/ntdll/tests/pipe.c ++++ b/dlls/ntdll/tests/pipe.c +@@ -1936,7 +1936,7 @@ static void _test_file_name(unsigned line, HANDLE pipe) + ok_(__FILE__,line)( iosb.Information == sizeof(name_info->FileNameLength) + sizeof(nameW), + "Information = %Iu\n", iosb.Information ); + ok( name_info->FileNameLength == sizeof(nameW), "FileNameLength = %lu\n", name_info->FileNameLength ); +- ok( !memcmp(name_info->FileName, nameW, sizeof(nameW)), "FileName = %s\n", wine_dbgstr_w(name_info->FileName) ); ++ ok( !memcmp(name_info->FileName, nameW, sizeof(nameW)), "FileName = %s\n", wine_dbgstr_wn(name_info->FileName, name_info->FileNameLength) ); + + /* too small buffer */ + memset( buffer, 0xaa, sizeof(buffer) ); +@@ -1946,7 +1946,7 @@ static void _test_file_name(unsigned line, HANDLE pipe) + ok( iosb.Status == STATUS_BUFFER_OVERFLOW, "Status = %lx\n", iosb.Status ); + ok( iosb.Information == 20, "Information = %Iu\n", iosb.Information ); + ok( name_info->FileNameLength == sizeof(nameW), "FileNameLength = %lu\n", name_info->FileNameLength ); +- ok( !memcmp(name_info->FileName, nameW, 16), "FileName = %s\n", wine_dbgstr_w(name_info->FileName) ); ++ ok( !memcmp(name_info->FileName, nameW, 16), "FileName = %s\n", wine_dbgstr_wn(name_info->FileName, name_info->FileNameLength) ); + + /* too small buffer */ + memset( buffer, 0xaa, sizeof(buffer) ); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0038-ntdll-tests-debugstr_w-debugstr_wn.patch b/0015-bernhard-asan/0038-ntdll-tests-debugstr_w-debugstr_wn.patch new file mode 100644 index 0000000..59426c0 --- /dev/null +++ b/0015-bernhard-asan/0038-ntdll-tests-debugstr_w-debugstr_wn.patch @@ -0,0 +1,252 @@ +From a77a25834816d50f49c6ec1059f083ff82733334 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 21:40:38 +0100 +Subject: [PATCH 38/86] ntdll/tests: debugstr_w - debugstr_wn + +================================================================= +==1360==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1dec70 at pc 0x0001402c42b1 bp 0x7ffffe1ddce0 sp 0x7ffffe1ddd28 +READ of size 2 at 0x7ffffe1dec70 thread T0 +065c:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001402c42b0 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 + #1 0x0001402b98e9 in debugstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:521:65 + #2 0x0001402b98e9 in test__snwprintf /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/string.c:1686:67 + #3 0x0001402b98e9 in func_string /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/string.c:2258:5 + #4 0x000140366861 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x000140366861 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001403687ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1dec70 is located in stack of thread T0 at offset 3056 in frame + #0 0x0001402acf2f in func_string /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/string.c:2237 + + This frame has 56 object(s): + [32, 35) 's.i904' (line 2220) + [48, 56) 'd.i' (line 2066) + [80, 84) 'f.i' (line 2067) + [96, 100) 'i.i' (line 2068) + [112, 116) 'buf_a.i' (line 1332) + [128, 132) 'buf_b.i' (line 1332) + [144, 147) 'str.i' (line 2014) + [160, 168) 'p.i' (line 2014) + [192, 194) 'wc.i' (line 2015) + [208, 720) 'ws.i' (line 1919) + [784, 1296) 'expectedw.i' (line 1919) + [1360, 1872) 'specw.i' (line 1919) + [1936, 2192) 'expected.i' (line 1921) + [2256, 2512) 'spec.i' (line 1921) + [2576, 2832) 's.i' (line 1921) + [2896, 2960) 'buf.i561' (line 1778) + [2992, 3056) 'buffer.i498' (line 1662) <== Memory access at offset 3056 overflows this variable + [3088, 3120) 'buf.i' (line 1617) + [3152, 3184) 'buffer.i414' (line 1489) + [3216, 3244) 'arr.i394' (line 1469) + [3280, 3284) 'l.i' (line 1470) + [3296, 3316) 'arr.i' (line 1392) + [3360, 3365) 'carr.i' (line 1393) + [3392, 3448) 'strarr.i' (line 1394) + [3488, 3544) 'strarr2.i' (line 1403) + [3584, 134656) 'buffer.i' (line 1291) + [134912, 134920) 'endpos.i' (line 1235) + [134944, 134952) 'tmp.i' (line 1249) + [134976, 134992) 'uni.i183' (line 1170) + [135008, 135024) 'uni.i159' (line 1003) + [135040, 135056) 'uni.i' (line 961) + [135072, 135208) 'expected_wstr.i26.i' (line 779) + [135280, 135416) 'dest_wstr.i27.i' (line 780) + [135488, 135504) 'unicode_string.i28.i' (line 781) + [135520, 135536) 'ansi_str.i29.i' (line 782) + [135552, 135688) 'expected_wstr.i.i84' (line 729) + [135760, 135896) 'dest_wstr.i.i85' (line 730) + [135968, 135984) 'unicode_string.i.i86' (line 731) + [136000, 136016) 'ansi_str.i.i87' (line 732) + [136032, 136168) 'expected_wstr.i81.i' (line 436) + [136240, 136376) 'dest_wstr.i82.i' (line 437) + [136448, 136464) 'unicode_string.i83.i' (line 438) + [136480, 136496) 'ansi_str.i84.i' (line 439) + [136512, 136648) 'expected_wstr.i32.i' (line 400) + [136720, 136856) 'dest_wstr.i33.i' (line 401) + [136928, 136944) 'unicode_string.i34.i' (line 402) + [136960, 136976) 'ansi_str.i35.i' (line 403) + [136992, 137128) 'expected_wstr.i.i' (line 365) + [137200, 137336) 'dest_wstr.i.i' (line 366) + [137408, 137424) 'unicode_string.i.i' (line 367) + [137440, 137456) 'ansi_str.i.i' (line 368) + [137472, 137540) 'dest_str.i24.i' (line 694) + [137584, 137652) 'dest_str.i.i3' (line 665) + [137696, 137764) 'dest_str.i49.i' (line 327) + [137808, 137876) 'dest_str.i32.i' (line 308) + [137920, 137988) 'dest_str.i.i' (line 289) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:262:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1de980: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1dea00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 + 0x7ffffe1dea80: f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1deb00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1deb80: f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 +=>0x7ffffe1dec00: f8 f8 f2 f2 f2 f2 00 00 00 00 00 00 00 00[f2]f2 + 0x7ffffe1dec80: f2 f2 f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 f2 f2 + 0x7ffffe1ded00: f2 f2 f8 f8 f8 f8 f2 f2 f2 f2 f8 f2 f8 f8 f8 f2 + 0x7ffffe1ded80: f2 f2 f2 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f2 + 0x7ffffe1dee00: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 + 0x7ffffe1dee80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1360==ABORTING +065c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:299457: dlls/ntdll/tests/x86_64-windows/string.ok] Fehler 1 +--- + dlls/ntdll/tests/string.c | 40 +++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c +index 3d975d12a10..525e46469ae 100644 +--- a/dlls/ntdll/tests/string.c ++++ b/dlls/ntdll/tests/string.c +@@ -1672,104 +1672,104 @@ static void test__snwprintf(void) + res = p_snwprintf(buffer, lstrlenW(teststring), teststring); + ok(res == lstrlenW(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenW(teststring)); + ok(!wcscmp(buffer, L"hello worldX"), "_snprintf returned buffer %s, expected 'hello worldX'.\n", +- debugstr_w(buffer)); ++ debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + wcscpy(buffer, origstring); + res = p_snwprintf(buffer, lstrlenW(teststring) + 1, teststring); + ok(res == lstrlenW(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenW(teststring)); + ok(!wcscmp(buffer, teststring), "_snprintf returned buffer %s, expected %s.\n", +- debugstr_w(buffer), debugstr_w(teststring)); ++ debugstr_wn(buffer, ARRAY_SIZE(buffer)), debugstr_w(teststring)); + + memset(buffer, 0xcc, sizeof(buffer)); + res = p_snwprintf(buffer, 4, L"test"); + ok(res == 4, "res = %d\n", res); +- ok(!memcmp(buffer, L"test", 4 * sizeof(WCHAR)), "buf = %s\n", debugstr_w(buffer)); ++ ok(!memcmp(buffer, L"test", 4 * sizeof(WCHAR)), "buf = %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + ok(buffer[4] == 0xcccc, "buffer[4] = %x\n", buffer[4]); + + memset(buffer, 0xcc, sizeof(buffer)); + res = p_snwprintf(buffer, 3, L"test"); + ok(res == -1, "res = %d\n", res); +- ok(!memcmp(buffer, L"tes", 3 * sizeof(WCHAR)), "buf = %s\n", debugstr_w(buffer)); ++ ok(!memcmp(buffer, L"tes", 3 * sizeof(WCHAR)), "buf = %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + ok(buffer[3] == 0xcccc, "buffer[3] = %x\n", buffer[3]); + + memset(buffer, 0xcc, sizeof(buffer)); + res = p_snwprintf(buffer, 4, L"%s", L"test"); + ok(res == 4, "res = %d\n", res); +- ok(!memcmp(buffer, L"test", 4 * sizeof(WCHAR)), "buf = %s\n", debugstr_w(buffer)); ++ ok(!memcmp(buffer, L"test", 4 * sizeof(WCHAR)), "buf = %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + ok(buffer[4] == 0xcccc, "buffer[4] = %x\n", buffer[4]); + + memset(buffer, 0xcc, sizeof(buffer)); + res = p_snwprintf(buffer, 3, L"%s", L"test"); + ok(res == -1, "res = %d\n", res); +- ok(!memcmp(buffer, L"tes", 3), "buf = %s\n", debugstr_w(buffer)); ++ ok(!memcmp(buffer, L"tes", 3), "buf = %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + ok(buffer[3] == 0xcccc, "buffer[3] = %x\n", buffer[3]); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%I64x %d", (ULONGLONG)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%I32x %d", 0x123456, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"123456 1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"123456 1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%#x %#x", 0, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"0 0x1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"0 0x1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%hx %hd", 0x123456, 987654); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"3456 4614"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"3456 4614"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + if (sizeof(void *) == 8) + { + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%Ix %d", (ULONG_PTR)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%zx %d", (ULONG_PTR)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"1234567890 1") || broken(!wcscmp(buffer, L"zx 878082192")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%tx %d", (ULONG_PTR)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"1234567890 1") || broken(!wcscmp(buffer, L"tx 878082192")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%jx %d", (ULONG_PTR)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"1234567890 1") || broken(!wcscmp(buffer, L"jx 878082192")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%llx %d", (ULONG_PTR)0x1234567890, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"1234567890 1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + } + else + { + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%Ix %d", (ULONG_PTR)0x123456, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); +- ok(!wcscmp(buffer, L"123456 1"), "got %s\n", debugstr_w(buffer)); ++ ok(!wcscmp(buffer, L"123456 1"), "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%zx %d", (ULONG_PTR)0x123456, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"123456 1") || broken(!wcscmp(buffer, L"zx 1193046")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%tx %d", (ULONG_PTR)0x123456, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"123456 1") || broken(!wcscmp(buffer, L"tx 1193046")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%jx %d", 0x1234567890ull, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"1234567890 1") || broken(!wcscmp(buffer, L"jx 878082192")), +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + + res = p_snwprintf(buffer, ARRAY_SIZE(buffer), L"%llx %d", 0x1234567890ull, 1); + ok(res == lstrlenW(buffer), "wrong size %d\n", res); + ok(!wcscmp(buffer, L"1234567890 1") || broken(!wcscmp(buffer, L"34567890 18")), /* winxp */ +- "got %s\n", debugstr_w(buffer)); ++ "got %s\n", debugstr_wn(buffer, ARRAY_SIZE(buffer))); + } + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0039-setupapi-tests-debugstr_a-debugstr_an.patch b/0015-bernhard-asan/0039-setupapi-tests-debugstr_a-debugstr_an.patch new file mode 100644 index 0000000..56a6686 --- /dev/null +++ b/0015-bernhard-asan/0039-setupapi-tests-debugstr_a-debugstr_an.patch @@ -0,0 +1,148 @@ +From c48f827648f6d59502290bba2835aa0c676345c6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 23:04:49 +0100 +Subject: [PATCH 39/86] setupapi/tests: debugstr_a - debugstr_an + +================================================================= +==504==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fc974 at pc 0x00014005ac1d bp 0x7ffffe1fbe40 sp 0x7ffffe1fbe88 +READ of size 1 at 0x7ffffe1fc974 thread T0 +01e4:fixme:file:server_get_file_info Unsupported info class e + #0 0x00014005ac1c in wine_dbgstr_an /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:219:30 + #1 0x00014005ac1c in debugstr_a /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:521:65 + #2 0x000140054cef in test_driver_store /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4510:44 + #3 0x0001400224ad in func_devinst /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4709:5 + #4 0x0001400c710c in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001400c710c in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001400c903f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fc974 is located in stack of thread T0 at offset 2004 in frame + #0 0x00014005279f in test_driver_store /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4335 + + This frame has 13 object(s): + [32, 292) 'path.i.i' (line 570) + [368, 628) 'filename.i.i' (line 570) + [704, 1508) 'cab_params.i' (line 583) + [1648, 1660) 'erf.i' (line 585) + [1680, 1712) 'device' (line 4337) + [1744, 2004) 'dest' (line 4338) <== Memory access at offset 2004 overflows this variable + [2080, 2340) 'orig_dest' (line 4338) + [2416, 2676) 'inf_path' (line 4338) + [2752, 3552) 'driver' (line 4339) + [3680, 3940) 'orig_cwd' (line 4340) + [4016, 4276) 'driver_path' (line 4341) + [4352, 4400) 'system_info' (line 4342) + [4432, 4436) 'size' (line 4345) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:219:30 in wine_dbgstr_an +Shadow bytes around the buggy address: + 0x7ffffe1fc680: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fc700: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fc780: f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fc800: f2 f2 f8 f8 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00 + 0x7ffffe1fc880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fc900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[04]f2 + 0x7ffffe1fc980: f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 + 0x7ffffe1fca00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fca80: 00 00 00 00 00 00 00 00 04 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fcb00: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==504==ABORTING +01e4:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:352637: dlls/setupapi/tests/x86_64-windows/devinst.ok] Fehler 1 +--- + dlls/setupapi/tests/devinst.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c +index c5c0114b2b7..3b900eeed31 100644 +--- a/dlls/setupapi/tests/devinst.c ++++ b/dlls/setupapi/tests/devinst.c +@@ -4464,7 +4464,7 @@ static void test_driver_store(struct testsign_context *ctx) + memset(dest, 0xcc, sizeof(dest)); + ret = pDriverStoreFindDriverPackageA("winetest.inf", 0, 0, system_info.wProcessorArchitecture, 0, dest, &size); + ok(ret == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got %#x.\n", ret); +- ok(!dest[0], "Got %s.\n", debugstr_a(dest)); ++ ok(!dest[0], "Got %s.\n", debugstr_an(dest, ARRAY_SIZE(dest))); + todo_wine ok(!size, "Got size %lu.\n", size); + + /* Windows 7 allows relative paths. Windows 8+ do not. +@@ -4479,8 +4479,8 @@ static void test_driver_store(struct testsign_context *ctx) + ok(!ret, "Got %#x.\n", ret); + ok(size > ARRAY_SIZE(repository_dir), "Got size %lu.\n", size); + ok(size == strlen(dest) + 1, "Expected size %Iu, got %lu.\n", strlen(dest) + 1, size); +- ok(!memicmp(dest, repository_dir, strlen(repository_dir)), "Got path %s.\n", debugstr_a(dest)); +- ok(!strcmp(dest + strlen(dest) - 13, "\\winetest.inf"), "Got path %s.\n", debugstr_a(dest)); ++ ok(!memicmp(dest, repository_dir, strlen(repository_dir)), "Got path %s.\n", debugstr_an(dest, ARRAY_SIZE(dest))); ++ ok(!strcmp(dest + strlen(dest) - 13, "\\winetest.inf"), "Got path %s.\n", debugstr_an(dest, ARRAY_SIZE(dest))); + + strcpy(orig_dest, dest); + +@@ -4489,14 +4489,14 @@ static void test_driver_store(struct testsign_context *ctx) + memset(dest, 0xcc, sizeof(dest)); + ret = pDriverStoreAddDriverPackageA(inf_path, 0, 0, system_info.wProcessorArchitecture, dest, &size); + ok(!ret, "Got %#x.\n", ret); +- ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_a(dest)); ++ ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_an(dest, ARRAY_SIZE(dest))); + ok(size == strlen(dest) + 1, "Expected size %Iu, got %lu.\n", strlen(dest) + 1, size); + + size = ARRAY_SIZE(dest); + memset(dest, 0xcc, sizeof(dest)); + ret = pDriverStoreFindDriverPackageA("winetest.inf", 0, 0, system_info.wProcessorArchitecture, 0, dest, &size); + ok(!ret, "Got %#x.\n", ret); +- ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_a(dest)); ++ ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_an(dest, ARRAY_SIZE(dest))); + ok(size == strlen(dest) + 1, "Expected size %Iu, got %lu.\n", strlen(dest) + 1, size); + + /* Test the length parameter. +@@ -4507,7 +4507,7 @@ static void test_driver_store(struct testsign_context *ctx) + memset(dest, 0xcc, sizeof(dest)); + ret = pDriverStoreFindDriverPackageA("winetest.inf", 0, 0, system_info.wProcessorArchitecture, 0, dest, &size); + ok(ret == E_INVALIDARG, "Got %#x.\n", ret); +- ok(dest[0] == (char)0xcc, "Got %s.\n", debugstr_a(dest)); ++ ok(dest[0] == (char)0xcc, "Got %s.\n", debugstr_an(dest, ARRAY_SIZE(dest))); + ok(size == MAX_PATH - 1, "Expected size %Iu, got %lu.\n", strlen(orig_dest) + 1, size); + + size = 0; +@@ -4582,7 +4582,7 @@ static void test_driver_store(struct testsign_context *ctx) + ok(!ret || ret == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /* Win < 8 */, "Got %#x.\n", ret); + if (!ret) + { +- ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_a(dest)); ++ ok(!strcmp(dest, orig_dest), "Expected %s, got %s.\n", debugstr_a(orig_dest), debugstr_an(dest, ARRAY_SIZE(dest))); + ok(size == strlen(dest) + 1, "Expected size %Iu, got %lu.\n", strlen(dest) + 1, size); + } + +@@ -4594,7 +4594,7 @@ static void test_driver_store(struct testsign_context *ctx) + memset(dest, 0xcc, sizeof(dest)); + ret = pDriverStoreFindDriverPackageA("not_winetest.inf", 0, 0, system_info.wProcessorArchitecture, 0, dest, &size); + ok(ret == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got %#x.\n", ret); +- ok(!dest[0], "Got %s.\n", debugstr_a(dest)); ++ ok(!dest[0], "Got %s.\n", debugstr_an(dest, ARRAY_SIZE(dest))); + todo_wine ok(!size, "Got size %lu.\n", size); + + ret = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, set, &device); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0040-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch b/0015-bernhard-asan/0040-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch new file mode 100644 index 0000000..2e42123 --- /dev/null +++ b/0015-bernhard-asan/0040-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch @@ -0,0 +1,103 @@ +From 6ea1de51588c748ea4f519fb6d7d0079a013acc8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 01:20:02 +0100 +Subject: [PATCH 40/86] user32/tests: wine_dbgstr_w - wine_dbgstr_wn + +================================================================= +==460==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fca30 at pc 0x00014040e081 bp 0x7ffffe1fc6a0 sp 0x7ffffe1fc6e8 +READ of size 2 at 0x7ffffe1fca30 thread T0 +0724:fixme:file:server_get_file_info Unsupported info class e + #0 0x00014040e080 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 + #1 0x0001403f4a7a in wine_dbgstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:306:12 + #2 0x0001403f4a7a in test_gettext /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/win.c:8480:82 + #3 0x000140367d54 in func_win /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/win.c:13507:5 + #4 0x00014044f7b1 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00014044f7b1 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x00014045172f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fca30 is located in stack of thread T0 at offset 112 in frame + #0 0x0001403f1c1f in test_gettext /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/win.c:8288 + + This frame has 5 object(s): + [32, 36) 'tid' (line 8290) + [48, 112) 'bufW' (line 8291) <== Memory access at offset 112 overflows this variable + [144, 152) 'thread' (line 8292) + [176, 208) 'buf' (line 8294) + [240, 288) 'msg' (line 8298) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1fc780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fc800: 00 00 00 00 00 00 00 00 00 00 00 00 00 04 f3 f3 + 0x7ffffe1fc880: f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 + 0x7ffffe1fc900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fc980: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 00 00 +=>0x7ffffe1fca00: 00 00 00 00 00 00[f2]f2 f2 f2 00 f2 f2 f2 00 00 + 0x7ffffe1fca80: 00 00 f2 f2 f2 f2 00 00 00 00 00 00 f3 f3 f3 f3 + 0x7ffffe1fcb00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==460==ABORTING +0724:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:388405: dlls/user32/tests/x86_64-windows/win.ok] Fehler 1 +--- + dlls/user32/tests/win.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 160d85f2190..f5be29fc628 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -8345,7 +8345,7 @@ static void test_gettext(void) + bufW[0] = 0xcc; + buf_len = InternalGetWindowText( hwnd, bufW, ARRAYSIZE(bufW) ); + ok( buf_len == ARRAYSIZE("caption") - 1, "expected a nonempty window text\n" ); +- ok( !lstrcmpW( bufW, L"caption" ), "got %s\n", debugstr_w(bufW) ); ++ ok( !lstrcmpW( bufW, L"caption" ), "got %s\n", wine_dbgstr_wn(bufW, ARRAY_SIZE(bufW)) ); + + g_wm_gettext_override.enabled = FALSE; + +@@ -8458,7 +8458,7 @@ static void test_gettext(void) + g_wm_gettext_override.dont_terminate = TRUE; + buf_len = GetWindowTextW( hwnd, bufW, ARRAY_SIZE(bufW)); + ok( buf_len == 4, "Unexpected text length, %d\n", buf_len ); +- ok( !memcmp(bufW, textW, 4 * sizeof(WCHAR)), "Unexpected window text, %s\n", wine_dbgstr_w(bufW) ); ++ ok( !memcmp(bufW, textW, 4 * sizeof(WCHAR)), "Unexpected window text, %s\n", wine_dbgstr_wn(bufW, ARRAY_SIZE(bufW)) ); + ok( bufW[4] == 0, "Unexpected buffer contents, %#x\n", bufW[4] ); + g_wm_gettext_override.dont_terminate = FALSE; + +@@ -8477,7 +8477,7 @@ static void test_gettext(void) + g_wm_gettext_override.dont_terminate = TRUE; + buf_len = GetWindowTextW( hwnd2, bufW, ARRAY_SIZE(bufW)); + ok( buf_len == 4, "Unexpected text length, %d\n", buf_len ); +- ok( !memcmp(bufW, textW, 4 * sizeof(WCHAR)), "Unexpected window text, %s\n", wine_dbgstr_w(bufW) ); ++ ok( !memcmp(bufW, textW, 4 * sizeof(WCHAR)), "Unexpected window text, %s\n", wine_dbgstr_wn(bufW, ARRAY_SIZE(bufW)) ); + ok( bufW[4] == 0x1c1c, "Unexpected buffer contents, %#x\n", bufW[4] ); + g_wm_gettext_override.dont_terminate = FALSE; + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0041-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch b/0015-bernhard-asan/0041-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch new file mode 100644 index 0000000..9e5418c --- /dev/null +++ b/0015-bernhard-asan/0041-user32-tests-wine_dbgstr_w-wine_dbgstr_wn.patch @@ -0,0 +1,165 @@ +From 6b600fe273068ff3dc7133c61e295890c2577e8b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 01:06:53 +0100 +Subject: [PATCH 41/86] user32/tests: wine_dbgstr_w - wine_dbgstr_wn + +================================================================= +==1048==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fe4d0 at pc 0x000140160cb1 bp 0x7ffffe1fc0a0 sp 0x7ffffe1fc0e8 +READ of size 2 at 0x7ffffe1fe4d0 thread T0 +0414:fixme:file:server_get_file_info Unsupported info class e + #0 0x000140160cb0 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 + #1 0x0001401155dc in wine_dbgstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:306:12 + #2 0x0001401155dc in test_key_names /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/input.c:3838:49 + #3 0x0001401155dc in func_input /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/input.c:6180:5 + #4 0x00014044f751 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00014044f751 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001404516cf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fe4d0 is located in stack of thread T0 at offset 8336 in frame + #0 0x00014010ad1f in func_input /home/bernhard/data/entwicklung/2024/wine\wine/dlls/user32/tests/input.c:6147 + + This frame has 68 object(s): + [32, 48) 'rect.i1566' (line 5786) + [64, 80) 'clip_rect.i1567' (line 5786) + [96, 112) 'virtual_rect.i1568' (line 5786) + [128, 200) 'cls.i' (line 5156) + [240, 320) 'inputs.i' (line 5157) + [352, 368) 'rc.i' (line 5159) + [384, 432) 'msg.i1478' (line 5160) + [464, 976) 'devices.i' (line 1913) + [1040, 1044) 'devcount.i' (line 1914) + [1056, 1060) 'odevcount.i' (line 1914) + [1072, 1104) 'info.i' (line 1949) + [1136, 1140) 'size.i' (line 1950) + [1152, 1408) 'name.i' (line 1986) + [1472, 1600) 'nameA.i' (line 1987) + [1632, 1636) 'sz.i' (line 1988) + [1648, 1680) 'info143.i' (line 1989) + [1712, 1720) 'preparsed.i' (line 2051) + [1744, 1768) 'in.i1197' (line 1604) + [1808, 6608) 'out.i1198' (line 1605) + [6864, 6872) 'point.i1199' (line 1606) + [6896, 6936) 'input.i' (line 1607) + [6976, 7008) 'params.i1014' (line 2998) + [7040, 7064) 'process_info.i' (line 2999) + [7104, 7120) 'raw_devices.i1015' (line 3000) + [7136, 7240) 'startup_info.i' (line 3001) + [7280, 7288) 'pt.i1016' (line 3004) + [7312, 7320) 'newpt.i' (line 3004) + [7344, 7604) 'path.i' (line 3007) + [7680, 7682) 'wchr.i' (line 5071) + [7696, 7697) 'oem_char.i' (line 5072) + [7712, 7736) 'params.i' (line 4959) + [7776, 8032) 'keystate.i' (line 4962) + [8096, 8144) 'msg.i853' (line 4965) + [8176, 8216) 'buffer.i' (line 3804) + [8256, 8336) 'bufferW.i' (line 3805) <== Memory access at offset 8336 overflows this variable + [8368, 8386) 'klid.i' (line 3476) + [8432, 8450) 'tmpklid.i' (line 3476) + [8496, 9016) 'layout_path.i' (line 3476) + [9152, 9162) 'value.i' (line 3476) + [9184, 9188) 'value_size.i' (line 3478) + [9200, 9204) 'klid_size.i' (line 3478) + [9216, 9220) 'type.i' (line 3478) + [9232, 9240) 'hkey.i' (line 3480) + [9264, 9296) 'wstr.i' (line 3383) + [9328, 9344) 'str.i' (line 3384) + [9360, 9362) 'character.i' (line 3385) + [9376, 9632) 'state.i409' (line 3386) + [9696, 9704) 'wStr.i' (line 3309) + [9728, 9984) 'state.i' (line 3310) + [10048, 10304) 'buff.i' (line 1446) + [10368, 10384) 'rect.i247' (line 5730) + [10400, 10416) 'clip_rect.i248' (line 5730) + [10432, 10448) 'virtual_rect.i249' (line 5730) + [10464, 10480) 'rect.i218' (line 5677) + [10496, 10512) 'clip_rect.i' (line 5677) + [10528, 10544) 'virtual_rect.i' (line 5677) + [10560, 10568) 'thread.i' (line 5679) + [10592, 10608) 'rect.i' (line 5634) + [10624, 10648) 'in.i' (line 1828) + [10688, 12224) 'out.i' (line 1829) + [12352, 13888) 'out2.i' (line 1829) + [14016, 14024) 'point.i' (line 1830) + [14048, 14064) 'raw_devices.i' (line 2764) + [14080, 14088) 'done.i' (line 2765) + [14112, 14120) 'pt.i' (line 2767) + [14144, 14192) 'msg.i' (line 2769) + [14224, 14232) 'argv' (line 6148) + [14256, 14264) 'pos' (line 6150) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x7ffffe1fe200: f2 f2 f2 f2 f2 f2 f2 f2 f8 f2 f8 f2 f8 f8 f8 f2 + 0x7ffffe1fe280: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fe300: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fe380: f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8 f8 + 0x7ffffe1fe400: f8 f8 f2 f2 f2 f2 00 00 00 00 00 f2 f2 f2 f2 f2 +=>0x7ffffe1fe480: 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2 f8 f8 + 0x7ffffe1fe500: f8 f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 + 0x7ffffe1fe580: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fe600: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fe680: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fe700: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1048==ABORTING +0414:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:387435: dlls/user32/tests/x86_64-windows/input.ok] Fehler 1 +--- + dlls/user32/tests/input.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c +index 9196e67c15b..0bffb40d718 100644 +--- a/dlls/user32/tests/input.c ++++ b/dlls/user32/tests/input.c +@@ -3824,19 +3824,19 @@ static void test_key_names(void) + + memset( bufferW, 0xcc, sizeof(bufferW) ); + ret = GetKeyNameTextW( lparam, bufferW, ARRAY_SIZE(bufferW)); +- ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); +- ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); ++ ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); ++ ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); + + memset( bufferW, 0xcc, sizeof(bufferW) ); + prev = ret; + ret = GetKeyNameTextW( lparam, bufferW, prev ); +- ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); +- ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); ++ ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); ++ ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); + + memset( bufferW, 0xcc, sizeof(bufferW) ); + ret = GetKeyNameTextW( lparam, bufferW, 0 ); +- ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); +- ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) ); ++ ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); ++ ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_wn(bufferW, ARRAY_SIZE(bufferW)) ); + } + + static void simulate_click(BOOL left, int x, int y) +-- +2.47.1 + diff --git a/0015-bernhard-asan/0042-win32u-tests-debugstr_w-debugstr_wn.patch b/0015-bernhard-asan/0042-win32u-tests-debugstr_w-debugstr_wn.patch new file mode 100644 index 0000000..a220e47 --- /dev/null +++ b/0015-bernhard-asan/0042-win32u-tests-debugstr_w-debugstr_wn.patch @@ -0,0 +1,119 @@ +From 406fb1ba3ff84fd589e97104dd91b58376721402 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 18 Dec 2024 00:25:54 +0100 +Subject: [PATCH 42/86] win32u/tests: debugstr_w - debugstr_wn. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M win32u.dll -p dlls/win32u/tests/i386-windows/win32u_test.exe win32u && touch dlls/win32u/tests/i386-windows/win32u.ok +================================================================= +==2640==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x005cf650 at pc 0x0042d112 bp 0x005cdf34 sp 0x005cdf30 +READ of size 2 at 0x005cf650 thread T0 +0a64:fixme:msvcrt:_set_abort_behavior _WRITE_CALL_REPORTFAULT unhandled +0a64:fixme:file:server_get_file_info Unsupported info class e + #0 0x0042d111 in wine_dbgstr_wn /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 + #1 0x0040394a in debugstr_w /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:522:65 + #2 0x0040394a in test_class /home/bernhard/data/entwicklung/2024/wine\wine/dlls/win32u/tests/win32u.c:269:41 + #3 0x0040394a in func_win32u /home/bernhard/data/entwicklung/2024/wine\wine/dlls/win32u/tests/win32u.c:2548:5 + #4 0x00436849 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00436260 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #6 0x00437f0b in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x7877ea3f in BaseThreadInitThunk (C:\windows\system32\kernel32.dll+0x7b80ea3f) + #8 0x788fce82 in call_thread_func_wrapper (C:\windows\system32\ntdll.dll+0x7bc0ce82) + #9 0x789304b4 in call_thread_func /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\signal_i386.c:524:9 + +Address 0x005cf650 is located in stack of thread T0 at offset 5296 in frame + #0 0x0040100f in func_win32u /home/bernhard/data/entwicklung/2024/wine\wine/dlls/win32u/tests/win32u.c:2518 + + This frame has 37 object(s): + [16, 100) 'source_name.i' (line 1291) + [144, 184) 'cls.i675' (line 2031) + [224, 264) 'cls.i638' (line 1349) + [304, 564) 'path.i' (line 1350) + [640, 656) 'pi.i' (line 1351) + [672, 740) 'startup.i' (line 1352) + [784, 812) 'msg.i639' (line 1353) + [848, 876) 'msg.i615' (line 1271) + [912, 940) 'msg.i' (line 1220) + [976, 1024) 'item.i' (line 1143) + [1056, 2080) 'buf.i537' (line 1088) + [2208, 2216) 'callback_params.i' (line 1024) + [2240, 2252) 'smp.i' (line 1028) + [2272, 2312) 'cls.i440' (line 1029) + [2352, 2872) 'module.i' (line 891) + [3008, 3528) 'res_buf.i' (line 891) + [3664, 3672) 'module_str.i' (line 892) + [3696, 3704) 'res_str.i' (line 892) + [3728, 4752) 'bmp_bits.i' (line 893) + [4880, 4884) 'width.i' (line 894) + [4896, 4900) 'height.i' (line 894) + [4912, 4916) 'rate.i' (line 895) + [4928, 4932) 'steps.i' (line 895) + [4944, 4964) 'info.i348' (line 898) + [5008, 5012) 'ret_size.i' (line 752) + [5024, 5056) 'buf.i234' (line 415) + [5088, 5100) 'himc.i' (line 415) + [5120, 5124) 'size.i' (line 417) + [5136, 5144) 'name.i' (line 180) + [5168, 5296) 'buf.i173' (line 181) <== Memory access at offset 5296 overflows this variable + [5328, 5368) 'cls.i' (line 182) + [5408, 5412) 'count.i' (line 123) + [5424, 6264) 'info.i' (line 71) + [6400, 6436) 'mdi.i' (line 1389) + [6480, 6680) 'bufW.i' (line 1390) + [6752, 6852) 'buf.i' (line 1391) + [6896, 6900) 'argv' (line 2519) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/debug.h:263:30 in wine_dbgstr_wn +Shadow bytes around the buggy address: + 0x005cf380: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x005cf400: f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x005cf480: f2 f2 f2 f2 f2 f2 f8 f2 f8 f2 f8 f2 f8 f2 f8 f8 + 0x005cf500: f8 f2 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 f2 f2 f2 f2 + 0x005cf580: f8 f8 f2 f2 f8 f2 00 f2 f2 f2 00 00 00 00 00 00 +=>0x005cf600: 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2 00 00 + 0x005cf680: 00 00 00 f2 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 f8 f8 + 0x005cf700: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x005cf780: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x005cf800: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x005cf880: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==2640==ABORTING +make: *** [Makefile:414149: dlls/win32u/tests/i386-windows/win32u.ok] Fehler 1 +--- + dlls/win32u/tests/win32u.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c +index b51218ef60d..2db0572a3eb 100644 +--- a/dlls/win32u/tests/win32u.c ++++ b/dlls/win32u/tests/win32u.c +@@ -266,7 +266,7 @@ static void test_class(void) + ret = NtUserGetAtomName( class, &name ); + ok( !ret && GetLastError() == ERROR_INVALID_HANDLE, + "NtUserGetAtomName returned %lx %lu\n", ret, GetLastError() ); +- ok( buf[0] == 0xcccc, "buf = %s\n", debugstr_w(buf) ); ++ ok( buf[0] == 0xcccc, "buf = %s\n", debugstr_wn(buf, ARRAY_SIZE(buf)) ); + + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0043-advapi32-Use-no_sanitize_address-in-pointer_from_han.patch b/0015-bernhard-asan/0043-advapi32-Use-no_sanitize_address-in-pointer_from_han.patch new file mode 100644 index 0000000..e85b8a5 --- /dev/null +++ b/0015-bernhard-asan/0043-advapi32-Use-no_sanitize_address-in-pointer_from_han.patch @@ -0,0 +1,29 @@ +From 9ad46071889594123770df4771c36d5b571bfb1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 17:28:09 +0100 +Subject: [PATCH 43/86] advapi32: Use no_sanitize_address in + pointer_from_handle. + +provider_from_handle +ret = CryptContextAddRef(0xdeadbeef, NULL, 0); +test_CryptReleaseContext +func_crypt +--- + dlls/advapi32/crypt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c +index 0c94999660a..8444ec7046e 100644 +--- a/dlls/advapi32/crypt.c ++++ b/dlls/advapi32/crypt.c +@@ -58,6 +58,7 @@ static HWND crypt_hWindow; + #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size)) + #define CRYPT_Free(buffer) (LocalFree(buffer)) + ++__attribute__((no_sanitize_address)) + static void *pointer_from_handle(UINT_PTR handle, DWORD magic) + { + void *ret = NULL; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0044-bcrypt-Use-no_sanitize_address-in-get_object-BCryptC.patch b/0015-bernhard-asan/0044-bcrypt-Use-no_sanitize_address-in-get_object-BCryptC.patch new file mode 100644 index 0000000..e765f4e --- /dev/null +++ b/0015-bernhard-asan/0044-bcrypt-Use-no_sanitize_address-in-get_object-BCryptC.patch @@ -0,0 +1,107 @@ +From fd76dfdc1c8d6a5a145f9ef9469ff93d545d9abf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 17:59:00 +0100 +Subject: [PATCH 44/86] bcrypt: Use no_sanitize_address in + get_object/BCryptCloseAlgorithmProvider. + +================================================================= +==664==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ebd152e0640 at pc 0x6ffff85f3d2d bp 0x7ffffe1fd970 sp 0x7ffffe1fd9b8 +READ of size 4 at 0x7ebd152e0640 thread T0 +02a4:fixme:dbghelp:elf_search_auxv can't find symbol in module +02a4:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007E950AA50B80,symt:0000000000000000) in ctx(00007E950AFC1010,L"bcrypt") +02a4:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007E950A770B80,symt:0000000000000000) in ctx(00007E950C300D70,L"bcrypt_test") + #0 0x6ffff85f3d2c in BCryptDestroyHash Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\bcrypt\bcrypt_main.c:1124 + #1 0x00014005910d in test_hash+0x328d (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005910d) + #2 0x0001400029cc in func_bcrypt+0x19cc (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x1400029cc) + #3 0x00014005e773 in run_test+0x163 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e773) + #4 0x00014005e1bb in main+0x4db (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e1bb) + #5 0x0001400600ef in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #6 0x6ffffbdc4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #7 0x6ffffad1fa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7ebd152e0640 is located 0 bytes inside of 432-byte region [0x7ebd152e0640,0x7ebd152e07f0) +freed by thread T0 here: +02a4:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007E9505EA0B80,symt:0000000000000000) in ctx(00007E950AEC4A20,L"libclang_rt.asan_dynamic-x86_64") + #0 0x6ffff901a041 in free+0x81 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a041) + #1 0x6ffff85f3c49 in BCryptDestroyHash Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\bcrypt\bcrypt_main.c:1126 + #2 0x00014005902a in test_hash+0x31aa (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005902a) + #3 0x0001400029cc in func_bcrypt+0x19cc (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x1400029cc) + #4 0x00014005e773 in run_test+0x163 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e773) + #5 0x00014005e1bb in main+0x4db (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e1bb) + #6 0x0001400600ef in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #7 0x6ffffbdc4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #8 0x6ffffad1fa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff901a276 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a276) + #1 0x6ffff85f35a5 in hash_create Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\bcrypt\bcrypt_main.c:1036 + #2 0x6ffff85f349e in BCryptCreateHash Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\bcrypt\bcrypt_main.c:1080 + #3 0x0001400587e0 in test_hash+0x2960 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x1400587e0) + #4 0x0001400029cc in func_bcrypt+0x19cc (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x1400029cc) + #5 0x00014005e773 in run_test+0x163 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e773) + #6 0x00014005e1bb in main+0x4db (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\bcrypt\tests\x86_64-windows\bcrypt_test.exe+0x14005e1bb) + #7 0x0001400600ef in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #8 0x6ffffbdc4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #9 0x6ffffad1fa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\bcrypt\bcrypt_main.c:1124 in BCryptDestroyHash +Shadow bytes around the buggy address: + 0x7ebd152e0380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa + 0x7ebd152e0400: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd + 0x7ebd152e0480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ebd152e0500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ebd152e0580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa +=>0x7ebd152e0600: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd + 0x7ebd152e0680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ebd152e0700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ebd152e0780: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa + 0x7ebd152e0800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7ebd152e0880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==664==ABORTING +make: *** [Makefile:16069: dlls/bcrypt/tests/x86_64-windows/bcrypt.ok] Fehler 1 +--- + dlls/bcrypt/bcrypt_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c +index 3d88430a07e..2af43afb589 100644 +--- a/dlls/bcrypt/bcrypt_main.c ++++ b/dlls/bcrypt/bcrypt_main.c +@@ -258,6 +258,7 @@ static inline BOOL is_alg_pseudo_handle( BCRYPT_ALG_HANDLE handle ) + return (((ULONG_PTR)handle & 1) == 1); + } + ++__attribute__((no_sanitize_address)) + static struct object *get_object( BCRYPT_HANDLE handle, ULONG magic ) + { + ULONG idx; +@@ -405,6 +406,7 @@ static void destroy_object( struct object *obj ) + free( obj ); + } + ++__attribute__((no_sanitize_address)) + NTSTATUS WINAPI BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle, DWORD flags ) + { + struct algorithm *alg = handle; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0045-comctl32-Use-no_sanitize_address-in-is_valid.patch b/0015-bernhard-asan/0045-comctl32-Use-no_sanitize_address-in-is_valid.patch new file mode 100644 index 0000000..1eb65cb --- /dev/null +++ b/0015-bernhard-asan/0045-comctl32-Use-no_sanitize_address-in-is_valid.patch @@ -0,0 +1,24 @@ +From 2552da1a4accc050b1b9687dedfb2b5678db4b5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sat, 14 Dec 2024 15:47:05 +0100 +Subject: [PATCH 45/86] comctl32: Use no_sanitize_address in is_valid. + +--- + dlls/comctl32/imagelist.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c +index 49155e8d2c1..b7a2a642135 100644 +--- a/dlls/comctl32/imagelist.c ++++ b/dlls/comctl32/imagelist.c +@@ -3788,6 +3788,7 @@ static const IImageList2Vtbl ImageListImpl_Vtbl = { + ImageListImpl_ReplaceFromImageList + }; + ++__attribute__((no_sanitize_address)) + static BOOL is_valid(HIMAGELIST himl) + { + BOOL valid; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0046-rpcrt4-Use-no_sanitize_address-in-get_context_entry-.patch b/0015-bernhard-asan/0046-rpcrt4-Use-no_sanitize_address-in-get_context_entry-.patch new file mode 100644 index 0000000..6fae018 --- /dev/null +++ b/0015-bernhard-asan/0046-rpcrt4-Use-no_sanitize_address-in-get_context_entry-.patch @@ -0,0 +1,139 @@ +From a8924354ce559c929be5e8e8e71f840882abaecd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 11 Dec 2024 00:08:22 +0100 +Subject: [PATCH 46/86] rpcrt4: Use no_sanitize_address in + get_context_entry/NDRCContextBinding. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M services.exe -p programs/services/tests/x86_64-windows/services.exe_test.exe service && touch programs/services/tests/x86_64-windows/service.ok +================================================================= +==1424==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ebf035c0330 at pc 0x6ffff8362808 bp 0x7ffffe1fdca0 sp 0x7ffffe1fdce8 +READ of size 4 at 0x7ebf035c0330 thread T0 +05e4:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff8362807 in get_context_entry /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:65:14 + #1 0x6ffff8362807 in NDRCContextBinding /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:87:11 + #2 0x6ffff83a07ac in client_get_handle /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:344:44 + #3 0x6ffff83994e0 in ndr_client_call /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:748:24 + #4 0x6ffff83985be in NdrpClientCall2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:981:18 + #5 0x6ffff8395a3a in NdrClientCall2 (C:\windows\system32\rpcrt4.dll+0x180045a3a) + #6 0x6ffffc02d730 in svcctl_QueryServiceStatusEx /home/bernhard/data/entwicklung/2024/wine/wine-build/build-64/obj\dlls/sechost/x86_64-windows\svcctl_c.c:867:15 + #7 0x6ffffc027529 in QueryServiceStatusEx /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:1122:15 + #8 0x6ffffc027285 in QueryServiceStatus /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:1096:11 + #9 0x6ffffc027285 in QueryServiceStatus /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:1085:31 + #10 0x000140004b8a in test_no_stop /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:576:11 + #11 0x000140001c46 in test_runner /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:605:5 + #12 0x0001400011dc in func_service /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:753:9 + #13 0x00014000e243 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #14 0x00014000dc8b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #15 0x00014000fbbf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #16 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #17 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7ebf035c0330 is located 16 bytes inside of 56-byte region [0x7ebf035c0320,0x7ebf035c0358) +freed by thread T0 here: + #0 0x6ffff885a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff8362f6a in ndr_update_context_handle /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:185:13 + #2 0x6ffff8362f6a in NDRCContextUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:219:14 + #3 0x6ffff8374399 in NdrClientContextUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_marshall.c:7092:5 + #4 0x6ffff8374399 in NdrContextHandleUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_marshall.c:7038:9 + #5 0x6ffff8396328 in call_unmarshaller /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:126:19 + #6 0x6ffff8396328 in client_do_args /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:531:17 + #7 0x6ffff8399824 in ndr_client_call /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:841:9 + #8 0x6ffff83985be in NdrpClientCall2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:981:18 + #9 0x6ffff8395a3a in NdrClientCall2 (C:\windows\system32\rpcrt4.dll+0x180045a3a) + #10 0x6ffffc02cbc9 in svcctl_CloseServiceHandle /home/bernhard/data/entwicklung/2024/wine/wine-build/build-64/obj\dlls/sechost/x86_64-windows\svcctl_c.c:128:15 + #11 0x6ffffc02355d in CloseServiceHandle /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:456:15 + #12 0x000140004b79 in test_no_stop /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:574:5 + #13 0x000140001c46 in test_runner /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:605:5 + #14 0x0001400011dc in func_service /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:753:9 + #15 0x00014000e243 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #16 0x00014000dc8b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #17 0x00014000fbbf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #18 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #19 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff885a2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff8362e10 in ndr_update_context_handle /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:192:15 + #2 0x6ffff8362e10 in NDRCContextUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:219:14 + #3 0x6ffff8374399 in NdrClientContextUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_marshall.c:7092:5 + #4 0x6ffff8374399 in NdrContextHandleUnmarshall /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_marshall.c:7038:9 + #5 0x6ffff8396328 in call_unmarshaller /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:126:19 + #6 0x6ffff8396328 in client_do_args /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:531:17 + #7 0x6ffff8399824 in ndr_client_call /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:841:9 + #8 0x6ffff83985be in NdrpClientCall2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:981:18 + #9 0x6ffff8395a3a in NdrClientCall2 (C:\windows\system32\rpcrt4.dll+0x180045a3a) + #10 0x6ffffc02ce11 in svcctl_CreateServiceW /home/bernhard/data/entwicklung/2024/wine/wine-build/build-64/obj\dlls/sechost/x86_64-windows\svcctl_c.c:324:15 + #11 0x6ffffc0244b3 in CreateServiceW /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:407:19 + #12 0x6ffffc0241a0 in CreateServiceA /home/bernhard/data/entwicklung/2024/wine/wine/dlls/sechost\service.c:360:14 + #13 0x00014000af9f in register_service /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:365:15 + #14 0x00014000304a in test_no_stop /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:494:32 + #15 0x000140001c46 in test_runner /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:605:5 + #16 0x0001400011dc in func_service /home/bernhard/data/entwicklung/2024/wine\wine/programs/services/tests/service.c:753:9 + #17 0x00014000e243 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #18 0x00014000dc8b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #19 0x00014000fbbf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #20 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #21 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_contexthandle.c:65:14 in get_context_entry +Shadow bytes around the buggy address: + 0x7ebf035c0080: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd + 0x7ebf035c0100: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa + 0x7ebf035c0180: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa + 0x7ebf035c0200: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd + 0x7ebf035c0280: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa +=>0x7ebf035c0300: fa fa fa fa fd fd[fd]fd fd fd fd fa fa fa fa fa + 0x7ebf035c0380: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd + 0x7ebf035c0400: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa + 0x7ebf035c0480: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa + 0x7ebf035c0500: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd + 0x7ebf035c0580: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1424==ABORTING +05e4:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:543942: programs/services/tests/x86_64-windows/service.ok] Fehler 1 +--- + dlls/rpcrt4/ndr_contexthandle.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/rpcrt4/ndr_contexthandle.c b/dlls/rpcrt4/ndr_contexthandle.c +index 1bff1e82936..3ab83426175 100644 +--- a/dlls/rpcrt4/ndr_contexthandle.c ++++ b/dlls/rpcrt4/ndr_contexthandle.c +@@ -58,6 +58,7 @@ static CRITICAL_SECTION_DEBUG ndr_context_debug = + }; + static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; + ++__attribute__((no_sanitize_address)) + static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) + { + struct context_handle_entry *che = CContext; +@@ -76,6 +77,7 @@ static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid) + return NULL; + } + ++__attribute__((no_sanitize_address)) + RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) + { + struct context_handle_entry *che; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0047-rpcrt4-Use-no_sanitize_address-in-client_do_args.patch b/0015-bernhard-asan/0047-rpcrt4-Use-no_sanitize_address-in-client_do_args.patch new file mode 100644 index 0000000..be5440b --- /dev/null +++ b/0015-bernhard-asan/0047-rpcrt4-Use-no_sanitize_address-in-client_do_args.patch @@ -0,0 +1,96 @@ +From 3ef732b55ff468bd60959df290c698e547d305d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 22:53:34 +0100 +Subject: [PATCH 47/86] rpcrt4: Use no_sanitize_address in client_do_args. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M msctf.dll -p dlls/msctf/tests/x86_64-windows/msctf_test.exe inputprocessor && touch dlls/msctf/tests/x86_64-windows/inputprocessor.ok +01bc:fixme:msctf:TextStoreACPSink_OnLockGranted OnLockGranted called for something other than an EditSession +================================================================= +==440==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ef431f3fb60 at pc 0x6ffff7cb66fe bp 0x7ef431f3e060 sp 0x7ef431f3e0a8 +READ of size 8 at 0x7ef431f3fb60 thread T1 +01d0:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff7cb66fd in client_do_args /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:511:17 + #1 0x6ffff7cb958d in ndr_client_call /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:789:13 + #2 0x6ffff7cb87ec in NdrpClientCall2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:929:22 + #3 0x6ffff7d11d0b in call_stubless_func (C:\windows\system32\rpcrt4.dll+0x1800a1d0b) + #4 0x6ffff7fe1fe1 in IRemUnknown_RemQueryInterface /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\dlls/combase\dcom.h:309:12 + #5 0x6ffff7fe1fe1 in ClientIdentity_QueryMultipleInterfaces /home/bernhard/data/entwicklung/2024/wine\wine/dlls/combase/marshal.c:1047:18 + #6 0x6ffff7fe0d13 in IMultiQI_QueryMultipleInterfaces /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\objidl.h:1502:12 + #7 0x6ffff7fe0d13 in ClientIdentity_QueryInterface /home/bernhard/data/entwicklung/2024/wine\wine/dlls/combase/marshal.c:975:10 + #8 0x000140022aea in ITfThreadMgrEx_QueryInterface /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\msctf.h:1311:12 + #9 0x000140022aea in test_MultiThreadApartment_Thread /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msctf/tests/inputprocessor.c:2595:10 + #10 0x6ffff902b17d in asan_thread_start(void*) /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:147:14 + #11 0x6ffffbdc4808 in BaseThreadInitThunk /usr/src/packages/BUILD\dlls/kernel32\thread.c:61:5 + #12 0x6ffffad1fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ef431f3fb60 is located in stack of thread T1 at offset 0 in frame + #0 0x6ffff7fe14bf in ClientIdentity_QueryMultipleInterfaces /home/bernhard/data/entwicklung/2024/wine\wine/dlls/combase/marshal.c:999 + + This frame has 1 object(s): + [32, 40) 'qiresults' (line 1001) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +Thread T1 created by T0 here: + #0 0x6ffff902b096 in CreateThread /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:158:3 + #1 0x00014000a276 in test_MultiThreadApartment /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msctf/tests/inputprocessor.c:2618:14 + #2 0x00014000a276 in func_inputprocessor /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msctf/tests/inputprocessor.c:2659:9 + #3 0x000140024b33 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x00014002457b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #5 0x0001400264af in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffffbdc4808 in BaseThreadInitThunk /usr/src/packages/BUILD\dlls/kernel32\thread.c:61:5 + #7 0x6ffffad1fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: stack-buffer-underflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/rpcrt4/ndr_stubless.c:511:17 in client_do_args +Shadow bytes around the buggy address: + 0x7ef431f3f880: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ef431f3f900: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ef431f3f980: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ef431f3fa00: f8 f8 f8 f8 f8 f8 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 + 0x7ef431f3fa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ef431f3fb00: 00 00 00 00 00 00 00 00 00 00 00 00[f1]f1 f1 f1 + 0x7ef431f3fb80: 00 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ef431f3fc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ef431f3fc80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ef431f3fd00: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 + 0x7ef431f3fd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==440==ABORTING +make: *** [Makefile:225627: dlls/msctf/tests/x86_64-windows/inputprocessor.ok] Fehler 1 +01d0:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/rpcrt4/ndr_stubless.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c +index 8cb051443ae..8b54ed22b72 100644 +--- a/dlls/rpcrt4/ndr_stubless.c ++++ b/dlls/rpcrt4/ndr_stubless.c +@@ -477,6 +477,7 @@ static size_t basetype_arg_size( unsigned char fc ) + } + } + ++__attribute__((no_sanitize_address)) + void client_do_args( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, enum stubless_phase phase, + BOOLEAN fpu_args, unsigned short number_of_params, unsigned char *pRetVal ) + { +-- +2.47.1 + diff --git a/0015-bernhard-asan/0048-wsdapi-Use-no_sanitize_address-in-find_allocation.patch b/0015-bernhard-asan/0048-wsdapi-Use-no_sanitize_address-in-find_allocation.patch new file mode 100644 index 0000000..0452ab4 --- /dev/null +++ b/0015-bernhard-asan/0048-wsdapi-Use-no_sanitize_address-in-find_allocation.patch @@ -0,0 +1,96 @@ +From b379d3f096dd3a4612d80fc923f99f518102d10b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 23:19:08 +0100 +Subject: [PATCH 48/86] wsdapi: Use no_sanitize_address in find_allocation. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M wsdapi.dll -p dlls/wsdapi/tests/x86_64-windows/wsdapi_test.exe memory && touch dlls/wsdapi/tests/x86_64-windows/memory.ok +================================================================= +==1160==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f6035d00580 at pc 0x6ffff85f6e73 bp 0x7ffffe1ff860 sp 0x7ffffe1ff8a8 +READ of size 4 at 0x7f6035d00580 thread T0 +0494:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff85f6e72 in find_allocation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/memory.c:58:21 + #1 0x6ffff85f6e72 in WSDAllocateLinkedMemory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/memory.c:101:14 + #2 0x00014001d896 in AllocateLinkedMemory_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:55:14 + #3 0x00014001d896 in func_memory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:73:5 + #4 0x0001400375a0 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001400375a0 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x00014003940f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f6035d00580 is located 0 bytes inside of 1072-byte region [0x7f6035d00580,0x7f6035d009b0) +freed by thread T0 here: + #0 0x6ffff885a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x00014001d889 in AllocateLinkedMemory_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:52:5 + #2 0x00014001d889 in func_memory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:73:5 + #3 0x0001400375a0 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001400375a0 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #5 0x00014003940f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff885a2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff85f6d29 in WSDAllocateLinkedMemory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/memory.c:88:11 + #2 0x00014001d724 in AllocateLinkedMemory_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:46:14 + #3 0x00014001d724 in func_memory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/tests/memory.c:73:5 + #4 0x0001400375a0 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001400375a0 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x00014003940f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wsdapi/memory.c:58:21 in find_allocation +Shadow bytes around the buggy address: + 0x7f6035d00300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00480: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa + 0x7f6035d00500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +=>0x7f6035d00580:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00780: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f6035d00800: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1160==ABORTING +0494:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:457258: dlls/wsdapi/tests/x86_64-windows/memory.ok] Fehler 1 +--- + dlls/wsdapi/memory.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wsdapi/memory.c b/dlls/wsdapi/memory.c +index 7003f0aa4cb..5b7c4fdb413 100644 +--- a/dlls/wsdapi/memory.c ++++ b/dlls/wsdapi/memory.c +@@ -44,6 +44,7 @@ struct memory_allocation + struct list children; + }; + ++__attribute__((no_sanitize_address)) + static struct memory_allocation *find_allocation(void *ptr) + { + struct memory_allocation *allocation; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0049-shell32-Use-no_sanitize_address-in-ShellView_WndProc.patch b/0015-bernhard-asan/0049-shell32-Use-no_sanitize_address-in-ShellView_WndProc.patch new file mode 100644 index 0000000..819920e --- /dev/null +++ b/0015-bernhard-asan/0049-shell32-Use-no_sanitize_address-in-ShellView_WndProc.patch @@ -0,0 +1,90 @@ +From 0c06ca296791538459c589f0983c48e284aea612 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 17 Dec 2024 23:47:37 +0100 +Subject: [PATCH 49/86] shell32: Use no_sanitize_address in ShellView_WndProc. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M shell32.dll -p dlls/shell32/tests/i386-windows/shell32_test.exe shlview && touch dlls/shell32/tests/i386-windows/shlview.ok +================================================================= +==1076==ERROR: AddressSanitizer: heap-use-after-free on address 0x02b03524 at pc 0x775fbc42 bp 0x00b5e894 sp 0x00b5e890 +READ of size 4 at 0x02b03524 thread T0 +0404:fixme:msvcrt:_set_abort_behavior _WRITE_CALL_REPORTFAULT unhandled +0404:fixme:file:server_get_file_info Unsupported info class e + #0 0x775fbc41 in ShellView_WndProc /home/bernhard/data/entwicklung/2024/wine\wine/dlls/shell32/shlview.c:1700:37 + #1 0x75aa8787 in WINPROC_wrapper (C:\windows\system32\user32.dll+0x10008787) + #2 0x75afb658 in call_window_proc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:111:15 + #3 0x75b00f90 in dispatch_win_proc_params /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:710:13 + #4 0x75aedf7a in User32CallWindowProc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:824:14 + #5 0x789328f8 in dispatch_user_callback /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\exception.c:292:18 + #6 0x78900b6e in KiUserCallbackDispatcher /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\signal_i386.c:222:23 + #7 0x757adf97 in NtUserDestroyWindow (C:\windows\system32\win32u.dll+0x1000df97) + +0x02b03524 is located 100 bytes inside of 148-byte region [0x02b034c0,0x02b03554) +freed by thread T0 here: + #0 0x7645281b in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x775f38d3 in IShellView_fnRelease /home/bernhard/data/entwicklung/2024/wine\wine/dlls/shell32/shlview.c:1812:4 + #2 0x775f8e94 in ShellView_WndProc /home/bernhard/data/entwicklung/2024/wine\wine/dlls/shell32/shlview.c:1699:7 + #3 0x75aa8787 in WINPROC_wrapper (C:\windows\system32\user32.dll+0x10008787) + #4 0x75afb658 in call_window_proc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:111:15 + #5 0x75b00f90 in dispatch_win_proc_params /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:710:13 + #6 0x75aedf7a in User32CallWindowProc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32\winproc.c:824:14 + #7 0x789328f8 in dispatch_user_callback /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\exception.c:292:18 + #8 0x78900b6e in KiUserCallbackDispatcher /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\signal_i386.c:222:23 + #9 0x757adf97 in NtUserDestroyWindow (C:\windows\system32\win32u.dll+0x1000df97) + +previously allocated by thread T0 here: + #0 0x76452a1e in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x775f1bb3 in IShellView_Constructor /home/bernhard/data/entwicklung/2024/wine\wine/dlls/shell32/shlview.c:3789:10 + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/shell32/shlview.c:1700:37 in ShellView_WndProc +Shadow bytes around the buggy address: + 0x02b03280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03480: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd +=>0x02b03500: fd fd fd fd[fd]fd fd fd fd fd fd fa fa fa fa fa + 0x02b03580: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd + 0x02b03600: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa + 0x02b03680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x02b03780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1076==ABORTING +make: *** [Makefile:370069: dlls/shell32/tests/i386-windows/shlview.ok] Fehler 1 +--- + dlls/shell32/shlview.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c +index 9c699ecda08..6b26520de76 100644 +--- a/dlls/shell32/shlview.c ++++ b/dlls/shell32/shlview.c +@@ -1657,6 +1657,7 @@ static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pi + * ShellView_WndProc + */ + ++__attribute__((no_sanitize_address)) + static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) + { + IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0050-cmd-Avoid-buffer-underflow-in-search_command.-ASan.patch b/0015-bernhard-asan/0050-cmd-Avoid-buffer-underflow-in-search_command.-ASan.patch new file mode 100644 index 0000000..69f682e --- /dev/null +++ b/0015-bernhard-asan/0050-cmd-Avoid-buffer-underflow-in-search_command.-ASan.patch @@ -0,0 +1,84 @@ +From 67e178c6301405f07a17335ebd0c5b9d3c8f5060 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 5 Nov 2024 15:44:57 +0100 +Subject: [PATCH 50/86] cmd: Avoid buffer underflow in search_command. (ASan) + +benutzer@debian:/mnt/sda1/wineprefix_asan_test_2/drive_c/x86_64$ wine cmd.exe_asan.exe +Microsoft Windows 10.0.19043 + +C:\x86_64>ls +================================================================= +==556==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffffe1fa6fe at pc 0x000140029f79 bp 0x7ffffe1f5960 sp 0x7ffffe1f59a8 +READ of size 2 at 0x7ffffe1fa6fe thread T0 +023c:fixme:file:server_get_file_info Unsupported info class e + #0 0x000140029f78 in search_command /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:1591:17 + #1 0x00014002fb76 in execute_single_command /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:1877:19 + #2 0x00014002fb76 in node_execute /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:3738:27 + #3 0x000140032bc4 in wmain /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:4228:11 + #4 0x00014003c6ca in wmainCRTStartup /home/bernhard/data/entwicklung/2024/wine/wine/dlls/msvcrt\crt_wmain.c:58:11 + #5 0x6fffffa98d58 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #6 0x6fffffc95afa in RtlRaiseException (C:\windows\system32\ntdll.dll+0x170055afa) + +Address 0x7ffffe1fa6fe is located in stack of thread T0 at offset 30 in frame + #0 0x00014002f3bf in node_execute /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:3719 + + This frame has 3 object(s): + [32, 564) 'sc.i' (line 1864) <== Memory access at offset 30 underflows this variable + [704, 1224) 'temp_path' (line 3763) + [1360, 1880) 'filename' (line 3764) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-underflow /home/bernhard/data/entwicklung/2024/wine/wine/programs/cmd\wcmdmain.c:1591:17 in search_command +Shadow bytes around the buggy address: + 0x7ffffe1fa400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f3 + 0x7ffffe1fa580: f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 + 0x7ffffe1fa600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fa680: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1[f1] + 0x7ffffe1fa700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fa900: 00 00 04 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==556==ABORTING +023c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + programs/cmd/wcmdmain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c +index 1018fd56624..f7f415bf301 100644 +--- a/programs/cmd/wcmdmain.c ++++ b/programs/cmd/wcmdmain.c +@@ -1586,7 +1586,7 @@ static RETURN_CODE search_command(WCHAR *command, struct search_command *sc, BOO + + /* Remove quotes */ + length = wcslen(sc->path); +- if (sc->path[length - 1] == L'"') ++ if (length > 1 && sc->path[length - 1] == L'"') + sc->path[length - 1] = 0; + + if (*sc->path != L'"') +-- +2.47.1 + diff --git a/0015-bernhard-asan/0053-crypt32-Avoid-stack-buffer-overflow-in-CryptSignMess.patch b/0015-bernhard-asan/0053-crypt32-Avoid-stack-buffer-overflow-in-CryptSignMess.patch new file mode 100644 index 0000000..649c4ad --- /dev/null +++ b/0015-bernhard-asan/0053-crypt32-Avoid-stack-buffer-overflow-in-CryptSignMess.patch @@ -0,0 +1,88 @@ +From 8268941ebc0053b9c577fc58a36249f9797eab93 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 19:12:28 +0100 +Subject: [PATCH 53/86] crypt32: Avoid stack-buffer-overflow in + CryptSignMessage. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M crypt32.dll -p dlls/crypt32/tests/x86_64-windows/crypt32_test.exe message && touch dlls/crypt32/tests/x86_64-windows/message.ok +================================================================= +==632==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1ff5f0 at pc 0x6ffff824d3b9 bp 0x7ffffe1fef80 sp 0x7ffffe1fefc8 +READ of size 4 at 0x7ffffe1ff5f0 thread T0 +027c:fixme:dbghelp:elf_search_auxv can't find symbol in module +027c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007E8F33C20B80,symt:0000000000000000) in ctx(00007E8F34E22200,L"crypt32") +027c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007E8F33D90B80,symt:0000000000000000) in ctx(00007E8F34F818E0,L"crypt32_test") + #0 0x6ffff824d3b8 in CryptMsgOpenToEncode Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\msg.c + #1 0x6ffff82473d0 in CryptSignMessage Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\message.c:491 + #2 0x0001400e11ad in func_message+0x728d (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\crypt32\tests\x86_64-windows\crypt32_test.exe+0x1400e11ad) + #3 0x00014015ecb1 in main+0x541 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\crypt32\tests\x86_64-windows\crypt32_test.exe+0x14015ecb1) + #4 0x000140160bbf in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #5 0x6ffffbdc4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #6 0x6ffffad1fa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ff5f0 is located in stack of thread T0 at offset 272 in frame + #0 0x6ffff8246c2f in CryptSignMessage Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\message.c:409 + + This frame has 5 object(s): + [32, 40) 'hCryptProv' (line 410) + [64, 68) 'freeProv' (line 411) + [80, 84) 'keySpec' (line 412) + [96, 144) 'signInfo' (line 415) + [176, 272) 'signer' (line 416) <== Memory access at offset 272 overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\crypt32\msg.c in CryptMsgOpenToEncode +Shadow bytes around the buggy address: + 0x7ffffe1ff300: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ff380: f8 f8 f8 f8 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 + 0x7ffffe1ff400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff480: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1ff500: 00 f2 f2 f2 04 f2 04 f2 00 00 00 00 00 00 f2 f2 +=>0x7ffffe1ff580: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00[f3]f3 + 0x7ffffe1ff600: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff700: f1 f1 f1 f1 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 + 0x7ffffe1ff780: f8 f8 f2 f2 f8 f2 f2 f2 f8 f2 00 00 00 00 00 00 + 0x7ffffe1ff800: 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==632==ABORTING +make: *** [Makefile:36953: dlls/crypt32/tests/x86_64-windows/message.ok] Fehler 1 +--- + dlls/crypt32/msg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c +index 5e6d59a1f58..4cbdf5391b3 100644 +--- a/dlls/crypt32/msg.c ++++ b/dlls/crypt32/msg.c +@@ -1424,8 +1424,8 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags, + ret = FALSE; + for (i = 0; ret && i < msg->msg_data.info->cSignerInfo; i++) + { +- if (info->rgSigners[i].SignerId.dwIdChoice == +- CERT_ID_KEY_IDENTIFIER) ++ if (info->rgSigners[i].cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO_WITH_CMS) && ++ info->rgSigners[i].SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER) + msg->msg_data.info->version = CMSG_SIGNED_DATA_V3; + ret = CSignerInfo_Construct( + &msg->msg_data.info->rgSignerInfo[i], +-- +2.47.1 + diff --git a/0015-bernhard-asan/0054-d2d1-Avoid-buffer-overflow-by-increasing-buffer-size.patch b/0015-bernhard-asan/0054-d2d1-Avoid-buffer-overflow-by-increasing-buffer-size.patch new file mode 100644 index 0000000..96cc7d6 --- /dev/null +++ b/0015-bernhard-asan/0054-d2d1-Avoid-buffer-overflow-by-increasing-buffer-size.patch @@ -0,0 +1,124 @@ +From dad79450fa0c0ba467c769c20629113833700604 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Thu, 12 Dec 2024 01:31:49 +0100 +Subject: [PATCH 54/86] d2d1: Avoid buffer overflow by increasing buffer size. + +0470:err:d2d:d2d_fp_fast_expansion_sum_zeroelim a_idx=3 a_len=4 +================================================================= +==1068==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ecef8a7b6d0 at pc 0x6ffff818b751 bp 0x7ecef8a7b050 sp 0x7ecef8a7b098 +READ of size 4 at 0x7ecef8a7b6d0 thread T16 +0474:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts. +049c:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff818b750 in d2d_fp_fast_expansion_sum_zeroelim /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:317:26 + #1 0x6ffff819ddf3 in d2d_cdt_incircle_refine2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1064:9 + #2 0x6ffff819c7c2 in d2d_cdt_incircle /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1283:9 + #3 0x6ffff8199812 in d2d_cdt_merge /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1447:24 + #4 0x6ffff8199812 in d2d_cdt_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1546:10 + #5 0x6ffff8198e30 in d2d_cdt_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1543:10 + #6 0x6ffff8198df7 in d2d_cdt_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1541:10 + #7 0x6ffff8198df7 in d2d_cdt_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1541:10 + #8 0x6ffff8198df7 in d2d_cdt_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1541:10 + #9 0x6ffff8193f64 in d2d_path_geometry_triangulate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:2347:10 + #10 0x6ffff8193f64 in d2d_geometry_sink_Close /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:3244:9 + #11 0x000140025c84 in ID2D1GeometrySink_Close /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\d2d1.h:2784:12 + #12 0x000140025c84 in test_path_geometry /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:3907:10 + #13 0x0001400fa063 in thread_func /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:439:13 + #14 0x6ffff890b15d in asan_thread_start(void*) /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:147:14 + #15 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #16 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ecef8a7b6d0 is located in stack of thread T16 at offset 1296 in frame + #0 0x6ffff819d85f in d2d_cdt_incircle_refine2 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:1047 + + This frame has 15 object(s): + [32, 288) 'temp64' (line 1049) + [352, 544) 'temp48' (line 1049) + [608, 736) 'temp32a' (line 1049) + [768, 896) 'temp32b' (line 1049) + [928, 992) 'temp16a' (line 1049) + [1024, 1088) 'temp16b' (line 1049) + [1120, 1152) 'temp8' (line 1049) + [1184, 1216) 'bct' (line 1050) + [1248, 1264) 'bctt' (line 1050) + [1280, 1296) 'temp4a' (line 1050) <== Memory access at offset 1296 overflows this variable + [1312, 1328) 'temp4b' (line 1050) + [1344, 1408) 'axt_bct' (line 1082) + [1440, 1472) 'axt_bctt' (line 1082) + [1504, 1568) 'ayt_bct' (line 1124) + [1600, 1632) 'ayt_bctt' (line 1124) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +Thread T16 created by T0 here: + #0 0x6ffff890b076 in CreateThread /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:158:3 + #1 0x000140006389 in run_queued_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:467:22 + #2 0x000140006389 in func_d2d1 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:15540:5 + #3 0x0001400fbb13 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001400fb55b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #5 0x0001400fd4ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/geometry.c:317:26 in d2d_fp_fast_expansion_sum_zeroelim +Shadow bytes around the buggy address: + 0x7ecef8a7b400: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ecef8a7b480: 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00 00 + 0x7ecef8a7b500: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 00 + 0x7ecef8a7b580: 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00 00 + 0x7ecef8a7b600: f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00 +=>0x7ecef8a7b680: f2 f2 f2 f2 00 00 f2 f2 00 00[f2]f2 00 00 f2 f2 + 0x7ecef8a7b700: f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 + 0x7ecef8a7b780: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 + 0x7ecef8a7b800: f8 f8 f8 f8 f3 f3 f3 f3 00 00 00 00 00 00 00 00 + 0x7ecef8a7b880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ecef8a7b900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1068==ABORTING +049c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:41397: dlls/d2d1/tests/x86_64-windows/d2d1.ok] Fehler 1 +--- + dlls/d2d1/geometry.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c +index 3da3ad2e65b..7e71065b192 100644 +--- a/dlls/d2d1/geometry.c ++++ b/dlls/d2d1/geometry.c +@@ -1046,7 +1046,7 @@ static void d2d_cdt_incircle_refine2(struct d2d_fp_fin *fin, const struct d2d_fp + { + size_t temp64_len, temp48_len, temp32a_len, temp32b_len, temp16a_len, temp16b_len, temp8_len; + float temp64[64], temp48[48], temp32a[32], temp32b[32], temp16a[16], temp16b[16], temp8[8]; +- float bct[8], bctt[4], temp4a[4], temp4b[4], temp2a[2], temp2b[2]; ++ float bct[8], bctt[4], temp4a[5], temp4b[5], temp2a[2], temp2b[2]; + size_t bct_len, bctt_len; + float *swap; + +@@ -1171,7 +1171,7 @@ static BOOL d2d_cdt_incircle(const struct d2d_cdt *cdt, size_t a, size_t b, size + + size_t axt_det_bc_len, ayt_det_bc_len, bxt_det_ca_len, byt_det_ca_len, cxt_det_ab_len, cyt_det_ab_len; + float axt_det_bc[8], ayt_det_bc[8], bxt_det_ca[8], byt_det_ca[8], cxt_det_ab[8], cyt_det_ab[8]; +- float fin1[1152], fin2[1152], temp64[64], sub_det_a[32], sub_det_b[32], sub_det_c[32]; ++ float fin1[1152], fin2[1152], temp64[64], sub_det_a[33], sub_det_b[32], sub_det_c[32]; + float det_bc[4], det_ca[4], det_ab[4], daz[4], dbz[4], dcz[4], temp2a[2], temp2b[2]; + size_t temp64_len, sub_det_a_len, sub_det_b_len, sub_det_c_len; + float dbxdcy, dbydcx, dcxday, dcydax, daxdby, daydbx; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0055-d3dcompiler_43-Over-reserve-memory-to-avoid-buffer-o.patch b/0015-bernhard-asan/0055-d3dcompiler_43-Over-reserve-memory-to-avoid-buffer-o.patch new file mode 100644 index 0000000..981ee07 --- /dev/null +++ b/0015-bernhard-asan/0055-d3dcompiler_43-Over-reserve-memory-to-avoid-buffer-o.patch @@ -0,0 +1,97 @@ +From 6435ed9b964f16d43f8de74ef39a0ea1bd467a8d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 22:45:21 +0100 +Subject: [PATCH 55/86] d3dcompiler_43: Over-reserve memory to avoid + buffer-overflow. (ASan) + +effect.c:8932: Test failed: :8932 +01a8:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 15.0.6, 256 bits)"). +01a8:err:d3dcompiler:D3DCompile2 Failed to compile shader, vkd3d result -5. +01a8:err:d3dcompiler:D3DCompile2 Shader log: +01a8:err:d3dcompiler:D3DCompile2 :30:1: E5017: Aborting due to not yet implemented feature: Write pass assignments. +01a8:err:d3dcompiler:D3DCompile2 +================================================================= +==420==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f43cf38067e at pc 0x6ffff826aa11 bp 0x7ffffe1fe460 sp 0x7ffffe1fe4a8 +READ of size 1 at 0x7f43cf38067e thread T0 +01a8:fixme:dbghelp:elf_search_auxv can't find symbol in module +01a8:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F3315530B80,symt:0000000000000000) in ctx(00007F33442B1D20,L"d3dx9_36") +01a8:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r15/343 -> rbx/329) +01a8:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F3315620B80,symt:0000000000000000) in ctx(00007F3344721590,L"d3dx9_36_test") + #0 0x6ffff826aa10 in D3DXCreateEffectEx Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6723 + #1 0x6ffff826b14e in D3DXCreateEffectFromFileExW Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6936 + #2 0x00014003a95b in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8937 + #3 0x0001401afd37 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1401afd37) + #4 0x0001401b1c8f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #5 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #6 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f43cf38067e is located 0 bytes after 94-byte region [0x7f43cf380620,0x7f43cf38067e) +allocated by thread T0 here: +01a8:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F3307690B80,symt:0000000000000000) in ctx(00007F3334DC4A20,L"libclang_rt.asan_dynamic-x86_64") +01a8:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F3314A70B80,symt:0000000000000000) in ctx(00007F33442712A0,L"d3dcompiler_47") + #0 0x6ffff88fa3d6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a3d6) + #1 0x6ffff812acef in D3DCreateBlob Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dcompiler_43\blob.c + #2 0x6ffff813f5fe in D3DCompile2 Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dcompiler_43\compiler.c:596 + #3 0x6ffff813ff4c in D3DCompile Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dcompiler_43\compiler.c:648 + #4 0x6ffff826a3bd in D3DXCreateEffectEx Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c + #5 0x6ffff826b14e in D3DXCreateEffectFromFileExW Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6936 + #6 0x00014003a95b in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8937 + #7 0x0001401afd37 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1401afd37) + #8 0x0001401b1c8f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #9 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #10 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6723 in D3DXCreateEffectEx +Shadow bytes around the buggy address: + 0x7f43cf380380: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 06 + 0x7f43cf380400: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 07 + 0x7f43cf380480: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f43cf380500: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f43cf380580: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd +=>0x7f43cf380600: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00[06] + 0x7f43cf380680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f43cf380700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f43cf380780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f43cf380800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f43cf380880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==420==ABORTING +make: *** [Makefile:105962: dlls/d3dx9_36/tests/x86_64-windows/effect.ok] Fehler 1 +--- + dlls/d3dcompiler_43/blob.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d3dcompiler_43/blob.c b/dlls/d3dcompiler_43/blob.c +index f5bcb5f8fa3..a36137b4ef9 100644 +--- a/dlls/d3dcompiler_43/blob.c ++++ b/dlls/d3dcompiler_43/blob.c +@@ -120,7 +120,7 @@ static HRESULT d3dcompiler_blob_init(struct d3dcompiler_blob *blob, SIZE_T data_ + blob->refcount = 1; + blob->size = data_size; + +- blob->data = calloc(1, data_size); ++ blob->data = calloc(2, data_size); + if (!blob->data) + { + ERR("Failed to allocate D3D blob data memory\n"); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0056-d3dx9_36-Set-pointer-to-NULL-after-free.-ASan.patch b/0015-bernhard-asan/0056-d3dx9_36-Set-pointer-to-NULL-after-free.-ASan.patch new file mode 100644 index 0000000..15ec58e --- /dev/null +++ b/0015-bernhard-asan/0056-d3dx9_36-Set-pointer-to-NULL-after-free.-ASan.patch @@ -0,0 +1,71 @@ +From 386b56245b2de1648dc4b7445d53f367bf831a30 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 22:32:30 +0100 +Subject: [PATCH 56/86] d3dx9_36: Set pointer to NULL after free. (ASan) + +0364:err:d3dx:d3dx9_effect_init_from_binary :6536 +================================================================= +==864==ERROR: AddressSanitizer: attempting to call malloc_usable_size() for pointer which is not owned: 0x7f2443aad420 +0364:fixme:dbghelp:elf_search_auxv can't find symbol in module +0364:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F1D8AA80B80,symt:0000000000000000) in ctx(00007F1DD4084A20,L"libclang_rt.asan_dynamic-x86_64") +0364:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r13/341 -> r14/342) +0364:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F1D948C0B80,symt:0000000000000000) in ctx(00007F1DD4341D20,L"d3dx9_36") +0364:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r15/343 -> rbx/329) +0364:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F1D949B0B80,symt:0000000000000000) in ctx(00007F1DD47B1590,L"d3dx9_36_test") + #0 0x6ffff88fa0f2 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a0f2) + #1 0x6ffff8271408 in d3dx9_effect_init_from_binary Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c + #2 0x6ffff826a2ee in D3DXCreateEffectEx Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6717 + #3 0x6ffff826ab2f in D3DXCreateEffect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6740 + #4 0x00014008c3fd in test_effect_shared_parameters Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:6802 + #5 0x0001400494f9 in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8917 + #6 0x0001402233a7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1402233a7) + #7 0x0001402252ff in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #8 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #9 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f2443aad420 is located 0 bytes inside of 32-byte region [0x7f2443aad420,0x7f2443aad440) +freed by thread T0 here: + #0 0x6ffff88fa1a1 in free+0x81 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a1a1) + #1 0x6ffff82694c4 in free_top_level_parameter Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c + #2 0x6ffff8274324 in d3dx_effect_Release Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c + #3 0x00014008c3b0 in test_effect_shared_parameters Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:6800 + #4 0x0001400494f9 in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8917 + #5 0x0001402233a7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1402233a7) + #6 0x0001402252ff in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #7 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #8 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff88fa3d6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a3d6) + #1 0x6ffff8271408 in d3dx9_effect_init_from_binary Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c + #2 0x6ffff826a2ee in D3DXCreateEffectEx Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6717 + #3 0x6ffff826ab2f in D3DXCreateEffect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c:6740 + #4 0x00014008be15 in test_effect_shared_parameters Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:6788 + #5 0x0001400494f9 in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8917 + #6 0x0001402233a7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1402233a7) + #7 0x0001402252ff in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #8 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #9 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: bad-malloc_usable_size Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\effect.c in d3dx9_effect_init_from_binary +==864==ABORTING +make: *** [Makefile:105962: dlls/d3dx9_36/tests/x86_64-windows/effect.ok] Fehler 1 +--- + dlls/d3dx9_36/effect.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c +index 628d8ebc3eb..8110a932db9 100644 +--- a/dlls/d3dx9_36/effect.c ++++ b/dlls/d3dx9_36/effect.c +@@ -1944,6 +1944,7 @@ static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter * + { + free(param->shared_data->parameters); + /* Zeroing table size is required as the entry in pool parameters table can be reused. */ ++ param->shared_data->parameters = NULL; + param->shared_data->size = 0; + param->shared_data = NULL; + } +-- +2.47.1 + diff --git a/0015-bernhard-asan/0057-d3dx9_36-tests-Start-iteration-with-1-to-avoid-buffe.patch b/0015-bernhard-asan/0057-d3dx9_36-tests-Start-iteration-with-1-to-avoid-buffe.patch new file mode 100644 index 0000000..75d0787 --- /dev/null +++ b/0015-bernhard-asan/0057-d3dx9_36-tests-Start-iteration-with-1-to-avoid-buffe.patch @@ -0,0 +1,89 @@ +From 1cf4864c496c7edbedd3dada684af956c3d28058 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 14:54:39 +0100 +Subject: [PATCH 57/86] d3dx9_36/tests: Start iteration with 1 to avoid buffer + underflow. + +029c:fixme:d3dx:d3dx9_effect_compiler_init ID3DXEffectCompiler implementation is only a stub. +================================================================= +==664==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fd38c at pc 0x00014006ace1 bp 0x7ffffe1fd200 sp 0x7ffffe1fd248 +READ of size 4 at 0x7ffffe1fd38c thread T0 +029c:fixme:dbghelp:elf_search_auxv can't find symbol in module +029c:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r15/343 -> rbx/329) +029c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007EDE3C520B80,symt:0000000000000000) in ctx(00007EDE80471590,L"d3dx9_36_test") + #0 0x00014006ace0 in test_effect_parameter_value Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c + #1 0x00014003dd81 in func_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:8904 + #2 0x000140223327 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x140223327) + #3 0x00014022527f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #4 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #5 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fd38c is located in stack of thread T0 at offset 268 in frame + #0 0x00014005e66f in test_effect_parameter_value Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c:1953 + + This frame has 9 object(s): + [32, 56) 'edesc' (line 1962) + [96, 104) 'effect' (line 1963) + [128, 184) 'pdesc' (line 1981) + [224, 228) 'bvalue' (line 1982) + [240, 244) 'ivalue' (line 1983) + [256, 260) 'fvalue' (line 1984) + [272, 464) 'input_value' (line 1985) <== Memory access at offset 268 underflows this variable + [528, 720) 'expected_value' (line 1986) + [784, 808) 'matrix_pointer_array' (line 1988) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\tests\effect.c in test_effect_parameter_value +Shadow bytes around the buggy address: + 0x7ffffe1fd100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd280: f1 f1 f1 f1 00 00 00 f2 f2 f2 f2 f2 00 f2 f2 f2 + 0x7ffffe1fd300: 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 04 f2 04 f2 +=>0x7ffffe1fd380: 04[f2]00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd400: 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fd480: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd500: 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fd580: f2 f2 00 00 00 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 + 0x7ffffe1fd600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==664==ABORTING +make: *** [Makefile:105962: dlls/d3dx9_36/tests/x86_64-windows/effect.ok] Fehler 1 +--- + dlls/d3dx9_36/tests/effect.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c +index be0a181885d..c55019f0f7a 100644 +--- a/dlls/d3dx9_36/tests/effect.c ++++ b/dlls/d3dx9_36/tests/effect.c +@@ -2258,7 +2258,7 @@ static void test_effect_parameter_value(IDirect3DDevice9 *device) + + /* SetIntArray */ + *input_value = 123456; +- for (l = 0; l < res[k].bytes / sizeof(*input_value); ++l) ++ for (l = 1; l < res[k].bytes / sizeof(*input_value); ++l) + { + *(input_value + l) = *(input_value + l - 1) + 23; + } +-- +2.47.1 + diff --git a/0015-bernhard-asan/0058-d3dx9_36-tests-Increase-array-size-to-avoid-buffer-o.patch b/0015-bernhard-asan/0058-d3dx9_36-tests-Increase-array-size-to-avoid-buffer-o.patch new file mode 100644 index 0000000..ec784d3 --- /dev/null +++ b/0015-bernhard-asan/0058-d3dx9_36-tests-Increase-array-size-to-avoid-buffer-o.patch @@ -0,0 +1,122 @@ +From 675110836008f8734d4b451eb39f200241fbe6da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 10:56:21 +0100 +Subject: [PATCH 58/86] d3dx9_36/tests: Increase array size to avoid buffer + overflow. (ASan) + +0748:fixme:d3dx:d3dx_load_pixels_from_pixels Unhandled filter 0x80004. +================================================================= +==1860==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1ffae0 at pc 0x6ffff833fa4f bp 0x7ffffe1febb0 sp 0x7ffffe1febf8 +READ of size 1 at 0x7ffffe1ffae0 thread T0 +0748:fixme:dbghelp:elf_search_auxv can't find symbol in module +0748:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F40437B0B80,symt:0000000000000000) in ctx(00007F4088051D20,L"d3dx9_36") +0748:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r15/343 -> rbx/329) +0748:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F40438A0B80,symt:0000000000000000) in ctx(00007F40881B1590,L"d3dx9_36_test") + #0 0x6ffff833fa4e in get_relevant_argb_components Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c + #1 0x6ffff834107b in point_filter_argb_pixels Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2325 + #2 0x6ffff8342d98 in d3dx_load_pixels_from_pixels Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2644 + #3 0x6ffff8342f0e in d3dx_load_pixels_from_pixels Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2593 + #4 0x6ffff8363a33 in d3dx_load_volume_from_memory Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\volume.c:140 + #5 0x6ffff836324a in D3DXLoadVolumeFromMemory Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\volume.c:175 + #6 0x0001401fcdbc in func_volume+0x285c (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1401fcdbc) + #7 0x00014020bec7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x14020bec7) + #8 0x00014020de1f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #9 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #10 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ffae0 is located in stack of thread T0 at offset 672 in frame + #0 0x0001401fa56f in func_volume+0xf (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1401fa56f) + + This frame has 15 object(s): + [32, 56) 'src_box.i63' (line 219) + [96, 124) 'desc.i' (line 221) + [160, 188) 'img_info.i' (line 222) + [224, 232) 'volume.i64' (line 223) + [256, 272) 'locked_box.i65' (line 224) + [288, 312) 'volume_rb.i' (line 225) + [352, 360) 'volume_texture.i66' (line 226) + [384, 408) 'src_box.i' (line 54) + [448, 472) 'dst_box.i' (line 54) + [512, 528) 'locked_box.i' (line 55) + [544, 552) 'volume.i' (line 56) + [576, 584) 'volume_texture.i' (line 57) + [608, 672) 'pixels.i' (line 58) <== Memory access at offset 672 overflows this variable + [704, 712) 'device' (line 399) + [736, 800) 'd3dpp' (line 400) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c in get_relevant_argb_components +Shadow bytes around the buggy address: + 0x7ffffe1ff800: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2 + 0x7ffffe1ff880: f2 f2 f2 f2 f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 + 0x7ffffe1ff900: f2 f2 f2 f2 f8 f2 f2 f2 f8 f8 f2 f2 f8 f8 f8 f2 + 0x7ffffe1ff980: f2 f2 f2 f2 f8 f2 f2 f2 00 00 00 f2 f2 f2 f2 f2 + 0x7ffffe1ffa00: 00 00 00 f2 f2 f2 f2 f2 00 00 f2 f2 00 f2 f2 f2 +=>0x7ffffe1ffa80: 00 f2 f2 f2 00 00 00 00 00 00 00 00[f2]f2 f2 f2 + 0x7ffffe1ffb00: 00 f2 f2 f2 00 00 00 00 00 00 00 00 f3 f3 f3 f3 + 0x7ffffe1ffb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffd00: f1 f1 f1 f1 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1860==ABORTING +make: *** [Makefile:106898: dlls/d3dx9_36/tests/x86_64-windows/volume.ok] Fehler 1 +--- + dlls/d3dx9_36/tests/volume.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/dlls/d3dx9_36/tests/volume.c b/dlls/d3dx9_36/tests/volume.c +index d7529eb486c..21ff47a896d 100644 +--- a/dlls/d3dx9_36/tests/volume.c ++++ b/dlls/d3dx9_36/tests/volume.c +@@ -58,7 +58,11 @@ static void test_D3DXLoadVolumeFromMemory(IDirect3DDevice9 *device) + const DWORD pixels[] = { 0xc3394cf0, 0x235ae892, 0x09b197fd, 0x8dc32bf6, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +- 0xffffffff, 0x00000000, 0xffffffff, 0x00000000 }; ++ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, ++ 0x11111111, 0x11111111, 0x11111111, 0x11111111, ++ 0x22222222, 0x22222222, 0x22222222, 0x22222222, ++ 0x33333333, 0x33333333, 0x33333333, 0x33333333, ++ 0x44444444, 0x44444444, 0x44444444, 0x44444444}; + + hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, + &volume_texture, NULL); +@@ -98,14 +102,14 @@ static void test_D3DXLoadVolumeFromMemory(IDirect3DDevice9 *device) + + set_box(&src_box, 0, 0, 4, 4, 0, 1); + set_box(&dst_box, 0, 0, 4, 4, 0, 1); +- hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels), NULL, &src_box, D3DX_DEFAULT, 0); ++ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels)-64, NULL, &src_box, D3DX_DEFAULT, 0); + ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#lx, expected %#lx\n", hr, D3D_OK); + + IDirect3DVolume9_LockBox(volume, &locked_box, &dst_box, D3DLOCK_READONLY); + for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, i / 4, 0, pixels[i]); + IDirect3DVolume9_UnlockBox(volume); + +- hr = D3DXLoadVolumeFromMemory(volume, NULL, NULL, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels), NULL, &src_box, D3DX_FILTER_NONE, 0); ++ hr = D3DXLoadVolumeFromMemory(volume, NULL, NULL, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels)-64, NULL, &src_box, D3DX_FILTER_NONE, 0); + ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#lx, expected %#lx\n", hr, D3D_OK); + + IDirect3DVolume9_LockBox(volume, &locked_box, NULL, D3DLOCK_READONLY); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0059-d3d10-Alloc-more-buffer-to-avoid-buffer-overflow.patch b/0015-bernhard-asan/0059-d3d10-Alloc-more-buffer-to-avoid-buffer-overflow.patch new file mode 100644 index 0000000..2dac2e6 --- /dev/null +++ b/0015-bernhard-asan/0059-d3d10-Alloc-more-buffer-to-avoid-buffer-overflow.patch @@ -0,0 +1,100 @@ +From 2065c15bf17799efea7c983da7c1912db58baf5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 14:04:39 +0100 +Subject: [PATCH 59/86] d3d10: Alloc more buffer to avoid buffer-overflow. + +effect.c:10018: Test failed: :10018 +0560:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 15.0.6, 256 bits)"). +0560:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION +0560:err:d3d10:parse_fx10_buffer l->u.buffer.local_buffer=00007F8D82F86840 l->data_size=0x90 +effect.c:7968: Test failed: blend_factor=00007FFFFE1FFB50 :7968 +0560:err:d3d10:d3d10_effect_preshader_eval dst + v->offset=00007F7782F80B90, v->v->buffer->u.buffer.local_buffer + v->v->buffer_offset=00007F8D82F868C4, v->length * sizeof(*dst)=0x10 +0560:err:d3d10:d3d10_effect_preshader_eval v->v->buffer->u.buffer.local_buffer=00007F8D82F86840, v->v->buffer_offset=0x84, v->length=0x4, sizeof(*dst)=0x4 +0560:err:d3d10:d3d10_effect_preshader_eval v->v->buffer->data_size=0x90 +================================================================= +==1372==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f8d82f868d0 at pc 0x6ffff88f8bfb bp 0x7ffffe1fec30 sp 0x7ffffe1fec78 +READ of size 16 at 0x7f8d82f868d0 thread T0 +0560:fixme:dbghelp:elf_search_auxv can't find symbol in module +0560:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F72CA140B80,symt:0000000000000000) in ctx(00007F72F8664A20,L"libclang_rt.asan_dynamic-x86_64") +0560:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r13/341 -> rbx/329) +0560:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r13/341 -> rbx/329) +0560:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r13/341 -> rbx/329) +0560:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F72D8120B80,symt:0000000000000000) in ctx(00007F73181711B0,L"d3d10") +0560:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F72D8050B80,symt:0000000000000000) in ctx(00007F73185D0F10,L"d3d10_test") + #0 0x6ffff88f8bfa in __asan_memcpy+0x3aa (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x180048bfa) + #1 0x6ffff84f23f8 in d3d10_effect_preshader_eval Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:946 + #2 0x6ffff84f140a in d3d10_effect_update_dependent_props Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:1391 + #3 0x6ffff8508cfe in d3d10_effect_pass_Apply Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:5487 + #4 0x000140008362 in func_effect+0x2032 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3d10\tests\x86_64-windows\d3d10_test.exe+0x140008362) + #5 0x000140049a3c in main+0x50c (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3d10\tests\x86_64-windows\d3d10_test.exe+0x140049a3c) + #6 0x00014004a77f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #7 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #8 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f8d82f868d0 is located 0 bytes after 144-byte region [0x7f8d82f86840,0x7f8d82f868d0) +allocated by thread T0 here: + #0 0x6ffff88fa3d6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a3d6) + #1 0x6ffff84db063 in parse_fx10_buffer Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:3895 + #2 0x6ffff84d77e7 in d3d10_effect_parse Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:4341 + #3 0x6ffff84da310 in d3d10_create_effect Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:10124 + #4 0x6ffff84da0d7 in D3D10CreateEffectFromMemory Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:10155 + #5 0x00014000665c in func_effect+0x32c (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3d10\tests\x86_64-windows\d3d10_test.exe+0x14000665c) + #6 0x000140049a3c in main+0x50c (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3d10\tests\x86_64-windows\d3d10_test.exe+0x140049a3c) + #7 0x00014004a77f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #8 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #9 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d10\effect.c:946 in d3d10_effect_preshader_eval +Shadow bytes around the buggy address: + 0x7f8d82f86600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f8d82f86680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f8d82f86700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f8d82f86780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f8d82f86800: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 +=>0x7f8d82f86880: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa + 0x7f8d82f86900: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f8d82f86980: fd fd fd fd fa fa fa fa fa fa fa fa 00 00 00 00 + 0x7f8d82f86a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa + 0x7f8d82f86a80: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd + 0x7f8d82f86b00: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1372==ABORTING +make: *** [Makefile:42668: dlls/d3d10/tests/x86_64-windows/effect.ok] Fehler 1 +--- + dlls/d3d10/effect.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c +index 02e71e4dcee..acaff7984a3 100644 +--- a/dlls/d3d10/effect.c ++++ b/dlls/d3d10/effect.c +@@ -3889,7 +3889,7 @@ static HRESULT parse_fx10_buffer(const char *data, size_t data_size, const char + return E_OUTOFMEMORY; + } + +- if (local && !(l->u.buffer.local_buffer = calloc(1, l->data_size))) ++ if (local && !(l->u.buffer.local_buffer = calloc(1, l->data_size + 4))) + { + ERR("Failed to allocate local constant buffer memory.\n"); + return E_OUTOFMEMORY; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0060-dbghelp-Avoid-division-by-zero-in-compute_location.patch b/0015-bernhard-asan/0060-dbghelp-Avoid-division-by-zero-in-compute_location.patch new file mode 100644 index 0000000..d6e528a --- /dev/null +++ b/0015-bernhard-asan/0060-dbghelp-Avoid-division-by-zero-in-compute_location.patch @@ -0,0 +1,31 @@ +From 18ca7761a113991d0ae2fd56f6089b7faa9db4d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 21 Oct 2024 11:10:46 +0200 +Subject: [PATCH 60/86] dbghelp: Avoid division by zero in compute_location. + +This showed up when ASAN tried to show the call stack with +a x86_64 Wine built by llvm-mingw. +--- + dlls/dbghelp/dwarf.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c +index 84e861890d5..76d6e183a69 100644 +--- a/dlls/dbghelp/dwarf.c ++++ b/dlls/dbghelp/dwarf.c +@@ -896,8 +896,10 @@ compute_location(const struct module *module, const dwarf2_cuhead_t* head, + case DW_OP_shl: stack[stk-1] <<= stack[stk]; stk--; break; + case DW_OP_shr: stack[stk-1] >>= stack[stk]; stk--; break; + case DW_OP_plus_uconst: stack[stk] += dwarf2_leb128_as_unsigned(ctx); break; +- case DW_OP_shra: stack[stk-1] = stack[stk-1] / (1 << stack[stk]); stk--; break; +- case DW_OP_div: stack[stk-1] = stack[stk-1] / stack[stk]; stk--; break; ++ case DW_OP_shra: if (!stack[stk]) return loc_err_internal; ++ stack[stk-1] = stack[stk-1] / (1 << stack[stk]); stk--; break; ++ case DW_OP_div: if (!stack[stk]) return loc_err_internal; ++ stack[stk-1] = stack[stk-1] / stack[stk]; stk--; break; + case DW_OP_mod: stack[stk-1] = stack[stk-1] % stack[stk]; stk--; break; + case DW_OP_ge: stack[stk-1] = (stack[stk-1] >= stack[stk]); stk--; break; + case DW_OP_gt: stack[stk-1] = (stack[stk-1] > stack[stk]); stk--; break; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0061-dsound-tests-Reduce-cbSize.patch b/0015-bernhard-asan/0061-dsound-tests-Reduce-cbSize.patch new file mode 100644 index 0000000..cb0432b --- /dev/null +++ b/0015-bernhard-asan/0061-dsound-tests-Reduce-cbSize.patch @@ -0,0 +1,119 @@ +From 5509a0c6eab8be6fcce49a86d21723694a8bba63 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 14:54:23 +0100 +Subject: [PATCH 61/86] dsound/tests: Reduce cbSize. + +================================================================= +==44==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1febb8 at pc 0x6ffff8e88bfb bp 0x7ffffe1fdf50 sp 0x7ffffe1fdf98 +READ of size 58 at 0x7ffffe1febb8 thread T0 +01f4:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff8e88bfa in __asan_memcpy /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_interceptors_memintrinsics.cpp:63:3 + #1 0x6ffff8a4dba3 in DSOUND_CopyFormat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/primary.c:422:9 + #2 0x6ffff8a21421 in secondarybuffer_create /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/buffer.c:1066:14 + #3 0x6ffff8a36a27 in DirectSoundDevice_CreateSoundBuffer /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound.c:554:16 + #4 0x6ffff8a36a27 in IDirectSound8Impl_CreateSoundBuffer /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound.c:792:12 + #5 0x0001400624e9 in test_secondary8 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/tests/dsound8.c:828:16 + #6 0x0001400624e9 in dsenum_callback /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/tests/dsound8.c:931:9 + #7 0x6ffff8a3ce5b in a_to_w_callback /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound_main.c:304:12 + #8 0x6ffff8a3dc53 in enumerate_mmdevices /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound_main.c:482:18 + #9 0x6ffff8a3cbc4 in DirectSoundEnumerateW /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound_main.c:551:10 + #10 0x6ffff8a3cbc4 in DirectSoundEnumerateA /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/dsound_main.c:334:12 + #11 0x00014004dfba in dsound8_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/tests/dsound8.c:940:10 + #12 0x00014004dfba in func_dsound8 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/tests/dsound8.c:1942:5 + #13 0x00014007ba30 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #14 0x00014007ba30 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #15 0x00014007d8ff in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #16 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #17 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1febb8 is located in stack of thread T0 at offset 504 in frame + #0 0x00014005d1af in dsenum_callback /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/tests/dsound8.c:918 + + This frame has 31 object(s): + [32, 40) 'dso.i149' (line 685) + [64, 72) 'primary.i150' (line 686) + [96, 104) 'secondary.i151' (line 686) + [128, 168) 'bufdesc.i152' (line 687) + [208, 304) 'dscaps.i153' (line 688) + [336, 354) 'wfx.i154' (line 689) + [400, 418) 'wfx1.i' (line 689) + [464, 504) 'wfxe.i' (line 731) + [544, 552) 'dso.i96' (line 544) <== Memory access at offset 504 partially underflows this variable + [576, 584) 'primary.i97' (line 545) + [608, 616) 'secondary.i98' (line 545) + [640, 680) 'bufdesc.i99' (line 546) + [720, 816) 'dscaps.i100' (line 547) + [848, 866) 'wfx.i101' (line 548) + [912, 930) 'wfx2.i' (line 548) + [976, 984) 'dso.i62' (line 394) + [1008, 1016) 'primary.i' (line 395) + [1040, 1048) 'second.i' (line 395) + [1072, 1080) 'third.i' (line 395) + [1104, 1112) 'pb8.i' (line 396) + [1136, 1176) 'bufdesc.i63' (line 397) + [1216, 1312) 'dscaps.i' (line 398) + [1344, 1362) 'wfx.i64' (line 399) + [1408, 1412) 'vol.i' (line 479) + [1424, 1432) 'dso.i' (line 281) + [1456, 1464) 'dso1.i' (line 310) + [1488, 1496) 'secondary.i' (line 337) + [1520, 1560) 'bufdesc.i' (line 338) + [1600, 1618) 'wfx.i' (line 339) + [1664, 1672) 'buffer3d.i' (line 353) + [1696, 1704) 'buffer8.i' (line 354) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dsound/primary.c:422:9 in DSOUND_CopyFormat +Shadow bytes around the buggy address: + 0x7ffffe1fe900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fe980: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2 + 0x7ffffe1fea00: 00 f2 f2 f2 00 f2 f2 f2 00 00 00 00 00 f2 f2 f2 + 0x7ffffe1fea80: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 + 0x7ffffe1feb00: f2 f2 00 00 02 f2 f2 f2 f2 f2 00 00 02 f2 f2 f2 +=>0x7ffffe1feb80: f2 f2 00 00 00 00 00[f2]f2 f2 f2 f2 f8 f2 f2 f2 + 0x7ffffe1fec00: f8 f2 f2 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f2 f2 f2 + 0x7ffffe1fec80: f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 + 0x7ffffe1fed00: f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 + 0x7ffffe1fed80: f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1fee00: f2 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==44==ABORTING +01f4:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:158626: dlls/dsound/tests/x86_64-windows/dsound8.ok] Fehler 1 +--- + dlls/dsound/tests/dsound8.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/dsound/tests/dsound8.c b/dlls/dsound/tests/dsound8.c +index e95800af83e..9f09dffc3be 100644 +--- a/dlls/dsound/tests/dsound8.c ++++ b/dlls/dsound/tests/dsound8.c +@@ -824,6 +824,7 @@ static HRESULT test_secondary8(LPGUID lpGuid) + secondary=NULL; + } + ++ wfxe.Format.cbSize = sizeof(wfxe) - sizeof(WAVEFORMATEX); + wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); + rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + ok(rc==DS_OK && secondary, +-- +2.47.1 + diff --git a/0015-bernhard-asan/0062-dwrite-Avoid-heap-buffer-overflow.patch b/0015-bernhard-asan/0062-dwrite-Avoid-heap-buffer-overflow.patch new file mode 100644 index 0000000..4a5595d --- /dev/null +++ b/0015-bernhard-asan/0062-dwrite-Avoid-heap-buffer-overflow.patch @@ -0,0 +1,109 @@ +From 872014f2a491a272219cc8edfc49b7a7ee6e1ef3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 20:26:38 +0100 +Subject: [PATCH 62/86] dwrite: Avoid heap-buffer-overflow. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M dwrite.dll -p dlls/dwrite/tests/x86_64-windows/dwrite_test.exe layout && touch dlls/dwrite/tests/x86_64-windows/layout.ok +================================================================= +==1896==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7efe432f1c52 at pc 0x6ffff849c9eb bp 0x7ffffe1fc180 sp 0x7ffffe1fc1c8 +READ of size 2 at 0x7efe432f1c52 thread T0 +051c:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff849c9ea in get_cluster_length /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/analyzer.c:1858:32 + #1 0x6ffff849c9ea in dwritetextanalyzer1_ApplyCharacterSpacing /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/analyzer.c:1917:31 + #2 0x6ffff850a8af in IDWriteTextAnalyzer2_ApplyCharacterSpacing /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite_2.h:1925:12 + #3 0x6ffff850a8af in layout_shape_apply_character_spacing /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1073:9 + #4 0x6ffff850a8af in layout_shape_get_positions /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1118:14 + #5 0x6ffff850a8af in layout_shape_run /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1135:14 + #6 0x6ffff850a8af in layout_compute_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1221:13 + #7 0x6ffff850a8af in layout_compute /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1267:10 + #8 0x6ffff8502cf7 in layout_compute_effective_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:2147:10 + #9 0x6ffff84fbdae in layout_update_metrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:3706:12 + #10 0x6ffff84fbdae in dwritetextlayout_GetMetrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:3716:10 + #11 0x6ffff84eb8bd in IDWriteTextLayout_GetMetrics /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite.h:4360:12 + #12 0x6ffff84eb8bd in dwritetrimmingsign_GetMetrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/format.c:824:10 + #13 0x0001400b2bfa in IDWriteInlineObject_GetMetrics /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite.h:2822:12 + #14 0x0001400b2bfa in test_CreateEllipsisTrimmingSign /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:1747:10 + #15 0x0001400b2bfa in func_layout /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:7084:5 + #16 0x00014013a4bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #17 0x00014013a4bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #18 0x00014013c36f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #19 0x6ffffbdc4808 in BaseThreadInitThunk /usr/src/packages/BUILD\dlls/kernel32\thread.c:61:5 + #20 0x6ffffaeffa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7efe432f1c52 is located 0 bytes after 2-byte region [0x7efe432f1c50,0x7efe432f1c52) +allocated by thread T0 here: + #0 0x6ffff91fa276 in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x6ffff850a545 in layout_shape_apply_character_spacing /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1036:24 + #2 0x6ffff850a545 in layout_shape_get_positions /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1118:14 + #3 0x6ffff850a545 in layout_shape_run /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1135:14 + #4 0x6ffff850a545 in layout_compute_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1221:13 + #5 0x6ffff850a545 in layout_compute /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1267:10 + #6 0x6ffff8502cf7 in layout_compute_effective_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:2147:10 + #7 0x6ffff84fbdae in layout_update_metrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:3706:12 + #8 0x6ffff84fbdae in dwritetextlayout_GetMetrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:3716:10 + #9 0x6ffff84eb8bd in IDWriteTextLayout_GetMetrics /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite.h:4360:12 + #10 0x6ffff84eb8bd in dwritetrimmingsign_GetMetrics /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/format.c:824:10 + #11 0x0001400b2bfa in IDWriteInlineObject_GetMetrics /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite.h:2822:12 + #12 0x0001400b2bfa in test_CreateEllipsisTrimmingSign /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:1747:10 + #13 0x0001400b2bfa in func_layout /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:7084:5 + #14 0x00014013a4bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #15 0x00014013a4bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #16 0x00014013c36f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #17 0x6ffffbdc4808 in BaseThreadInitThunk /usr/src/packages/BUILD\dlls/kernel32\thread.c:61:5 + #18 0x6ffffaeffa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/analyzer.c:1858:32 in get_cluster_length +Shadow bytes around the buggy address: + 0x7efe432f1980: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa + 0x7efe432f1a00: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa + 0x7efe432f1a80: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa + 0x7efe432f1b00: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa + 0x7efe432f1b80: fa fa 00 fa fa fa 00 fa fa fa 02 fa fa fa 02 fa +=>0x7efe432f1c00: fa fa 04 fa fa fa 00 fa fa fa[02]fa fa fa fa fa + 0x7efe432f1c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7efe432f1d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7efe432f1d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7efe432f1e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7efe432f1e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1896==ABORTING +make: *** [Makefile:162532: dlls/dwrite/tests/x86_64-windows/layout.ok] Fehler 1 +051c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/dwrite/analyzer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c +index 0fab5b7142e..a26bcf522b7 100644 +--- a/dlls/dwrite/analyzer.c ++++ b/dlls/dwrite/analyzer.c +@@ -1855,7 +1855,7 @@ static inline UINT32 get_cluster_length(UINT16 const *clustermap, UINT32 start, + UINT16 g = clustermap[start]; + UINT32 length = 1; + +- while (start < text_len && clustermap[++start] == g) ++ while ((start + 1) < text_len && clustermap[++start] == g) + length++; + return length; + } +-- +2.47.1 + diff --git a/0015-bernhard-asan/0063-dwrite-Avoid-stack-buffer-overflow-in-arabic_setup_m.patch b/0015-bernhard-asan/0063-dwrite-Avoid-stack-buffer-overflow-in-arabic_setup_m.patch new file mode 100644 index 0000000..5d550f5 --- /dev/null +++ b/0015-bernhard-asan/0063-dwrite-Avoid-stack-buffer-overflow-in-arabic_setup_m.patch @@ -0,0 +1,98 @@ +From 897efdce6c6e2f35e41b40e55a299c9a13debb0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 20:52:57 +0100 +Subject: [PATCH 63/86] dwrite: Avoid stack-buffer-overflow in + arabic_setup_masks. + +Using action with NONE as index overflows the masks array. + +================================================================= +==1648==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fb7dc at pc 0x6ffff854f30b bp 0x7ffffe1fb720 sp 0x7ffffe1fb768 +READ of size 4 at 0x7ffffe1fb7dc thread T0 +0694:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff854f30a in arabic_setup_masks /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/shapers/arabic.c:180:41 + #1 0x6ffff8531ebd in opentype_layout_set_glyph_masks /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/opentype.c:4847:8 + #2 0x6ffff8537bd9 in opentype_layout_apply_gsub_features /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/opentype.c:6128:5 + #3 0x6ffff854d555 in shape_get_glyphs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/shape.c:362:5 + #4 0x6ffff849a954 in dwritetextanalyzer_GetGlyphs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/analyzer.c:1571:10 + #5 0x6ffff8509d46 in IDWriteTextAnalyzer2_GetGlyphs /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite_2.h:1915:12 + #6 0x6ffff8509d46 in layout_shape_get_glyphs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:973:14 + #7 0x6ffff8509d46 in layout_shape_run /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1134:9 + #8 0x6ffff8509d46 in layout_compute_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1221:13 + #9 0x6ffff8509d46 in layout_compute /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:1267:10 + #10 0x6ffff8502d07 in layout_compute_effective_runs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:2147:10 + #11 0x6ffff84fa9d1 in dwritetextlayout_Draw /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/layout.c:3576:10 + #12 0x0001400bccea in IDWriteTextLayout_Draw /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dwrite.h:4354:12 + #13 0x0001400bccea in test_Draw /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:2326:10 + #14 0x0001400bccea in func_layout /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/tests/layout.c:7087:5 + #15 0x00014013a4bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #16 0x00014013a4bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #17 0x00014013c36f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #18 0x6ffffbdc4808 in BaseThreadInitThunk /usr/src/packages/BUILD\dlls/kernel32\thread.c:61:5 + #19 0x6ffffaeffa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fb7dc is located in stack of thread T0 at offset 60 in frame + #0 0x6ffff854ebaf in arabic_setup_masks /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/shapers/arabic.c:145 + + This frame has 1 object(s): + [32, 60) 'masks' (line 147) <== Memory access at offset 60 overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dwrite/shapers/arabic.c:180:41 in arabic_setup_masks +Shadow bytes around the buggy address: + 0x7ffffe1fb500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fb780: 00 00 00 00 f1 f1 f1 f1 00 00 00[04]f3 f3 f3 f3 + 0x7ffffe1fb800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb880: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 + 0x7ffffe1fb900: f8 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fb980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fba00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f2 f8 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1648==ABORTING +make: *** [Makefile:162532: dlls/dwrite/tests/x86_64-windows/layout.ok] Fehler 1 +0694:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/dwrite/shapers/arabic.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/dlls/dwrite/shapers/arabic.c b/dlls/dwrite/shapers/arabic.c +index 92e888d0bd9..ff5fbded3a7 100644 +--- a/dlls/dwrite/shapers/arabic.c ++++ b/dlls/dwrite/shapers/arabic.c +@@ -176,8 +176,10 @@ static void arabic_setup_masks(struct scriptshaping_context *context, + { + enum arabic_shaping_action action = arabic_get_shaping_action(context, i); + if (action != NONE) ++ { + opentype_layout_unsafe_to_break(context, i, i + 1); +- context->glyph_infos[i].mask |= masks[action]; ++ context->glyph_infos[i].mask |= masks[action]; ++ } + } + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0064-gdi32-Do-not-rely-on-termination-in-logfont-conversa.patch b/0015-bernhard-asan/0064-gdi32-Do-not-rely-on-termination-in-logfont-conversa.patch new file mode 100644 index 0000000..31b3147 --- /dev/null +++ b/0015-bernhard-asan/0064-gdi32-Do-not-rely-on-termination-in-logfont-conversa.patch @@ -0,0 +1,309 @@ +From 268c86c3be6b7020973c4944649d8ef35bdebb33 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 4 Dec 2024 22:26:51 +0100 +Subject: [PATCH 64/86] gdi32: Do not rely on termination in logfont + conversations. + +gdi32_test font (ASan) + +bernhard@rechner:~/wine_asan_2024-11-07/drive_c/x86_64$ ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/gdi32/tests/x86_64-windows/gdi32_test.exe font +================================================================= +==1512==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1ff8ec at pc 0x6ffffa6106e9 bp 0x7ffffe1f9a70 sp 0x7ffffe1f9ab8 +READ of size 33 at 0x7ffffe1ff8ec thread T0 +05fc:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffffa6106e8 in strlen /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:425:5 + #1 0x6fffff439388 in MultiByteToWideChar /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernelbase\locale.c:7023:30 + #2 0x6ffffe0e28fa in logfont_AtoW /home/bernhard/data/entwicklung/2024/wine/wine/dlls/gdi32\text.c:784:5 + #3 0x6ffffe0e28fa in CreateFontIndirectA /home/bernhard/data/entwicklung/2024/wine/wine/dlls/gdi32\text.c:868:5 + #4 0x0001400c25be in test_logfont /home/bernhard/data/entwicklung/2024/wine\wine/dlls/gdi32/tests/font.c:220:13 + #5 0x0001400c25be in func_font /home/bernhard/data/entwicklung/2024/wine\wine/dlls/gdi32/tests/font.c:7862:5 + #6 0x0001401bcac1 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #7 0x0001401bcac1 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #8 0x0001401be9cf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #9 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ff8ec is located in stack of thread T0 at offset 21228 in frame + #0 0x0001400c083f in func_font /home/bernhard/data/entwicklung/2024/wine\wine/dlls/gdi32/tests/font.c:7841 + + This frame has 215 object(s): + [32, 92) 'lf.i.i4718' (line 6164) + [128, 148) 'rgm.i.i' (line 6168) + [192, 212) 'vgm.i.i' (line 6168) + [256, 260) 'code.i.i' (line 6169) + [272, 274) 'idx.i.i' (line 6170) + [288, 300) 'abc.i.i' (line 6171) + [320, 332) 'vabc.i.i' (line 6171) + [352, 584) 'otm.i.i' (line 6172) + [656, 658) 'numOfLongVerMetrics.i.i' (line 6173) + [672, 674) 'topSideBearing.i.i' (line 6217) + [688, 948) 'ttf_name.i4719' (line 6252) + [1024, 1044) 'gm.i4720' (line 6255) + [1088, 1090) 'hgi.i' (line 6256) + [1104, 1106) 'vgi.i' (line 6256) + [1120, 1380) 'ttf_name.i4641' (line 7788) + [1456, 1516) 'tm1.i4642' (line 7789) + [1552, 1612) 'tm2.i' (line 7789) + [1648, 1652) 'enum_called.i' (line 7790) + [1664, 1756) 'lf.i4643' (line 7791) + [1792, 1852) 'lf.i4610' (line 7702) + [1888, 1948) 'lf.i4605' (line 7591) + [1984, 2000) 'efnd.i4490' (line 7127) + [2016, 2032) 'efnd_w.i' (line 7128) + [2048, 2308) 'ttf_name.i4491' (line 7129) + [2384, 2644) 'ttf_name2.i' (line 7129) + [2720, 2980) 'ttf_name3.i' (line 7129) + [3056, 3116) 'font.i4492' (line 7130) + [3152, 3244) 'font_w.i' (line 7131) + [3280, 3296) 'efnd.i4424' (line 7055) + [3312, 3572) 'ttf_name.i4425' (line 7056) + [3648, 3908) 'ttf_name_bold.i' (line 7056) + [3984, 4044) 'font.i4426' (line 7057) + [4080, 4340) 'ttf_name.i4357' (line 7009) + [4416, 4476) 'font.i' (line 7010) + [4512, 4516) 'found_font.i' (line 7012) + [4528, 4538) 'glyphs.i4243' (line 6951) + [4560, 4580) 'widths.i' (line 6952) + [4624, 4628) 'width.i' (line 6953) + [4640, 4700) 'lf.i4244' (line 6954) + [4736, 4796) 'abc.i4245' (line 6955) + [4832, 4844) 'abc1.i' (line 6955) + [4864, 4884) 'text.i' (line 6821) + [4928, 4988) 'lf.i4152' (line 6832) + [5024, 5056) 'facename.i' (line 6834) + [5088, 5132) 'bmi.i' (line 6835) + [5168, 5176) 'hBmp.i.sroa.0' (line 6836) + [5200, 5208) 'hBmp.i.sroa.6' (line 6836) + [5232, 5248) 'pixels.i' (line 6837) + [5264, 5296) 'bmp.i' (line 6840) + [5328, 5384) 'tm.i4153' (line 6841) + [5424, 5456) 'ci.i' (line 6842) + [5488, 5489) 'chr.i' (line 6843) + [5504, 5506) 'code.i' (line 6918) + [5520, 5580) 'lf.i4050' (line 6704) + [5616, 5984) 'data.i4051' (line 6706) + [6048, 6108) 'lf.i3917' (line 6606) + [6144, 6148) 'bufferA.i' (line 6608) + [6160, 6164) 'bufferW.i' (line 6609) + [6176, 6192) 'efd.i3872' (line 6568) + [6208, 6268) 'lf.i3873' (line 6569) + [6304, 6364) 'lf.i3739' (line 6506) + [6400, 6456) 'tm1.i' (line 6508) + [6496, 6552) 'tm.i3740' (line 6508) + [6592, 6652) 'lf.i3687' (line 6323) + [6688, 6720) 'face_name.i3688' (line 6325) + [6752, 6880) 'bufW.i3625' (line 5585) + [6912, 6976) 'bufA.i3626' (line 5586) + [7008, 7068) 'lf.i3627' (line 5588) + [7104, 7164) 'lf.i3582' (line 4607) + [7200, 7260) 'clf.i' (line 4607) + [7296, 7556) 'lfex.i' (line 5082) + [7632, 7692) 'lf.i3509' (line 5051) + [7728, 7788) 'getobj_lf.i' (line 5051) + [7824, 7884) 'lf.i3175' (line 7393) + [7920, 8152) 'otm.i3176' (line 7396) + [8224, 8260) 'hhea.i' (line 7397) + [8304, 8316) 'info.i3177' (line 7398) + [8336, 8348) 'info2.i3178' (line 7398) + [8368, 8384) 'pt.i3179' (line 7403) + [8400, 8460) 'lf.i3090' (line 7601) + [8496, 8556) 'str.i' (line 7606) + [8592, 8656) 'result.i3091' (line 7607) + [8688, 8808) 'kern.i' (line 7608) + [8848, 8968) 'pos.i3092' (line 7608) + [9008, 9128) 'pos_kern.i' (line 7608) + [9168, 9288) 'dx.i' (line 7608) + [9328, 9448) 'dx_kern.i' (line 7608) + [9488, 9552) 'result.i' (line 4996) + [9584, 9624) 'glyphs.i2892' (line 4998) + [9664, 9744) 'pos.i' (line 4999) + [9776, 9836) 'fA.i' (line 4488) + [9872, 9964) 'fW.i' (line 4489) + [10000, 10032) 'bufA.i' (line 4490) + [10064, 10128) 'bufW.i' (line 4491) + [10160, 10696) 'file_info.i' (line 4347) + [10832, 10848) 'info.i' (line 4349) + [10864, 10992) 'info2.i' (line 4349) + [11024, 11028) 'read.i' (line 4349) + [11040, 11048) 'needed.i' (line 4351) + [11072, 11132) 'lf.i2501' (line 4352) + [11168, 11184) 'file.i' (line 4354) + [11200, 11214) 'data.i' (line 4354) + [11232, 11240) 'time.i' (line 4355) + [11264, 11272) 'size.i2502' (line 4356) + [11296, 11352) 'tm.i2476' (line 4105) + [11392, 11452) 'lf.i2477' (line 4106) + [11488, 11492) 'enumed.i' (line 4109) + [11504, 11520) 'efd.i2443' (line 3223) + [11536, 11596) 'target.i' (line 3224) + [11632, 11692) 'enum_font.i' (line 3224) + [11728, 11760) 'csi.i2444' (line 3227) + [11792, 11808) 'efd.i2236' (line 2961) + [11824, 11840) 'efdw.i' (line 2962) + [11856, 11916) 'lf.i2237' (line 2963) + [11952, 11956) 'ansi_charset.i2238' (line 2965) + [11968, 11972) 'symbol_charset.i2239' (line 2965) + [11984, 11988) 'russian_charset.i2240' (line 2965) + [12000, 12016) 'efd.i1966' (line 2961) + [12032, 12092) 'lf.i1967' (line 2963) + [12128, 12132) 'ansi_charset.i1968' (line 2965) + [12144, 12148) 'symbol_charset.i1969' (line 2965) + [12160, 12164) 'russian_charset.i1970' (line 2965) + [12176, 12192) 'efd.i1836' (line 2961) + [12208, 12268) 'lf.i1837' (line 2963) + [12304, 12308) 'ansi_charset.i1838' (line 2965) + [12320, 12324) 'symbol_charset.i1839' (line 2965) + [12336, 12340) 'russian_charset.i1840' (line 2965) + [12352, 12368) 'efd.i1518' (line 2961) + [12384, 12444) 'lf.i1519' (line 2963) + [12480, 12484) 'ansi_charset.i1520' (line 2965) + [12496, 12500) 'symbol_charset.i1521' (line 2965) + [12512, 12516) 'russian_charset.i1522' (line 2965) + [12528, 12544) 'efd.i' (line 2961) + [12560, 12620) 'lf.i1379' (line 2963) + [12656, 12660) 'ansi_charset.i' (line 2965) + [12672, 12676) 'symbol_charset.i' (line 2965) + [12688, 12692) 'russian_charset.i' (line 2965) + [12704, 12764) 'lf.i1321' (line 5501) + [12800, 12816) 'efnd.i' (line 5503) + [12832, 12892) 'lf.i1203' (line 5391) + [12928, 13188) 'tmp_path.i.i.i' (line 139) + [13264, 13268) 'size.i.i' (line 2091) + [13280, 13540) 'ttf_name.i.i' (line 2094) + [13616, 13676) 'lf.i1148' (line 4579) + [13712, 13720) 'size.i1149' (line 4581) + [13744, 13804) 'lf.i895' (line 4159) + [13840, 13872) 'csi.i896' (line 4162) + [13904, 13936) 'buf.i' (line 4164) + [13968, 14028) 'lf.i871' (line 2805) + [14064, 14124) 'lf.i832' (line 2744) + [14160, 14192) 'csi.i763' (line 2593) + [14224, 14232) 'csb.i' (line 2642) + [14256, 14272) 'clientArea.i' (line 2369) + [14288, 14348) 'lf.i698' (line 2370) + [14384, 14392) 'size.i699' (line 2373) + [14416, 14424) 'expect.i' (line 2373) + [14448, 14452) 'indices.i' (line 2375) + [14464, 14524) 'lf.i662' (line 7728) + [14560, 14592) 'face_name.i663' (line 7732) + [14624, 14684) 'lf.i612' (line 2185) + [14720, 14780) 'lf.i517' (line 1782) + [14816, 15048) 'otm.i518' (line 1792) + [15120, 15180) 'lf.i444' (line 1583) + [15216, 15228) 'testtext.i' (line 1585) + [15248, 15252) 'c.i' (line 1586) + [15264, 15274) 'glyphs.i445' (line 1587) + [15296, 15352) 'textm.i' (line 1588) + [15392, 15396) 'num_fonts.i' (line 1591) + [15408, 15668) 'ttf_name.i' (line 1593) + [15744, 15748) 'fit1.i' (line 1403) + [15760, 15764) 'fit2.i' (line 1403) + [15776, 15788) 'extents2.i' (line 1403) + [15808, 15868) 'lf.i300' (line 1404) + [15904, 15960) 'tm.i301' (line 1405) + [16000, 16008) 'sz.i' (line 1408) + [16032, 16040) 'sz1.i' (line 1409) + [16064, 16072) 'sz2.i' (line 1409) + [16096, 16156) 'lf.i198' (line 1113) + [16192, 16200) 'hfont.i' (line 1114) + [16224, 16236) 'abc.i' (line 1115) + [16256, 16268) 'abcw.i' (line 1116) + [16288, 16300) 'abcf.i' (line 1117) + [16320, 16322) 'glyphs.i' (line 1118) + [16336, 16360) 'a.i' (line 1204) + [16400, 16424) 'w.i' (line 1204) + [16464, 19536) 'full.i' (line 1205) + [19664, 19684) 'gm.i199' (line 1316) + [19728, 19788) 'tm.i172' (line 1024) + [19824, 19832) 'size.i' (line 1026) + [19856, 19860) 'height.i' (line 1027) + [19872, 19932) 'lf.i114' (line 864) + [19968, 20024) 'tm.i' (line 866) + [20064, 20096) 'face_name.i115' (line 868) + [20128, 20160) 'csi.i' (line 869) + [20192, 20212) 'gm.i116' (line 914) + [20256, 20264) 'fs.i' (line 915) + [20288, 20348) 'lf.i75' (line 452) + [20384, 20616) 'otm.i' (line 454) + [20688, 20696) 'size_orig.i76' (line 455) + [20720, 20724) 'width_orig.i77' (line 456) + [20736, 20760) 'xform.i' (line 457) + [20800, 20820) 'gm.i' (line 458) + [20864, 20880) 'mat2.i' (line 459) + [20896, 20904) 'pt.i' (line 460) + [20928, 20988) 'bitmap_lf.i' (line 362) + [21024, 21080) 'tm_orig.i' (line 364) + [21120, 21128) 'size_orig.i' (line 365) + [21152, 21156) 'width_orig.i' (line 366) + [21168, 21228) 'lf.i37' (line 203) <== Memory access at offset 21228 overflows this variable + [21264, 21320) 'tm.i.i' (line 6364) + [21360, 21420) 'lf.i' (line 6451) + [21456, 21716) 'path_name' (line 7846) + [21792, 21896) 'startup' (line 7847) + [21936, 21944) 'argv' (line 7848) + [21968, 21992) 'info' (line 7940) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernelbase\locale.c:7023:30 in MultiByteToWideChar +Shadow bytes around the buggy address: + 0x7ffffe1ff600: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ff680: f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1ff700: f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 + 0x7ffffe1ff780: f8 f8 f2 f2 f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ff800: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 +=>0x7ffffe1ff880: f8 f2 f2 f2 f8 f2 00 00 00 00 00 00 00[04]f2 f2 + 0x7ffffe1ff900: f2 f2 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 + 0x7ffffe1ff980: f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 00 00 00 00 00 00 + 0x7ffffe1ffa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffa80: 00 00 00 00 00 00 00 00 00 00 04 f2 f2 f2 f2 f2 + 0x7ffffe1ffb00: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1512==ABORTING +bernhard@rechner:~/wine_asan_2024-11-07/drive_c/x86_64$ 05fc:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/gdi32/text.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c +index ff548306dc3..2de68f892d8 100644 +--- a/dlls/gdi32/text.c ++++ b/dlls/gdi32/text.c +@@ -781,7 +781,7 @@ static void text_metric_ex_WtoA(const NEWTEXTMETRICEXW *tmW, NEWTEXTMETRICEXA *t + static void logfont_AtoW( const LOGFONTA *fontA, LPLOGFONTW fontW ) + { + memcpy( fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE ); +- MultiByteToWideChar( CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName, ++ MultiByteToWideChar( CP_ACP, 0, fontA->lfFaceName, sizeof(fontA->lfFaceName), fontW->lfFaceName, + LF_FACESIZE ); + fontW->lfFaceName[LF_FACESIZE - 1] = 0; + } +@@ -789,7 +789,7 @@ static void logfont_AtoW( const LOGFONTA *fontA, LPLOGFONTW fontW ) + static void logfont_WtoA( const LOGFONTW *fontW, LPLOGFONTA fontA ) + { + memcpy( fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE ); +- WideCharToMultiByte( CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName, ++ WideCharToMultiByte( CP_ACP, 0, fontW->lfFaceName, sizeof(fontA->lfFaceName), fontA->lfFaceName, + LF_FACESIZE, NULL, NULL ); + fontA->lfFaceName[LF_FACESIZE - 1] = 0; + } +-- +2.47.1 + diff --git a/0015-bernhard-asan/0065-gdi32-Return-immediately-with-negative-count.patch b/0015-bernhard-asan/0065-gdi32-Return-immediately-with-negative-count.patch new file mode 100644 index 0000000..f279db0 --- /dev/null +++ b/0015-bernhard-asan/0065-gdi32-Return-immediately-with-negative-count.patch @@ -0,0 +1,46 @@ +From 0e9169b6e889a4829d29a4e7263f71634e0709a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Wed, 4 Dec 2024 22:34:56 +0100 +Subject: [PATCH 65/86] gdi32: Return immediately with negative count. + +gdi32_test font (ASan) + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/gdi32/tests/x86_64-windows/gdi32_test.exe font +... +font.c:1213: Tests skipped: TrueType font for charset 136 is not installed +================================================================= +==1536==ERROR: AddressSanitizer: requested allocation size 0xfffffffffffffffe (0x800 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0) +0614:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffffa61a8a3 in HeapAlloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:230:3 + #1 0x6ffffc4c9eff in BIDI_Reorder.isra.0 /home/bernhard/data/entwicklung/2024/wine/wine/dlls/gdi32\text.c:397:16 + #2 0x6ffffc4e5f74 in GetTextExtentExPointW /home/bernhard/data/entwicklung/2024/wine/wine/dlls/gdi32\text.c:1393:5 + #3 0x0001400cc8c1 in test_text_extents /home/bernhard/data/entwicklung/2024/wine\wine/dlls/gdi32/tests/font.c:1481:11 + #4 0x0001400cc8c1 in func_font /home/bernhard/data/entwicklung/2024/wine\wine/dlls/gdi32/tests/font.c:7868:5 + #5 0x0001401bcac1 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x0001401bcac1 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #7 0x0001401be9cf in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +==1536==HINT: if you don't care about these errors you may set allocator_may_return_null=1 +SUMMARY: AddressSanitizer: allocation-size-too-big /home/bernhard/data/entwicklung/2024/wine/wine/dlls/gdi32\text.c:397:16 in BIDI_Reorder.isra.0 +==1536==ABORTING +--- + dlls/gdi32/text.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c +index 2de68f892d8..815b282ef4f 100644 +--- a/dlls/gdi32/text.c ++++ b/dlls/gdi32/text.c +@@ -1384,6 +1384,7 @@ BOOL WINAPI GetTextExtentExPointW( HDC hdc, const WCHAR *str, INT count, INT max + BOOL ret = TRUE; + + if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; ++ if (count < 0) return FALSE; + + bidi_flags = dc_attr->text_align & TA_RTLREADING ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR; + bidi_flags |= WINE_GCPW_DISABLE_REORDERING; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0066-mfplat-tests-Do-not-access-buffer-beyond-allocation.patch b/0015-bernhard-asan/0066-mfplat-tests-Do-not-access-buffer-beyond-allocation.patch new file mode 100644 index 0000000..64e1148 --- /dev/null +++ b/0015-bernhard-asan/0066-mfplat-tests-Do-not-access-buffer-beyond-allocation.patch @@ -0,0 +1,101 @@ +From 5891e547af1b512235edbe738543f6054e8c6823 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 20:25:17 +0100 +Subject: [PATCH 66/86] mfplat/tests: Do not access buffer beyond allocation. + +================================================================= +==896==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7e96f3284374 at pc 0x0001400ae98f bp 0x7ffffe1fc0a0 sp 0x7ffffe1fc0e8 +READ of size 1 at 0x7e96f3284374 thread T0 +04b0:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001400ae98e in test_MFCreate2DMediaBuffer /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7057:99 + #1 0x00014003247f in func_mfplat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:13258:5 + #2 0x0001401439b3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #3 0x0001401433fb in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #4 0x0001401453af in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #5 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #6 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7e96f3284374 is located 0 bytes after 20-byte region [0x7e96f3284360,0x7e96f3284374) +allocated by thread T0 here: + #0 0x6ffff88fa2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff7b17698 in init_am_media_type_audio_format /home/bernhard/data/entwicklung/2024/wine/wine/dlls/mfplat\mediatype.c:4078:16 + #2 0x6ffff7b17698 in MFInitAMMediaTypeFromMFMediaType /home/bernhard/data/entwicklung/2024/wine/wine/dlls/mfplat\mediatype.c:4356:14 + #3 0x0001400a932b in IMFMediaBuffer_Lock /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\mfobjects.h:824:12 + #4 0x0001400a932b in test_MFCreate2DMediaBuffer /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7040:14 + #5 0x00014003247f in func_mfplat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:13258:5 + #6 0x0001401439b3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #7 0x0001401433fb in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #8 0x0001401453af in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #9 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7057:99 in test_MFCreate2DMediaBuffer +Shadow bytes around the buggy address: + 0x7e96f3284080: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd + 0x7e96f3284100: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa + 0x7e96f3284180: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fd + 0x7e96f3284200: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd + 0x7e96f3284280: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa +=>0x7e96f3284300: fd fd fd fd fa fa fd fd fd fa fa fa 00 00[04]fa + 0x7e96f3284380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e96f3284400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e96f3284480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e96f3284500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e96f3284580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==896==ABORTING +04b0:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:213822: dlls/mfplat/tests/x86_64-windows/mfplat.ok] Fehler 1 +--- + dlls/mfplat/tests/mfplat.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c +index 752be9ea260..7c3c5715c17 100644 +--- a/dlls/mfplat/tests/mfplat.c ++++ b/dlls/mfplat/tests/mfplat.c +@@ -7054,7 +7054,10 @@ static void test_MFCreate2DMediaBuffer(void) + if (data[j] != (j & 0x7f)) + break; + } +- ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j); ++ if (j < ptr->contiguous_length) ++ ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j); ++ else ++ ok(j == ptr->contiguous_length, "Unexpected byte at position %u.\n", j); + + memset(data, 0xff, length2); + +@@ -7081,7 +7084,10 @@ static void test_MFCreate2DMediaBuffer(void) + if (data[j] != (j & 0x7f)) + break; + } +- ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j); ++ if (j < ptr->contiguous_length) ++ ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j); ++ else ++ ok(j == ptr->contiguous_length, "Unexpected byte at position %u.\n", j); + + hr = IMFMediaBuffer_Unlock(buffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0067-mfplat-tests-Fix-release-calls.patch b/0015-bernhard-asan/0067-mfplat-tests-Fix-release-calls.patch new file mode 100644 index 0000000..8a3d4a8 --- /dev/null +++ b/0015-bernhard-asan/0067-mfplat-tests-Fix-release-calls.patch @@ -0,0 +1,107 @@ +From 15f818237a2735f64e6e66208e6d5ca74c158ad6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 20:44:40 +0100 +Subject: [PATCH 67/86] mfplat/tests: Fix release calls. + +================================================================= +==1368==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ea4a0fe23c8 at pc 0x0001400b8f53 bp 0x7ffffe1fc0c0 sp 0x7ffffe1fc108 +READ of size 8 at 0x7ea4a0fe23c8 thread T0 +0668:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001400b8f52 in IMF2DBuffer_Release /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\mfobjects.h:1460:18 + #1 0x0001400b8f52 in test_MFCreateMediaBufferFromMediaType /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7577:5 + #2 0x000140032484 in func_mfplat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:13265:5 + #3 0x000140143913 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x00014014335b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #5 0x00014014530f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7ea4a0fe23c8 is located 8 bytes inside of 296-byte region [0x7ea4a0fe23c0,0x7ea4a0fe24e8) +freed by thread T0 here: + #0 0x6ffff88fa1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff7b15f71 in memory_buffer_Release /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/buffer.c:177:9 + #2 0x0001400b5d65 in IMFMediaBuffer_Release /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\mfobjects.h:820:12 + #3 0x0001400b5d65 in test_MFCreateMediaBufferFromMediaType /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7561:5 + #4 0x000140032484 in func_mfplat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:13265:5 + #5 0x000140143913 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x00014014335b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #7 0x00014014530f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff88fa3d6 in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x6ffff7b12e7d in create_2d_buffer /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/buffer.c:1461:20 + #2 0x6ffff7b150dc in MFCreateMediaBufferFromMediaType /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/buffer.c:1749:17 + #3 0x0001400b549b in test_MFCreateMediaBufferFromMediaType /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:7543:10 + #4 0x000140032484 in func_mfplat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/mfplat/tests/mfplat.c:13265:5 + #5 0x000140143913 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x00014014335b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #7 0x00014014530f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\mfobjects.h:1460:18 in IMF2DBuffer_Release +Shadow bytes around the buggy address: + 0x7ea4a0fe2100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ea4a0fe2180: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa + 0x7ea4a0fe2200: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd + 0x7ea4a0fe2280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ea4a0fe2300: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa +=>0x7ea4a0fe2380: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd + 0x7ea4a0fe2400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7ea4a0fe2480: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa + 0x7ea4a0fe2500: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 + 0x7ea4a0fe2580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ea4a0fe2600: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1368==ABORTING +make: *** [Makefile:213822: dlls/mfplat/tests/x86_64-windows/mfplat.ok] Fehler 1 +0668:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/mfplat/tests/mfplat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c +index 7c3c5715c17..2cd74ba8d91 100644 +--- a/dlls/mfplat/tests/mfplat.c ++++ b/dlls/mfplat/tests/mfplat.c +@@ -7574,7 +7574,7 @@ static void test_MFCreateMediaBufferFromMediaType(void) + ok(scanline0 == data, "Unexpected scanline0.\n"); + hr = IMF2DBuffer2_Unlock2D(buffer_2d2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +- IMF2DBuffer_Release(buffer_2d); ++ IMF2DBuffer2_Release(buffer_2d2); + + IMFMediaBuffer_Release(buffer); + +@@ -7591,7 +7591,7 @@ static void test_MFCreateMediaBufferFromMediaType(void) + ok(scanline0 == data - pitch * 7, "Unexpected scanline0.\n"); + hr = IMF2DBuffer2_Unlock2D(buffer_2d2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +- IMF2DBuffer_Release(buffer_2d); ++ IMF2DBuffer2_Release(buffer_2d2); + + IMFMediaBuffer_Release(buffer); + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0068-msi-Avoid-buffer-underflow-in-verify_format.patch b/0015-bernhard-asan/0068-msi-Avoid-buffer-underflow-in-verify_format.patch new file mode 100644 index 0000000..70ade1f --- /dev/null +++ b/0015-bernhard-asan/0068-msi-Avoid-buffer-underflow-in-verify_format.patch @@ -0,0 +1,96 @@ +From b387c9a00fbbd3e9343be486c525c80d149c0b37 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 21:13:05 +0100 +Subject: [PATCH 68/86] msi: Avoid buffer underflow in verify_format. + +================================================================= +==612==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f7b2c3e528e at pc 0x6ffff7efba7f bp 0x7ffffe1ff460 sp 0x7ffffe1ff4a8 +READ of size 2 at 0x7f7b2c3e528e thread T0 +0178:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff7efba7e in verify_format /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:743:56 + #1 0x6ffff7efba7e in deformat_string_internal /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:783:10 + #2 0x6ffff7efb607 in MSI_FormatRecordW /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:871:5 + #3 0x6ffff7efee90 in MsiFormatRecordA /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:996:9 + #4 0x000140117b64 in test_formatrecord /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/tests/format.c:257:9 + #5 0x000140114919 in func_format /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/tests/format.c:2340:5 + #6 0x0001403c8c07 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #7 0x0001403c8c07 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #8 0x0001403cab5f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #9 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f7b2c3e528e is located 2 bytes before 8-byte region [0x7f7b2c3e5290,0x7f7b2c3e5298) +allocated by thread T0 here: + #0 0x6ffff88fa2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff978a929 in _wcsdup /home/bernhard/data/entwicklung/2024/wine/wine/dlls/msvcrt\wcs.c:83:11 + #2 0x6ffff7efb8fb in wcsdup /home/bernhard/data/entwicklung/2024/wine\wine/include/msvcrt/string.h:90:60 + #3 0x6ffff7efb8fb in deformat_string_internal /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:774:13 + #4 0x6ffff7efb607 in MSI_FormatRecordW /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:871:5 + #5 0x6ffff7efee90 in MsiFormatRecordA /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:996:9 + #6 0x000140117b64 in test_formatrecord /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/tests/format.c:257:9 + #7 0x000140114919 in func_format /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/tests/format.c:2340:5 + #8 0x0001403c8c07 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #9 0x0001403c8c07 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #10 0x0001403cab5f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #11 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #12 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msi/format.c:743:56 in verify_format +Shadow bytes around the buggy address: + 0x7f7b2c3e5000: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa + 0x7f7b2c3e5080: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fd + 0x7f7b2c3e5100: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa + 0x7f7b2c3e5180: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fa + 0x7f7b2c3e5200: fa fa 00 fa fa fa 00 fa fa fa fd fa fa fa 00 fa +=>0x7f7b2c3e5280: fa[fa]00 fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f7b2c3e5300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f7b2c3e5380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f7b2c3e5400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f7b2c3e5480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f7b2c3e5500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==612==ABORTING +0178:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:243661: dlls/msi/tests/x86_64-windows/format.ok] Fehler 1 +--- + dlls/msi/format.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dlls/msi/format.c b/dlls/msi/format.c +index 5301752a41a..e63118ea006 100644 +--- a/dlls/msi/format.c ++++ b/dlls/msi/format.c +@@ -736,10 +736,11 @@ static UINT replace_stack(struct format *format, struct stack *stack, struct sta + static BOOL verify_format(LPWSTR data) + { + int count = 0; ++ LPWSTR start = data; + + while (*data) + { +- if (*data == '[' && *(data - 1) != '\\') ++ if (*data == '[' && ((data - 1) < start || *(data - 1) != '\\')) + count++; + else if (*data == ']') + count--; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0069-ntdll-tests-atoi-in-ASan-returns-a-few-values-differ.patch b/0015-bernhard-asan/0069-ntdll-tests-atoi-in-ASan-returns-a-few-values-differ.patch new file mode 100644 index 0000000..1696246 --- /dev/null +++ b/0015-bernhard-asan/0069-ntdll-tests-atoi-in-ASan-returns-a-few-values-differ.patch @@ -0,0 +1,53 @@ +From 2d614ab3bcd09061319c3e15225b03b300b3296d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 16 Dec 2024 23:14:14 +0100 +Subject: [PATCH 69/86] ntdll/tests: atoi in ASan returns a few values + differently. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M ntdll.dll -p dlls/ntdll/tests/x86_64-windows/ntdll_test.exe string && touch dlls/ntdll/tests/x86_64-windows/string.ok +string.c:985: Test failed: (test 51): call failed: _atoi("-9999999999") has result -2147483648, expected: -1410065407 +string.c:985: Test failed: (test 52): call failed: _atoi("-2147483649") has result -2147483648, expected: 2147483647 +string.c:985: Test failed: (test 60): call failed: _atoi("2147483648") has result 2147483647, expected: -2147483648 +string.c:985: Test failed: (test 61): call failed: _atoi("2147483649") has result 2147483647, expected: -2147483647 +string.c:985: Test failed: (test 62): call failed: _atoi("4294967294") has result 2147483647, expected: -2 +string.c:985: Test failed: (test 63): call failed: _atoi("4294967295") has result 2147483647, expected: -1 +string.c:985: Test failed: (test 64): call failed: _atoi("4294967296") has result 2147483647, expected: 0 +string.c:985: Test failed: (test 65): call failed: _atoi("9999999999") has result 2147483647, expected: 1410065407 +make: *** [Makefile:299457: dlls/ntdll/tests/x86_64-windows/string.ok] Fehler 8 +--- + dlls/ntdll/tests/string.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c +index 525e46469ae..46d2bf33af3 100644 +--- a/dlls/ntdll/tests/string.c ++++ b/dlls/ntdll/tests/string.c +@@ -902,8 +902,10 @@ static const str2long_t str2long[] = { + { "00x12345", 0 }, + { "0xx12345", 0 }, + { "1x34", 1 }, ++#if 0 /*ASan*/ + { "-9999999999", -1410065407 }, /* Big negative integer */ + { "-2147483649", 2147483647 }, /* Too small to fit in 32 Bits */ ++#endif + { "-2147483648", 0x80000000 }, /* Smallest negative integer */ + { "-2147483647", -2147483647 }, + { "-1", -1 }, +@@ -911,12 +913,14 @@ static const str2long_t str2long[] = { + { "1", 1 }, + { "2147483646", 2147483646 }, + { "2147483647", 2147483647 }, /* Largest signed positive integer */ ++#if 0 /*ASan*/ + { "2147483648", 2147483648UL }, /* Positive int equal to smallest negative int */ + { "2147483649", 2147483649UL }, + { "4294967294", 4294967294UL }, + { "4294967295", 4294967295UL }, /* Largest unsigned integer */ + { "4294967296", 0 }, /* Too big to fit in 32 Bits */ + { "9999999999", 1410065407 }, /* Big positive integer */ ++#endif + { "056789", 56789 }, /* Leading zero and still decimal */ + { "b1011101100", 0 }, /* Binary (b-notation) */ + { "-b1011101100", 0 }, /* Negative Binary (b-notation) */ +-- +2.47.1 + diff --git a/0015-bernhard-asan/0070-rpcrt4-Do-not-call-strdup-with-a-null-pointer.patch b/0015-bernhard-asan/0070-rpcrt4-Do-not-call-strdup-with-a-null-pointer.patch new file mode 100644 index 0000000..941992e --- /dev/null +++ b/0015-bernhard-asan/0070-rpcrt4-Do-not-call-strdup-with-a-null-pointer.patch @@ -0,0 +1,51 @@ +From ffd0b54edca4ae79a1da1489decd4cd0cf9f930a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 21 Oct 2024 11:09:09 +0200 +Subject: [PATCH 70/86] rpcrt4: Do not call strdup with a null pointer. + +This gets visible when ASAN replaces the strdup implementation, +which does not handle the NULL case like the msvcrt implementation. +--- + dlls/rpcrt4/rpc_binding.c | 10 +++++----- + dlls/rpcrt4/rpc_transport.c | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c +index d4e35bdf116..73f7d3f1d2e 100644 +--- a/dlls/rpcrt4/rpc_binding.c ++++ b/dlls/rpcrt4/rpc_binding.c +@@ -979,11 +979,11 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy( + + DestBinding->ObjectUuid = SrcBinding->ObjectUuid; + DestBinding->BlockingFn = SrcBinding->BlockingFn; +- DestBinding->Protseq = strdup(SrcBinding->Protseq); +- DestBinding->NetworkAddr = strdup(SrcBinding->NetworkAddr); +- DestBinding->Endpoint = strdup(SrcBinding->Endpoint); +- DestBinding->NetworkOptions = wcsdup(SrcBinding->NetworkOptions); +- DestBinding->CookieAuth = wcsdup(SrcBinding->CookieAuth); ++ DestBinding->Protseq = SrcBinding->Protseq ? strdup(SrcBinding->Protseq) : NULL; ++ DestBinding->NetworkAddr = SrcBinding->NetworkAddr ? strdup(SrcBinding->NetworkAddr) : NULL; ++ DestBinding->Endpoint = SrcBinding->Endpoint ? strdup(SrcBinding->Endpoint) : NULL; ++ DestBinding->NetworkOptions = SrcBinding->NetworkOptions ? wcsdup(SrcBinding->NetworkOptions) : NULL; ++ DestBinding->CookieAuth = SrcBinding->CookieAuth ? wcsdup(SrcBinding->CookieAuth) : NULL; + if (SrcBinding->Assoc) SrcBinding->Assoc->refs++; + DestBinding->Assoc = SrcBinding->Assoc; + +diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c +index 8d53e7cee35..968bcfa37b1 100644 +--- a/dlls/rpcrt4/rpc_transport.c ++++ b/dlls/rpcrt4/rpc_transport.c +@@ -3302,8 +3302,8 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, + NewConnection->ref = 1; + NewConnection->server = server; + NewConnection->ops = ops; +- NewConnection->NetworkAddr = strdup(NetworkAddr); +- NewConnection->Endpoint = strdup(Endpoint); ++ NewConnection->NetworkAddr = NetworkAddr ? strdup(NetworkAddr) : NULL; ++ NewConnection->Endpoint = Endpoint ? strdup(Endpoint) : NULL; + NewConnection->NetworkOptions = wcsdup(NetworkOptions); + NewConnection->CookieAuth = wcsdup(CookieAuth); + NewConnection->MaxTransmissionSize = RPC_MAX_PACKET_SIZE; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0071-setupapi-tests-Make-sure-string-is-terminated.patch b/0015-bernhard-asan/0071-setupapi-tests-Make-sure-string-is-terminated.patch new file mode 100644 index 0000000..d5532f7 --- /dev/null +++ b/0015-bernhard-asan/0071-setupapi-tests-Make-sure-string-is-terminated.patch @@ -0,0 +1,97 @@ +From 0fbf4ce0f0cad682f3ba6e3cf1e26b3b0e9029f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 23:40:29 +0100 +Subject: [PATCH 71/86] setupapi/tests: Make sure string is terminated. + +================================================================= +==644==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fce34 at pc 0x6ffff88f2c0c bp 0x7ffffe1fb8c0 sp 0x7ffffe1fb900 +READ of size 262 at 0x7ffffe1fce34 thread T0 +0404:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff88f2c0b in strrchr /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:778:5 + #1 0x6ffff518dbfb in SetupCopyOEMInfA /home/bernhard/data/entwicklung/2024/wine/wine/dlls/setupapi\devinst.c:5552:41 + #2 0x00014004b8cb in test_copy_oem_inf /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4096:11 + #3 0x0001400224b5 in func_devinst /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4708:5 + #4 0x0001400c71ac in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001400c71ac in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001400c90df in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fce34 is located in stack of thread T0 at offset 2964 in frame + #0 0x00014004a53f in test_copy_oem_inf /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/devinst.c:4006 + + This frame has 14 object(s): + [32, 292) 'expect.i2138' (line 3952) + [368, 628) 'expect.i2049' (line 3952) + [704, 1228) 'orig_info.i' (line 3961) + [1360, 1364) 'size.i' (line 3963) + [1376, 1636) 'expect.i1501' (line 3952) + [1712, 1972) 'expect.i' (line 3952) + [2048, 2568) 'path' (line 4007) + [2704, 2964) 'dest' (line 4007) + [3040, 3300) 'orig_dest' (line 4007) <== Memory access at offset 2964 partially underflows this variable + [3376, 3636) 'orig_cwd' (line 4008) + [3712, 3720) 'filepart' (line 4008) + [3744, 4004) 'pnf' (line 4008) + [4080, 4128) 'system_info' (line 4009) + [4160, 4164) 'size' (line 4011) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine/wine/dlls/setupapi\devinst.c:5552:41 in SetupCopyOEMInfA +Shadow bytes around the buggy address: + 0x7ffffe1fcb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcc80: 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fcd00: f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1fce00: 00 00 00 00 00 00[04]f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fce80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fcf80: 04 f2 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 + 0x7ffffe1fd000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1fd080: 00 00 00 00 00 00 00 00 00 00 04 f2 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==644==ABORTING +make: *** [Makefile:352637: dlls/setupapi/tests/x86_64-windows/devinst.ok] Fehler 1 +0404:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/setupapi/tests/devinst.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c +index 3b900eeed31..1a369f9c490 100644 +--- a/dlls/setupapi/tests/devinst.c ++++ b/dlls/setupapi/tests/devinst.c +@@ -4092,8 +4092,9 @@ static void test_copy_oem_inf(struct testsign_context *ctx) + + /* Test with a relative path. */ + SetLastError(0xdeadbeef); +- memset(dest, 0xcc, sizeof(dest)); +- ret = SetupCopyOEMInfA("winetest.inf", NULL, 0, SP_COPY_NOOVERWRITE, dest, sizeof(dest), NULL, &filepart); ++ memset(dest, 0xcc, sizeof(dest) - 1); ++ dest[sizeof(dest) - 1] = '\0'; ++ ret = SetupCopyOEMInfA("winetest.inf", NULL, 0, SP_COPY_NOOVERWRITE, dest, sizeof(dest) - 1, NULL, &filepart); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists("winetest.inf"), "Expected source inf to exist.\n"); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0072-setupapi-tests-SetupCloseFileQueue-already-called-in.patch b/0015-bernhard-asan/0072-setupapi-tests-SetupCloseFileQueue-already-called-in.patch new file mode 100644 index 0000000..4e0daec --- /dev/null +++ b/0015-bernhard-asan/0072-setupapi-tests-SetupCloseFileQueue-already-called-in.patch @@ -0,0 +1,105 @@ +From bc678760a0bd256c3f79f657f3350b31f8d031c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 23:48:16 +0100 +Subject: [PATCH 72/86] setupapi/tests: SetupCloseFileQueue already called in + run_queue_. + +================================================================= +==1316==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ec6818e3740 at pc 0x6ffff518d19f bp 0x7ffffe1fa030 sp 0x7ffffe1fa078 +READ of size 4 at 0x7ec6818e3740 thread T0 +0830:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff518d19e in SetupCloseFileQueue /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/queue.c:436:16 + #1 0x000140079bc3 in test_rename /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2292:5 + #2 0x000140079bc3 in func_install /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2581:5 + #3 0x0001400c71bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001400c71bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #5 0x0001400c90ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7ec6818e3740 is located 0 bytes inside of 104-byte region [0x7ec6818e3740,0x7ec6818e37a8) +freed by thread T0 here: + #0 0x6ffff88fa1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff518d16f in SetupCloseFileQueue /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/queue.c:452:5 + #2 0x000140094948 in run_queue_ /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:1443:11 + #3 0x0001400793b2 in test_rename /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2281:5 + #4 0x0001400793b2 in func_install /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2581:5 + #5 0x0001400c71bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x0001400c71bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #7 0x0001400c90ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff88fa3d6 in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x6ffff518ccee in SetupOpenFileQueue /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/queue.c:419:19 + #2 0x000140078e46 in test_rename /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2269:13 + #3 0x000140078e46 in func_install /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/tests/install.c:2581:5 + #4 0x0001400c71bc in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x0001400c71bc in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0001400c90ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffff80e4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffff82bfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/setupapi/queue.c:436:16 in SetupCloseFileQueue +Shadow bytes around the buggy address: + 0x7ec6818e3480: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa + 0x7ec6818e3500: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd + 0x7ec6818e3580: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd + 0x7ec6818e3600: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa + 0x7ec6818e3680: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fa +=>0x7ec6818e3700: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd + 0x7ec6818e3780: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa + 0x7ec6818e3800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7ec6818e3880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7ec6818e3900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7ec6818e3980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1316==ABORTING +0830:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:352858: dlls/setupapi/tests/x86_64-windows/install.ok] Fehler 1 +--- + dlls/setupapi/tests/install.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/dlls/setupapi/tests/install.c b/dlls/setupapi/tests/install.c +index 9f5260359a5..61608946bff 100644 +--- a/dlls/setupapi/tests/install.c ++++ b/dlls/setupapi/tests/install.c +@@ -2289,7 +2289,6 @@ static void test_rename(void) + ok(!delete_file("b/five.txt"), "File should not exist.\n"); + ok(delete_file("b/six.txt"), "File should exist.\n"); + ok(delete_file("b/seven.txt"), "File should exist.\n"); +- SetupCloseFileQueue(queue); + + create_file("a/one.txt"); + create_file("a/three.txt"); +@@ -2312,7 +2311,6 @@ static void test_rename(void) + ok(!delete_file("a/four.txt"), "File should not exist.\n"); + ok(!delete_file("a/five.txt"), "File should not exist.\n"); + ok(delete_file("a/six.txt"), "File should exist.\n"); +- SetupCloseFileQueue(queue); + + ret = delete_file("a/"); + ok(ret, "Failed to delete directory, error %lu.\n", GetLastError()); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0073-spoolss-Access-memory-with-right-typed-pointer.patch b/0015-bernhard-asan/0073-spoolss-Access-memory-with-right-typed-pointer.patch new file mode 100644 index 0000000..9c41b8e --- /dev/null +++ b/0015-bernhard-asan/0073-spoolss-Access-memory-with-right-typed-pointer.patch @@ -0,0 +1,89 @@ +From 6d1efe634e008f8ea98fae2992445a91549d8d38 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 00:06:28 +0100 +Subject: [PATCH 73/86] spoolss: Access memory with right typed pointer. + +(Or is the pointer size right?) + +================================================================= +==1124==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1ffb60 at pc 0x6ffff67c4d01 bp 0x7ffffe1ffa10 sp 0x7ffffe1ffa58 +WRITE of size 8 at 0x7ffffe1ffb60 thread T0 +0470:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff67c4d00 in BuildOtherNamesFromMachineName /home/bernhard/data/entwicklung/2024/wine\wine/dlls/spoolss/spoolss_main.c:99:20 + #1 0x000140001447 in test_BuildOtherNamesFromMachineName /home/bernhard/data/entwicklung/2024/wine\wine/dlls/spoolss/tests/spoolss.c:131:11 + #2 0x000140001447 in func_spoolss /home/bernhard/data/entwicklung/2024/wine\wine/dlls/spoolss/tests/spoolss.c:218:5 + #3 0x000140004d63 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001400047ab in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #5 0x00014000552f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ffb60 is located in stack of thread T0 at offset 64 in frame + #0 0x00014000100f in func_spoolss /home/bernhard/data/entwicklung/2024/wine\wine/dlls/spoolss/tests/spoolss.c:208 + + This frame has 2 object(s): + [32, 40) 'buffers.i' (line 123) + [64, 68) 'numentries.i' (line 124) <== Memory access at offset 64 partially overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/spoolss/spoolss_main.c:99:20 in BuildOtherNamesFromMachineName +Shadow bytes around the buggy address: + 0x7ffffe1ff880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7ffffe1ffb00: 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2[04]f3 f3 f3 + 0x7ffffe1ffb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffc00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f8 + 0x7ffffe1ffc80: f8 f8 f8 f8 f3 f3 f3 f3 00 00 00 00 00 00 00 00 + 0x7ffffe1ffd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 + 0x7ffffe1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1124==ABORTING +0470:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:366858: dlls/spoolss/tests/x86_64-windows/spoolss.ok] Fehler 1 +--- + dlls/spoolss/spoolss_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/spoolss/spoolss_main.c b/dlls/spoolss/spoolss_main.c +index 355bf72b822..bc85dee2a9f 100644 +--- a/dlls/spoolss/spoolss_main.c ++++ b/dlls/spoolss/spoolss_main.c +@@ -91,12 +91,12 @@ LPWSTR WINAPI AllocSplStr(LPCWSTR pwstr) + /****************************************************************** + * BuildOtherNamesFromMachineName [SPOOLSS.@] + */ +-BOOL WINAPI BuildOtherNamesFromMachineName(LPVOID * ptr1, LPVOID * ptr2) ++BOOL WINAPI BuildOtherNamesFromMachineName(LPVOID * ptr1, DWORD * ptr2) + { + FIXME("(%p, %p) stub\n", ptr1, ptr2); + + *ptr1 = NULL; +- *ptr2 = NULL; ++ *ptr2 = 0; + return FALSE; + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0074-uiautomationcore-Avoid-double-free.patch b/0015-bernhard-asan/0074-uiautomationcore-Avoid-double-free.patch new file mode 100644 index 0000000..bc7a23f --- /dev/null +++ b/0015-bernhard-asan/0074-uiautomationcore-Avoid-double-free.patch @@ -0,0 +1,98 @@ +From 11997d5a92c154789ea0f82b36d061fb0ff1fa57 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 00:12:57 +0100 +Subject: [PATCH 74/86] uiautomationcore: Avoid double-free. + +================================================================= +==692==ERROR: AddressSanitizer: attempting double-free on 0x7f1e587f85f0 in thread T0: +04a8:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff8e8a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff8465c3b in uia_event_Release /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1062:9 + #2 0x6ffff845f44c in IWineUiaEvent_Release /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\dlls/uiautomationcore\uia_classes.h:256:12 + #3 0x6ffff845f44c in UiaRemoveEvent /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1730:5 + #4 0x6ffff8459c90 in uia_event_handler_destroy /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1392:9 + #5 0x6ffff8459c90 in uia_event_handler_map_entry_destroy /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1404:9 + #6 0x6ffff8459afc in uia_event_handlers_remove_handlers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1429:9 + #7 0x6ffff8459afc in uia_remove_com_event_handler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3840:5 + #8 0x6ffff844a738 in uia_iface_RemoveAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3861:10 + #9 0x000140053426 in IUIAutomation_RemoveAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\uiautomationclient.h:18546:12 + #10 0x000140053426 in test_IUIAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:15125:10 + #11 0x000140053426 in test_CUIAutomation_event_handlers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16202:5 + #12 0x000140053426 in test_CUIAutomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16357:5 + #13 0x00014000f641 in func_uiautomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:18683:5 + #14 0x0001400f87b3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #15 0x0001400f81fb in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #16 0x0001400fa12f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #17 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #18 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f1e587f85f0 is located 0 bytes inside of 32-byte region [0x7f1e587f85f0,0x7f1e587f8610) +freed by thread T0 here: + #0 0x6ffff8e8a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff8465ff1 in uia_event_advise_events /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1107:9 + #2 0x6ffff845f3a2 in IWineUiaEvent_advise_events /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\dlls/uiautomationcore\uia_classes.h:260:12 + #3 0x6ffff845f3a2 in uia_event_advise /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1567:10 + #4 0x6ffff845f3a2 in UiaRemoveEvent /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1719:10 + #5 0x6ffff8459c90 in uia_event_handler_destroy /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1392:9 + #6 0x6ffff8459c90 in uia_event_handler_map_entry_destroy /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1404:9 + #7 0x6ffff8459afc in uia_event_handlers_remove_handlers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:1429:9 + #8 0x6ffff8459afc in uia_remove_com_event_handler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3840:5 + #9 0x6ffff844a738 in uia_iface_RemoveAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3861:10 + #10 0x000140053426 in IUIAutomation_RemoveAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\uiautomationclient.h:18546:12 + #11 0x000140053426 in test_IUIAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:15125:10 + #12 0x000140053426 in test_CUIAutomation_event_handlers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16202:5 + #13 0x000140053426 in test_CUIAutomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16357:5 + #14 0x00014000f641 in func_uiautomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:18683:5 + #15 0x0001400f87b3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #16 0x0001400f81fb in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #17 0x0001400fa12f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #18 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #19 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffff8e8a2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff8e8a5f8 in _recalloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:131:21 + #2 0x6ffff845d46d in uia_array_reserve /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_private.h:204:20 + #3 0x6ffff845d46d in uia_event_add_event_adviser /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1275:10 + #4 0x6ffff845d46d in uia_event_add_provider_event_adviser /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1420:10 + #5 0x6ffff8442640 in uia_provider_attach_event /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_client.c:1920:18 + #6 0x6ffff8434b12 in IWineUiaProvider_attach_event /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\dlls/uiautomationcore\uia_classes.h:430:12 + #7 0x6ffff8434b12 in attach_event_to_node_provider /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_client.c:375:10 + #8 0x6ffff8434b12 in attach_event_to_uia_node /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_client.c:1345:14 + #9 0x6ffff845e505 in uia_add_clientside_event /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1647:10 + #10 0x6ffff8457b8e in uia_add_com_event_handler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3784:10 + #11 0x6ffff844a517 in uia_iface_AddAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_com_client.c:3823:10 + #12 0x000140053254 in IUIAutomation_AddAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\uiautomationclient.h:18543:12 + #13 0x000140053254 in test_IUIAutomationEventHandler /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:15119:10 + #14 0x000140053254 in test_CUIAutomation_event_handlers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16202:5 + #15 0x000140053254 in test_CUIAutomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:16357:5 + #16 0x00014000f641 in func_uiautomation /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/tests/uiautomation.c:18683:5 + #17 0x0001400f87b3 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #18 0x0001400f81fb in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #19 0x0001400fa12f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #20 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #21 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: double-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/uiautomationcore/uia_event.c:1062:9 in uia_event_Release +==692==ABORTING +04a8:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:377475: dlls/uiautomationcore/tests/x86_64-windows/uiautomation.ok] Fehler 1 +--- + dlls/uiautomationcore/uia_event.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/uiautomationcore/uia_event.c b/dlls/uiautomationcore/uia_event.c +index 0106be09999..b36ed813e95 100644 +--- a/dlls/uiautomationcore/uia_event.c ++++ b/dlls/uiautomationcore/uia_event.c +@@ -1105,6 +1105,7 @@ static HRESULT WINAPI uia_event_advise_events(IWineUiaEvent *iface, BOOL advise_ + for (i = 0; i < event->event_advisers_count; i++) + IWineUiaEventAdviser_Release(event->event_advisers[i]); + free(event->event_advisers); ++ event->event_advisers = NULL; + event->event_advisers_count = event->event_advisers_arr_size = 0; + } + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0075-urlmon-Avoid-calling-remove_dot_segments-with-too-sm.patch b/0015-bernhard-asan/0075-urlmon-Avoid-calling-remove_dot_segments-with-too-sm.patch new file mode 100644 index 0000000..5381799 --- /dev/null +++ b/0015-bernhard-asan/0075-urlmon-Avoid-calling-remove_dot_segments-with-too-sm.patch @@ -0,0 +1,182 @@ +From 981b30377a45e32fb6529771e7cb6acbf2f0e033 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 01:01:55 +0100 +Subject: [PATCH 75/86] urlmon: Avoid calling remove_dot_segments with too + small buffer. + +================================================================= +==888==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1fee2a at pc 0x6ffff83ca415 bp 0x7ffffe1fd4d0 sp 0x7ffffe1fd518 +READ of size 2 at 0x7ffffe1fee2a thread T0 +04a8:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff83ca414 in remove_dot_segments /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/uri.c:606:37 + #1 0x6ffff83bfb11 in parse_canonicalize /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/uri.c:6593:30 + #2 0x6ffff83befe2 in CoInternetParseIUri /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/uri.c:6963:14 + #3 0x0001400a59a4 in test_CoInternetParseIUri_InvalidArgs /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/tests/uri.c:11478:14 + #4 0x0001400a59a4 in func_uri /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/tests/uri.c:12219:5 + #5 0x00014011cde0 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #6 0x00014011cde0 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #7 0x00014011ec8f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #8 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #9 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1fee2a is located in stack of thread T0 at offset 5738 in frame + #0 0x00014008974f in func_uri /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/tests/uri.c:12124 + + This frame has 100 object(s): + [32, 40) 'session.i2942' (line 11247) + [64, 72) 'uri.i2710' (line 12034) + [96, 104) 'ubf.i' (line 12035) + [128, 136) 'ps.i' (line 12036) + [160, 168) 'ub.i' (line 12037) + [192, 200) 'bstr.i' (line 12038) + [224, 228) 'dword.i' (line 12039) + [240, 244) 'eq.i' (line 12040) + [256, 264) 'ui.i' (line 12041) + [288, 296) 'mon.i' (line 11711) + [320, 328) 'base_mon.i' (line 11711) + [352, 360) 'uri.i2586' (line 11713) + [384, 392) 'base_uri.i' (line 11713) + [416, 424) 'uri.i2499' (line 11557) + [448, 848) 'result.i2500' (line 11562) + [912, 916) 'result_len.i2501' (line 11563) + [928, 936) 'base.i2446' (line 11394) + [960, 968) 'result.i2447' (line 11399) + [992, 1000) 'received.i2448' (line 11410) + [1024, 1032) 'base.i2391' (line 11263) + [1056, 1064) 'relative.i2392' (line 11268) + [1088, 1096) 'result.i2393' (line 11273) + [1120, 1128) 'received.i2394' (line 11284) + [1152, 1160) 'session.i' (line 11231) + [1184, 1192) 'uri.i2278' (line 11520) + [1216, 5386) 'result.i2279' (line 11528) + [5648, 5652) 'result_len.i2280' (line 11529) + [5664, 5672) 'uri.i2091' (line 11426) + [5696, 5702) 'tmp.i2092' (line 11427) + [5728, 5732) 'result.i2093' (line 11429) + [5744, 5752) 'base.i1889' (line 11302) <== Memory access at offset 5738 underflows this variable + [5776, 5784) 'result.i1890' (line 11302) + [5808, 5816) 'received.i1891' (line 11353) + [5840, 5844) 'received172.i' (line 11371) + [5856, 5864) 'base.i' (line 11012) + [5888, 5896) 'relative.i' (line 11012) + [5920, 5928) 'result.i1721' (line 11012) + [5952, 5960) 'received.i1722' (line 11065) + [5984, 5988) 'received180.i' (line 11082) + [6000, 6008) 'uri.i1581' (line 10925) + [6032, 6040) 'factory.i' (line 10926) + [6064, 6072) 'builder.i1582' (line 10927) + [6096, 6104) 'tmp.i' (line 10959) + [6128, 6136) 'result.i1583' (line 10960) + [6160, 6164) 'result_len.i' (line 10961) + [6176, 6184) 'tmp114.i' (line 10995) + [6208, 6216) 'uri.i1534' (line 10897) + [6240, 6248) 'builder.i1535' (line 10901) + [6272, 6276) 'has.i' (line 10906) + [6288, 6292) 'port.i1536' (line 10907) + [6304, 6312) 'builder.i1404' (line 10812) + [6336, 6344) 'uri.i1405' (line 10847) + [6368, 6376) 'result.i' (line 10868) + [6400, 6408) 'received.i1406' (line 10876) + [6432, 6440) 'builder.i1283' (line 10675) + [6464, 6472) 'uri.i1284' (line 10681) + [6496, 6504) 'test.i1285' (line 10689) + [6528, 6536) 'builder.i1168' (line 10570) + [6560, 6568) 'uri.i1169' (line 10576) + [6592, 6596) 'received.i1170' (line 10577) + [6608, 6616) 'prop.i' (line 10596) + [6640, 6644) 'len.i1171' (line 10597) + [6656, 6664) 'builder.i1087' (line 9634) + [6688, 6696) 'received.i1088' (line 9640) + [6720, 6724) 'len.i' (line 9641) + [6736, 6740) 'port.i' (line 9641) + [6752, 6756) 'set.i' (line 9642) + [6768, 6776) 'builder.i982' (line 9542) + [6800, 6808) 'test.i983' (line 9548) + [6832, 6840) 'uri.i984' (line 9548) + [6864, 6872) 'builder.i' (line 9356) + [6896, 6904) 'uri.i938' (line 9357) + [6928, 6936) 'uri.i867' (line 9321) + [6960, 6968) 'received.i868' (line 9335) + [6992, 7000) 'uri.i824' (line 9307) + [7024, 7032) 'uri.i794' (line 9284) + [7056, 7076) 'fragmentW.i' (line 9285) + [7120, 7136) 'custom_uri.i' (line 9206) + [7152, 7160) 'uriA.i' (line 9207) + [7184, 7192) 'uriB.i' (line 9207) + [7216, 7220) 'equal.i' (line 9208) + [7232, 7240) 'uri.i540' (line 8934) + [7264, 7268) 'received.i542' (line 8966) + [7280, 7288) 'uri.i476' (line 8883) + [7312, 7316) 'received.i478' (line 8908) + [7328, 7336) 'uri.i389' (line 8772) + [7360, 7364) 'received.i390' (line 8780) + [7376, 7380) 'receivedLen.i' (line 8806) + [7392, 7400) 'uri.i317' (line 8683) + [7424, 7428) 'received.i318' (line 8718) + [7440, 7448) 'uri.i241' (line 8363) + [7472, 7476) 'received.i242' (line 8370) + [7488, 7492) 'received49.i' (line 8397) + [7504, 7512) 'uri.i195' (line 8287) + [7536, 7544) 'received.i' (line 8295) + [7568, 7576) 'received88.i' (line 8337) + [7600, 7608) 'uri.i165' (line 8271) + [7632, 7640) 'uri.i139' (line 8243) + [7664, 7680) 'invalidW.i' (line 8245) + [7696, 7704) 'uri.i' (line 8232) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/urlmon/uri.c:606:37 in remove_dot_segments +Shadow bytes around the buggy address: + 0x7ffffe1feb80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fec00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1fec80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fed00: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1fed80: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f2 00 f2 f2 f2 +=>0x7ffffe1fee00: 06 f2 f2 f2 04[f2]f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1fee80: f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 + 0x7ffffe1fef00: f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1fef80: f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 + 0x7ffffe1ff000: f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f8 f2 f8 f2 f2 f2 + 0x7ffffe1ff080: f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==888==ABORTING +04a8:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:381588: dlls/urlmon/tests/x86_64-windows/uri.ok] Fehler 1 +--- + dlls/urlmon/uri.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c +index cb5266518d1..d8e6b60dffc 100644 +--- a/dlls/urlmon/uri.c ++++ b/dlls/urlmon/uri.c +@@ -6588,7 +6588,7 @@ static HRESULT parse_canonicalize(const Uri *uri, DWORD flags, LPWSTR output, + /* Sometimes the path is the very last component of the IUri, so + * see if the dot segments need to be reduced now. + */ +- if(reduce_path && path) { ++ if(reduce_path && path && len < output_len) { + DWORD current_path_len = (output+len) - path; + DWORD new_path_len = remove_dot_segments(path, current_path_len); + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0076-wbemprox-Avoid-overflow-by-allocating-4-bytes.patch b/0015-bernhard-asan/0076-wbemprox-Avoid-overflow-by-allocating-4-bytes.patch new file mode 100644 index 0000000..8ddbae9 --- /dev/null +++ b/0015-bernhard-asan/0076-wbemprox-Avoid-overflow-by-allocating-4-bytes.patch @@ -0,0 +1,97 @@ +From 17645bebade39c34ee65fab9175d653021558eb7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 01:47:28 +0100 +Subject: [PATCH 76/86] wbemprox: Avoid overflow by allocating 4 bytes. + +(Was easier to reserve 32 bits instead of using just 16 bits later.) + +================================================================= +==2544==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7e84e25f0c52 at pc 0x6ffff8e88bfb bp 0x7ffffe1fd3b0 sp 0x7ffffe1fd3f8 +READ of size 4 at 0x7e84e25f0c52 thread T0 +0a34:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff8e88bfa in __asan_memcpy /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_interceptors_memintrinsics.cpp:63:3 + #1 0x6ffff8253e13 in SafeArrayPutElement /home/bernhard/data/entwicklung/2024/wine\wine/dlls/oleaut32/safearray.c:922:9 + #2 0x6ffff75fcb40 in to_safearray /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/query.c:1090:18 + #3 0x6ffff75fdadc in get_propval /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/query.c:1216:19 + #4 0x6ffff75efc60 in class_object_Get /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/class.c:409:12 + #5 0x0001400119a2 in IWbemClassObject_Get /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\wbemcli.h:1989:12 + #6 0x0001400119a2 in test_Win32_SystemEnclosure /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/tests/query.c:905:10 + #7 0x0001400119a2 in func_query /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/tests/query.c:2501:5 + #8 0x000140033d71 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #9 0x000140033d71 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #10 0x000140035c0f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #11 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #12 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7e84e25f0c52 is located 0 bytes after 2-byte region [0x7e84e25f0c50,0x7e84e25f0c52) +allocated by thread T0 here: + #0 0x6ffff8e8a2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff75e8645 in get_systemenclosure_chassistypes /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/builtin.c:4119:19 + #2 0x6ffff75e8645 in fill_systemenclosure /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/builtin.c:4150:25 + #3 0x6ffff75fba38 in exec_select_view /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/query.c:708:18 + #4 0x6ffff75fba38 in execute_view /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/query.c:746:16 + #5 0x6ffff75fc6d9 in exec_query /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/query.c:795:10 + #6 0x0001400116ef in IWbemServices_ExecQuery /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\wbemcli.h:1402:12 + #7 0x0001400116ef in test_Win32_SystemEnclosure /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/tests/query.c:895:10 + #8 0x0001400116ef in func_query /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wbemprox/tests/query.c:2501:5 + #9 0x000140033d71 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #10 0x000140033d71 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #11 0x000140035c0f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #12 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #13 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/oleaut32/safearray.c:922:9 in SafeArrayPutElement +Shadow bytes around the buggy address: + 0x7e84e25f0980: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fd + 0x7e84e25f0a00: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa + 0x7e84e25f0a80: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa + 0x7e84e25f0b00: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa + 0x7e84e25f0b80: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa +=>0x7e84e25f0c00: fa fa 00 fa fa fa 00 00 fa fa[02]fa fa fa 04 fa + 0x7e84e25f0c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e84e25f0d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e84e25f0d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e84e25f0e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7e84e25f0e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==2544==ABORTING +0a34:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:397130: dlls/wbemprox/tests/x86_64-windows/query.ok] Fehler 1 +--- + dlls/wbemprox/builtin.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c +index 3e8c320028d..51bcc3114c8 100644 +--- a/dlls/wbemprox/builtin.c ++++ b/dlls/wbemprox/builtin.c +@@ -4110,7 +4110,7 @@ static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len + const struct smbios_header *hdr; + const struct smbios_chassis *chassis; + struct array *ret = NULL; +- UINT16 *types; ++ UINT32 *types; + + if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, 0, buf, len )) || hdr->length < sizeof(*chassis)) goto done; + chassis = (const struct smbios_chassis *)hdr; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0077-winecfg-Do-not-call-strdup-with-a-null-pointer.patch b/0015-bernhard-asan/0077-winecfg-Do-not-call-strdup-with-a-null-pointer.patch new file mode 100644 index 0000000..b8d9c7f --- /dev/null +++ b/0015-bernhard-asan/0077-winecfg-Do-not-call-strdup-with-a-null-pointer.patch @@ -0,0 +1,97 @@ +From 9f383ebf8445851ee723ad1867e7cd06be0c8c4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 4 Nov 2024 17:42:22 +0100 +Subject: [PATCH 77/86] winecfg: Do not call strdup with a null pointer. + +This gets visible when ASAN replaces the strdup implementation, +which does not handle the NULL case like the msvcrt implementation. + +winecfg, Drives tab. + +Unhandled exception: page fault on read access to 0x0000000000000000 in 64-bit code (0x006ffffa38c300). +Register dump: + rip:00006ffffa38c300 rsp:00007ffffe1fca78 rbp:00007ffffe1fcb00 eflags:00010202 ( R- -- I - - - ) + rax:ffffffffffffffff rbx:000000014005b248 rcx:0000000000000000 rdx:000000002800b645 + rsi:0000000000000000 rdi:000000002800b649 r8:0000000000000000 r9:0000000000000000 r10:ffffffffffffffff + r11:0000000000000000 r12:0000000140200000 r13:0000000000000000 r14:0000000000000000 r15:00007f7ad88478a2 +Stack dump: +0x007ffffe1fca78: 00006ffffa3c6531 00006ffffdb6bc94 +0x007ffffe1fca88: 00006ffffad72d58 0000000000000400 +0x007ffffe1fca98: 00007ffffe1fcb80 0000000000000001 +0x007ffffe1fcaa8: 000000000000001e 00007ffffe1fcb90 +0x007ffffe1fcab8: 000000000000001c 00007ffffe1fcad0 +0x007ffffe1fcac8: 000000000000001c 00006ffffa3c6602 +0x007ffffe1fcad8: 0000000140009969 000000014000a6fb +0x007ffffe1fcae8: 000000014000d56e 00006ffffdc08d49 +0x007ffffe1fcaf8: 00006ffffdc0b13c 00006ffffdbcf529 +0x007ffffe1fcb08: 00006ffffdbcf7b5 00006ffffdc08c2b +0x007ffffe1fcb18: 00006ffffdc0ac44 00006ffffdbf179d +0x007ffffe1fcb28: 00006ffffdbf32ef 00006ffffdbd2d1b +Backtrace: +=>0 0x006ffffa38c300 in libclang_rt.asan_dynamic-x86_64 (+0xc300) (0x007ffffe1fcb00) + 1 0x006ffffa3c6531 __asan_wrap__strdup+0x31() in libclang_rt.asan_dynamic-x86_64 (0x007ffffe1fcb00) + 2 0x0000014000998c add_drive+0x13c(letter=, targetpath="../drive_c", device=0x00000000000000000, label=00007FFFFE1FD5D0, serial=0x43000000, type=0) [/home/bernhard/data/entwicklung/2024/wine/wine/programs/winecfg/drive.c:105] in winecfg.exe_asan (0x00000000000043) + 3 0x0000014000a6fb load_drives+0x22b() [/home/bernhard/data/entwicklung/2024/wine/wine/programs/winecfg/drive.c:0] in winecfg.exe_asan (0x007ffffe1fd440) + 4 0x0000014000d56e DriveDlgProc+0x58e(dialog=, msg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/programs/winecfg/driveui.c:660] in winecfg.exe_asan (0x007ffffe1fdf10) + 5 0x006ffffdc08d49 call_dialog_proc+0x59(hwnd=00000000000101B4, msg=0x110, wp=0x101ba, lp=0x7ffffe808028, result=00007FFFFE1FE058, arg=000000014000CFE0) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:86] in user32 (0x00000000000110) + 6 0x006ffffdc0b13c WINPROC_CallDlgProcW+0x6c(hwnd=00000000000101B4, msg=0x110, wParam=0x101ba, lParam=0x7ffffe808028) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:948] in user32 (0x000000000101ba) + 7 0x006ffffdbcf529 USER_DefDlgProcW+0x3b(lParam=, wParam=, msg=, hwnd=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:375] in user32 (0x007ffffe8328a0) + 8 0x006ffffdbcf529 USER_DefDlgProc+0x59(hwnd=, msg=, wParam=, lParam=, unicode=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:372] in user32 (0x007ffffe8328a0) + 9 0x006ffffdbcf7b5 DefDlgProcW+0x15(hwnd=, msg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:439] in user32 (0x007ffffe808028) + 10 0x006ffffdc08c2b call_window_proc+0x4b(hwnd=, msg=, wp=, lp=, result=[, arg=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:111] in user32 (0x007ffffe808028) + 11 0x006ffffdc0ac44 dispatch_win_proc_params+0x104(params=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:725] in user32 (0000000000000000) + 12 0x006ffffdbf179d dispatch_send_message+0x5d(params=, wparam=, lparam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:582] in user32 (0000000000000000) + 13 0x006ffffdbf32ef SendMessageW+0x4f(hwnd=, msg=, wparam=, lparam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:600] in user32 (0x00000050010003) + 14 0x006ffffdbd2d1b DIALOG_CreateIndirect+0xc0b(hInst=[, dlgTemplate=, owner=, dlgProc=[, param=[, unicode=[, modal_owner=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/dialog.c:676] in user32 (0x00000050010003) + 15 0x006ffffdbd40d4 CreateDialogIndirectParamW+0x24(hInst=, dlgTemplate=, owner=, dlgProc=, param=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/dialog.c:750] in user32 (0x00000000060128) + 16 0x006ffffc197772 HPSP_create_page+0x28(parent=, template=, hpsp=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:506] in comctl32 (0x00000000060128) + 17 0x006ffffc197772 PROPSHEET_CreatePage+0xd2(hwndParent=, index=, psInfo=, hpsp=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:1614] in comctl32 (0x00000000060128) + 18 0x006ffffc198158 PROPSHEET_SetCurSel+0x318(hwndDlg=, index=, skipdir=[, hpage=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:2169] in comctl32 (0x006ffffdbd0fe0) + 19 0x006ffffc19c7af PROPSHEET_DialogProc+0x20ef(hwnd=, uMsg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:3715] in comctl32 (0x0000000000004e) + 20 0x006ffffdc08d49 call_dialog_proc+0x59(hwnd=, msg=, wp=, lp=, result=[, arg=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:86] in user32 (0x0000000000004e) + 21 0x006ffffdc0b13c WINPROC_CallDlgProcW+0x6c(hwnd=, msg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:948] in user32 (0x00000000003020) + 22 0x006ffffdbcf529 USER_DefDlgProcW+0x3b(lParam=, wParam=, msg=, hwnd=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:375] in user32 (0x007ffffe819bf0) + 23 0x006ffffdbcf529 USER_DefDlgProc+0x59(hwnd=, msg=, wParam=, lParam=, unicode=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:372] in user32 (0x007ffffe819bf0) + 24 0x006ffffdbcf7b5 DefDlgProcW+0x15(hwnd=, msg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/defdlg.c:439] in user32 (0x007ffffe1ff0b0) + 25 0x006ffffdc08c2b call_window_proc+0x4b(hwnd=, msg=, wp=, lp=, result=[, arg=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:111] in user32 (0x007ffffe1ff0b0) + 26 0x006ffffdc0ac44 dispatch_win_proc_params+0x104(params=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:725] in user32 (0x00000100000002) + 27 0x006ffffdbf179d dispatch_send_message+0x5d(params=, wparam=, lparam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:582] in user32 (0x00000100000002) + 28 0x006ffffdbf32ef SendMessageW+0x4f(hwnd=, msg=, wparam=, lparam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:600] in user32 (0x00000000000005) + 29 0x006ffffc1b29b9 TAB_InsertItemT+0x12da(code=, infoPtr=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/tab.c:179] in comctl32 (0x00000000000005) + 30 0x006ffffc1b29b9 TAB_WindowProc+0x1459(hwnd=, uMsg=, wParam=, lParam=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/tab.c:3373] in comctl32 (0x00000000000005) + 31 0x006ffffdc08c2b call_window_proc+0x4b(hwnd=, msg=, wp=, lp=, result=[, arg=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:111] in user32 (0x00000000210062) + 32 0x006ffffdc0ac44 dispatch_win_proc_params+0x104(params=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/winproc.c:725] in user32 (0x006ffffdb6bc60) + 33 0x006ffffdbf1851 dispatch_message+0x61(msg=, ansi=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:855] in user32 (0x006ffffdb6bc60) + 34 0x006ffffdbf3afd DispatchMessageW+0x35(msg=[) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/message.c:943] in user32 (0x006ffffdb6bc60) + 35 0x006ffffdbd42d9 IsDialogMessageW+0x109(hwndDlg=, msg=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/user32/dialog.c:1294] in user32 (0x006ffffdb6bc60) + 36 0x006ffffc198905 do_loop+0x7d(psInfo=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:2971] in comctl32 (0x00000000060128) + 37 0x006ffffc198905 PROPSHEET_PropertySheet+0x2c5(psInfo=, unicode=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/comctl32/propsheet.c:3001] in comctl32 (0x00000000060128) + 38 0x000001400158cd doPropertySheet+0x40d(hInstance=) [/home/bernhard/data/entwicklung/2024/wine/wine/programs/winecfg/main.c:173] in winecfg.exe_asan (0x007ffffe1ffb10) + 39 0x00000140014872 wWinMain+0x3f2(hInstance=, hPrev=, cmdline=, nShow=) [/home/bernhard/data/entwicklung/2024/wine/wine/programs/winecfg/main.c:0] in winecfg.exe_asan (0x007ffffe1ffbe0) + 40 0x000001400250a3 wmain+0x203(argc=, argv=) in winecfg.exe_asan (0x007ffffe1ffee0) + 41 0x00000140024dcb wmainCRTStartup+0xfb() [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/msvcrt/crt_wmain.c:58] in winecfg.exe_asan (0000000000000000) + 42 0x006fffffa98d59 BaseThreadInitThunk+0x9(unknown=, entry=, arg=) [/home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32/thread.c:61] in kernel32 (0000000000000000) + 43 0x006fffffc95afb in ntdll (+0x55afb) (0000000000000000) +0x006ffffa38c300 libclang_rt.asan_dynamic-x86_64+0xc300: cmpb $0x00, 0x01(%rcx,%rax,1) +--- + programs/winecfg/drive.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/programs/winecfg/drive.c b/programs/winecfg/drive.c +index b113b71b199..0a1f930cbee 100644 +--- a/programs/winecfg/drive.c ++++ b/programs/winecfg/drive.c +@@ -101,8 +101,8 @@ BOOL add_drive(char letter, const char *targetpath, const char *device, const WC + wine_dbgstr_w(label), serial, type); + + drives[driveIndex].letter = toupper(letter); +- drives[driveIndex].unixpath = strdup(targetpath); +- drives[driveIndex].device = strdup(device); ++ drives[driveIndex].unixpath = targetpath ? strdup(targetpath) : NULL; ++ drives[driveIndex].device = device ? strdup(device) : NULL; + drives[driveIndex].label = wcsdup(label); + drives[driveIndex].serial = serial; + drives[driveIndex].type = type; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0078-wined3d-Set-pointer-to-NULL-after-free.patch b/0015-bernhard-asan/0078-wined3d-Set-pointer-to-NULL-after-free.patch new file mode 100644 index 0000000..9b61879 --- /dev/null +++ b/0015-bernhard-asan/0078-wined3d-Set-pointer-to-NULL-after-free.patch @@ -0,0 +1,94 @@ +From e941acf294b39b25b0e727d8b2d3bd6b95520b6f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Fri, 6 Dec 2024 22:44:27 +0100 +Subject: [PATCH 78/86] wined3d: Set pointer to NULL after free. + +d3d11:d3d11 +d3d10core:d3d10core + +ASAN_OPTIONS='verbosity=0:windows_hook_rtl_allocators=1' WINEDLLOVERRIDES="$F=n;*.dll=n" WINEDEBUG= wine64 z:/home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj/dlls/d3d11/tests/x86_64-windows/d3d11_test.exe d3d11 +... +0664:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 15.0.6, 256 bits)"). +================================================================= +==1556==ERROR: AddressSanitizer: attempting double-free on 0x7f9e9e29c440 in thread T13: +06f4:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffffbe8a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff8861db6 in shader_cleanup /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:1941:5 + #2 0x6ffff894bd2f in pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3162:9 + #3 0x6ffff894bd2f in wined3d_shader_create_ps /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3319:9 + #4 0x6ffffa08af3f in d3d_pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1445:9 + #5 0x6ffffa08af3f in d3d_pixel_shader_create /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1469:9 + #6 0x6ffffa073369 in d3d11_device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\device.c:4101:9 + #7 0x00014003327b in ID3D11Device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\d3d11.h:10924:12 + #8 0x00014003327b in test_create_shader /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:5097:10 + #9 0x0001401a6cb9 in run_mt_test /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:184:9 + #10 0x0001401a6cb9 in thread_func /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:201:13 + #11 0x6ffffbe9b2dd in asan_thread_start(void*) /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:147:14 + #12 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #13 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f9e9e29c440 is located 0 bytes inside of 288-byte region [0x7f9e9e29c440,0x7f9e9e29c560) +freed by thread T13 here: + #0 0x6ffffbe8a1a1 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff8861db6 in shader_cleanup /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:1941:5 + #2 0x6ffff887fe17 in shader_set_function /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:2393:13 + #3 0x6ffff894bcda in pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3159:9 + #4 0x6ffff894bcda in wined3d_shader_create_ps /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3319:9 + #5 0x6ffffa08af3f in d3d_pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1445:9 + #6 0x6ffffa08af3f in d3d_pixel_shader_create /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1469:9 + #7 0x6ffffa073369 in d3d11_device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\device.c:4101:9 + #8 0x00014003327b in ID3D11Device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\d3d11.h:10924:12 + #9 0x00014003327b in test_create_shader /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:5097:10 + #10 0x0001401a6cb9 in run_mt_test /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:184:9 + #11 0x0001401a6cb9 in thread_func /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:201:13 + #12 0x6ffffbe9b2dd in asan_thread_start(void*) /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:147:14 + #13 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #14 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T13 here: + #0 0x6ffffbe8a2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff887fa8c in shader_set_function /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:2382:35 + #2 0x6ffff894bcda in pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3159:9 + #3 0x6ffff894bcda in wined3d_shader_create_ps /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:3319:9 + #4 0x6ffffa08af3f in d3d_pixel_shader_init /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1445:9 + #5 0x6ffffa08af3f in d3d_pixel_shader_create /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\shader.c:1469:9 + #6 0x6ffffa073369 in d3d11_device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine/dlls/d3d11\device.c:4101:9 + #7 0x00014003327b in ID3D11Device_CreatePixelShader /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\d3d11.h:10924:12 + #8 0x00014003327b in test_create_shader /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:5097:10 + #9 0x0001401a6cb9 in run_mt_test /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:184:9 + #10 0x0001401a6cb9 in thread_func /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:201:13 + #11 0x6ffffbe9b2dd in asan_thread_start(void*) /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:147:14 + #12 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #13 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Thread T13 created by T0 here: + #0 0x6ffffbe9b1f6 in CreateThread /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_win.cpp:158:3 + #1 0x00014000801c in run_queued_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:229:22 + #2 0x00014000801c in func_d3d11 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d3d11/tests/d3d11.c:36786:5 + #3 0x0001401a8823 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #4 0x0001401a826b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #5 0x0001401aa1df in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #6 0x6fffffa54808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #7 0x6fffffc2fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: double-free /home/bernhard/data/entwicklung/2024/wine/wine/dlls/wined3d\shader.c:1941:5 in shader_cleanup +==1556==ABORTING +--- + dlls/wined3d/shader.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +index c40dc69e8ec..2fa513d7a37 100644 +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -1939,6 +1939,7 @@ static void shader_cleanup(struct wined3d_shader *shader) + shader->device->shader_backend->shader_destroy(shader); + shader_cleanup_reg_maps(&shader->reg_maps); + free(shader->byte_code); ++ shader->byte_code = NULL; + shader_delete_constant_list(&shader->constantsF); + shader_delete_constant_list(&shader->constantsB); + shader_delete_constant_list(&shader->constantsI); +-- +2.47.1 + diff --git a/0015-bernhard-asan/0079-wined3d-Increase-allocation-size-to-avoid-buffer-ove.patch b/0015-bernhard-asan/0079-wined3d-Increase-allocation-size-to-avoid-buffer-ove.patch new file mode 100644 index 0000000..86cbfb0 --- /dev/null +++ b/0015-bernhard-asan/0079-wined3d-Increase-allocation-size-to-avoid-buffer-ove.patch @@ -0,0 +1,110 @@ +From 5d678ab5df098678c6488eec9957a78c01be515d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sun, 8 Dec 2024 23:58:21 +0100 +Subject: [PATCH 79/86] wined3d: Increase allocation size to avoid buffer + overflow. + +042c:fixme:d3dx:save_dds_surface_to_memory Default palette unimplemented. +================================================================= +==1084==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f2bb9b05220 at pc 0x6ffff88f8bfb bp 0x7ffffe1fe950 sp 0x7ffffe1fe998 +READ of size 8 at 0x7f2bb9b05220 thread T0 +042c:fixme:dbghelp:elf_search_auxv can't find symbol in module +042c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F25144B0B80,symt:0000000000000000) in ctx(00007F253C3F4A20,L"libclang_rt.asan_dynamic-x86_64") +042c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F2517EA0B80,symt:0000000000000000) in ctx(00007F25581C1D20,L"d3dx9_36") +042c:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r15/343 -> rbx/329) +042c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F2517F90B80,symt:0000000000000000) in ctx(00007F2558311590,L"d3dx9_36_test") + #0 0x6ffff88f8bfa in __asan_memcpy+0x3aa (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x180048bfa) + #1 0x6ffff833da0f in copy_pixels Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2166 + #2 0x6ffff8342c4e in d3dx_load_pixels_from_pixels Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2534 + #3 0x6ffff8347583 in D3DXSaveSurfaceToFileInMemory Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:3023 + #4 0x0001401775bf in func_surface+0x1fef (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x1401775bf) + #5 0x00014020bec7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x14020bec7) + #6 0x00014020de1f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #7 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #8 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f2bb9b05220 is located 0 bytes after 32-byte region [0x7f2bb9b05200,0x7f2bb9b05220) +allocated by thread T1 here: +042c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F24FFE40B80,symt:0000000000000000) in ctx(00007F2558142890,L"wined3d") +042c:fixme:dbghelp_dwarf:compute_location Only supporting one breg (r12/340 -> rbx/329) +042c:fixme:dbghelp_dwarf:compute_location Only supporting one breg (rsi/332 -> rbx/329) + #0 0x6ffff88fa3d6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a3d6) + #1 0x6ffff6560c30 in wined3d_resource_prepare_sysmem Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\resource.c + #2 0x6ffff65c385f in wined3d_texture_load_location Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\texture.c:817 + #3 0x6ffff65d9b5f in texture_resource_sub_resource_map Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\texture.c:3507 + #4 0x6ffff64aa1f9 in wined3d_cs_exec_map+0xc9 (C:\windows\system32\wined3d.dll+0x1800aa1f9) + #5 0x6ffff64ace18 in wined3d_cs_execute_next+0x138 (C:\windows\system32\wined3d.dll+0x1800ace18) + #6 0x6ffff649dd3c in wined3d_cs_run+0x1ac (C:\windows\system32\wined3d.dll+0x18009dd3c) + #7 0x6ffff890b2dd in asan_thread_start+0x4d (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18005b2dd) + #8 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #9 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Thread T1 created by T0 here: +042c:fixme:dbghelp_dwarf:dwarf2_load_one_entry Unhandled Tag type 0xa at debug_info(abbrev:00007F25179B0B80,symt:0000000000000000) in ctx(00007F253C1F15B0,L"d3d9") + #0 0x6ffff890b1f6 in CreateThread+0x66 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18005b1f6) + #1 0x6ffff649d89b in wined3d_cs_create+0x44b (C:\windows\system32\wined3d.dll+0x18009d89b) + #2 0x6ffff64d56ec in wined3d_device_init Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\device.c:5558 + #3 0x6ffff6415da4 in adapter_gl_create_device Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\adapter_gl.c:4081 + #4 0x6ffff64e30e5 in wined3d_device_create Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\wined3d\directx.c:2766 + #5 0x6ffff586ade1 in device_init Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d9\device.c:4680 + #6 0x6ffff588030e in d3d9_CreateDevice Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3d9\directx.c:498 + #7 0x000140175812 in func_surface+0x242 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x140175812) + #8 0x00014020bec7 in main+0x777 (Z:\home\bernhard\data\entwicklung\2024\wine\wine-build\build-asan-pe\64\obj\dlls\d3dx9_36\tests\x86_64-windows\d3dx9_36_test.exe+0x14020bec7) + #9 0x00014020de1f in mainCRTStartup Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\msvcrt\crt_main.c:58 + #10 0x6ffffbfd4808 in BaseThreadInitThunk Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\kernel32\thread.c:61 + #11 0x6ffffacefa1a (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow Z:\home\bernhard\data\entwicklung\2024\wine\wine\dlls\d3dx9_36\surface.c:2166 in copy_pixels +Shadow bytes around the buggy address: + 0x7f2bb9b04f80: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd + 0x7f2bb9b05000: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa + 0x7f2bb9b05080: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd + 0x7f2bb9b05100: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd + 0x7f2bb9b05180: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa +=>0x7f2bb9b05200: 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa + 0x7f2bb9b05280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2bb9b05300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2bb9b05380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2bb9b05400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2bb9b05480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1084==ABORTING +make: *** [Makefile:106630: dlls/d3dx9_36/tests/x86_64-windows/surface.ok] Fehler 1 +--- + dlls/wined3d/resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index fcfe05db835..5ba72cccfa9 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -322,7 +322,7 @@ static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) + static const SIZE_T align = RESOURCE_ALIGNMENT; + void *mem; + +- if (!(mem = calloc(1, resource->size + align))) ++ if (!(mem = calloc(1, resource->size + align + 8))) + { + ERR("Failed to allocate system memory.\n"); + return FALSE; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0080-wined3d-Avoid-threads-for-now-still-fails.patch b/0015-bernhard-asan/0080-wined3d-Avoid-threads-for-now-still-fails.patch new file mode 100644 index 0000000..a241aec --- /dev/null +++ b/0015-bernhard-asan/0080-wined3d-Avoid-threads-for-now-still-fails.patch @@ -0,0 +1,206 @@ +From 0da843e7174a1d71825e50f381ad1829163626c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Sat, 14 Dec 2024 17:31:58 +0100 +Subject: [PATCH 80/86] wined3d: Avoid threads for now, still fails. + +dlls/d2d1/tests/x86_64-windows/d2d1.ok +dlls/d3d10core/tests/x86_64-windows/d3d10core.ok +dlls/d3d11/tests/x86_64-windows/d3d11.ok +dlls/dxgi/tests/x86_64-windows/dxgi.ok +dlls/evr/tests/x86_64-windows/evr.ok +dlls/mfplat/tests/x86_64-windows/mfplat.ok + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M d2d1.dll -p dlls/d2d1/tests/x86_64-windows/d2d1_test.exe d2d1 && touch dlls/d2d1/tests/x86_64-windows/d2d1.ok +05dc:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 15.0.6, 256 bits)"). +05dc:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION +05dc:fixme:dxgi:DXGID3D10CreateDevice Ignoring flags 0x20. +05dc:fixme:dwrite:dwritefactory_CreateMonitorRenderingParams (0000000000000001): monitor setting ignored +05dc:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts. +05dc:fixme:d3d11:d3d11_device_context_SwapDeviceContextState D3D10 interface emulation not fully implemented yet! +================================================================= +==1492==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f2a74121798 at pc 0x6ffff4c053b6 bp 0x7ffffe1ff300 sp 0x7ffffe1ff348 +READ of size 8 at 0x7f2a74121798 thread T0 +0308:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff4c053b5 in wined3d_context_gl_update_window /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/context_gl.c:1338:56 + #1 0x6ffff4c053b5 in wined3d_context_gl_activate /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/context_gl.c:4329:5 + #2 0x6ffff4c04d94 in wined3d_context_gl_acquire /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/context_gl.c:4399:5 + #3 0x6ffff4d78777 in context_acquire /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/wined3d_private.h:4751:12 + #4 0x6ffff4d78777 in texture_resource_unload /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/texture.c:3389:15 + #5 0x6ffff4c41cd0 in wined3d_cs_st_submit /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/cs.c:2988:9 + #6 0x6ffff4c520cb in wined3d_device_uninit_3d /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/device.c:1739:9 + #7 0x6ffff4d52bba in wined3d_swapchain_decref /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/swapchain.c:158:13 + #8 0x6ffff83b6f90 in dxgi_device_Release /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/device.c:98:9 + #9 0x0001400e22ab in IDXGIDevice_Release /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dxgi.h:2110:12 + #10 0x0001400e22ab in release_test_context_ /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1281:11 + #11 0x00014000a720 in test_clip /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1890:5 + #12 0x00014000633b in run_queued_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:456:13 + #13 0x00014000633b in func_d2d1 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:15540:5 + #14 0x0001400fbb03 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #15 0x0001400fb54b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #16 0x0001400fd4df in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #17 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #18 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f2a74121798 is located 1816 bytes inside of 1824-byte region [0x7f2a74121080,0x7f2a741217a0) +freed by thread T0 here: + #0 0x6ffffa57a041 in free /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:71:3 + #1 0x6ffff4d52ca7 in wined3d_swapchain_decref /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/swapchain.c:162:9 + #2 0x6ffff83cbbee in d3d11_swapchain_Release /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/swapchain.c:243:9 + #3 0x0001400e2245 in IDXGISwapChain_Release /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dxgi.h:1737:12 + #4 0x0001400e2245 in release_test_context_ /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1279:5 + #5 0x00014000a720 in test_clip /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1890:5 + #6 0x00014000633b in run_queued_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:456:13 + #7 0x00014000633b in func_d2d1 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:15540:5 + #8 0x0001400fbb03 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #9 0x0001400fb54b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #10 0x0001400fd4df in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #11 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #12 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +previously allocated by thread T0 here: + #0 0x6ffffa57a276 in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x6ffff4bb797b in adapter_gl_create_swapchain /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/adapter_gl.c:4425:26 + #2 0x6ffff4d57006 in wined3d_swapchain_create /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/swapchain.c:1740:9 + #3 0x6ffff83c83e5 in d3d11_swapchain_init /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/swapchain.c:1020:9 + #4 0x6ffff83b986c in dxgi_swapchain_factory_create_swapchain /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/device.c:464:9 + #5 0x6ffff83bdf38 in IWineDXGISwapChainFactory_create_swapchain /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include/wine\winedxgi.h:146:12 + #6 0x6ffff83bdf38 in dxgi_factory_CreateSwapChainForHwnd /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/factory.c:302:14 + #7 0x6ffff83bd6cd in IWineDXGIFactory_CreateSwapChainForHwnd /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include/wine\winedxgi.h:1024:12 + #8 0x6ffff83bd6cd in dxgi_factory_CreateSwapChain /home/bernhard/data/entwicklung/2024/wine\wine/dlls/dxgi/factory.c:238:12 + #9 0x0001400e2e42 in IDXGIFactory_CreateSwapChain /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\dxgi.h:1958:12 + #10 0x0001400e2e42 in create_swapchain /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1211:10 + #11 0x0001400e0c02 in init_test_context_ /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1302:22 + #12 0x000140007de7 in test_clip /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:1721:10 + #13 0x00014000633b in run_queued_tests /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:456:13 + #14 0x00014000633b in func_d2d1 /home/bernhard/data/entwicklung/2024/wine\wine/dlls/d2d1/tests/d2d1.c:15540:5 + #15 0x0001400fbb03 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #16 0x0001400fb54b in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h + #17 0x0001400fd4df in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #18 0x6ffffc1c4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #19 0x6ffffc39fa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-use-after-free /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wined3d/context_gl.c:1338:56 in wined3d_context_gl_update_window +Shadow bytes around the buggy address: + 0x7f2a74121500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +=>0x7f2a74121780: fd fd fd[fd]fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2a74121800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f2a74121880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121980: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd + 0x7f2a74121a00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1492==ABORTING +make: *** [Makefile:41397: dlls/d2d1/tests/x86_64-windows/d2d1.ok] Fehler 1 +0308:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +--- + dlls/d2d1/tests/d2d1.c | 2 +- + dlls/d3d10core/tests/d3d10core.c | 2 +- + dlls/d3d11/tests/d3d11.c | 2 +- + dlls/dxgi/swapchain.c | 2 +- + dlls/dxgi/tests/dxgi.c | 2 +- + dlls/wined3d/wined3d_main.c | 2 +- + 6 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c +index 625ad53292f..f9e16c4cb64 100644 +--- a/dlls/d2d1/tests/d2d1.c ++++ b/dlls/d2d1/tests/d2d1.c +@@ -15451,7 +15451,7 @@ START_TEST(d2d1) + pD2D1Vec3Length = (void *)GetProcAddress(d2d1_dll, "D2D1Vec3Length"); + pD2D1ConvertColorSpace = (void *)GetProcAddress(d2d1_dll, "D2D1ConvertColorSpace"); + +- use_mt = !getenv("WINETEST_NO_MT_D3D"); ++ use_mt = 0;//!getenv("WINETEST_NO_MT_D3D"); + /* Some host drivers (MacOS, Mesa radeonsi) never unmap memory even when + * requested. When using the chunk allocator, running the tests with more + * than one thread can exceed the 32-bit virtual address space. */ +diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c +index 9cb0ec118a4..dec69121ec8 100644 +--- a/dlls/d3d10core/tests/d3d10core.c ++++ b/dlls/d3d10core/tests/d3d10core.c +@@ -19722,7 +19722,7 @@ START_TEST(d3d10core) + damavand = true; + } + +- use_mt = !getenv("WINETEST_NO_MT_D3D"); ++ use_mt = 0;//!getenv("WINETEST_NO_MT_D3D"); + /* Some host drivers (MacOS, Mesa radeonsi) never unmap memory even when + * requested. When using the chunk allocator, running the tests with more + * than one thread can exceed the 32-bit virtual address space. */ +diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c +index 9c5b35faafa..7a51c8016d6 100644 +--- a/dlls/d3d11/tests/d3d11.c ++++ b/dlls/d3d11/tests/d3d11.c +@@ -36597,7 +36597,7 @@ START_TEST(d3d11) + damavand = true; + } + +- use_mt = !getenv("WINETEST_NO_MT_D3D"); ++ use_mt = 0;//!getenv("WINETEST_NO_MT_D3D"); + /* Some host drivers (MacOS, Mesa radeonsi) never unmap memory even when + * requested. When using the chunk allocator, running the tests with more + * than one thread can exceed the 32-bit virtual address space. */ +diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c +index 4797fcecd8d..3aa9d752f73 100644 +--- a/dlls/dxgi/swapchain.c ++++ b/dlls/dxgi/swapchain.c +@@ -1008,7 +1008,7 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi + + swapchain->IDXGISwapChain4_iface.lpVtbl = &d3d11_swapchain_vtbl; + swapchain->state_parent.ops = &d3d11_swapchain_state_parent_ops; +- swapchain->refcount = 1; ++ swapchain->refcount = 1; /* setting to 2 would avoid the free, but tests would fail because of this */ + wined3d_mutex_lock(); + wined3d_private_store_init(&swapchain->private_store); + +diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c +index 912bcd8fa61..db8cfa51cd0 100644 +--- a/dlls/dxgi/tests/dxgi.c ++++ b/dlls/dxgi/tests/dxgi.c +@@ -8018,7 +8018,7 @@ START_TEST(dxgi) + registry_mode.dmSize = sizeof(registry_mode); + ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, ®istry_mode), "Failed to get display mode.\n"); + +- use_mt = !getenv("WINETEST_NO_MT_D3D"); ++ use_mt = 0;//!getenv("WINETEST_NO_MT_D3D"); + /* Some host drivers (MacOS, Mesa radeonsi) never unmap memory even when + * requested. When using the chunk allocator, running the tests with more + * than one thread can exceed the 32-bit virtual address space. */ +diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c +index 3b436919559..02599ac0bb4 100644 +--- a/dlls/wined3d/wined3d_main.c ++++ b/dlls/wined3d/wined3d_main.c +@@ -115,7 +115,7 @@ CRITICAL_SECTION wined3d_command_cs = {&wined3d_command_cs_debug, -1, 0, 0, 0, 0 + * where appropriate. */ + struct wined3d_settings wined3d_settings = + { +- .cs_multithreaded = WINED3D_CSMT_ENABLE, ++ .cs_multithreaded = 0/*WINED3D_CSMT_ENABLE*/, + .max_gl_version = MAKEDWORD_VERSION(4, 4), + .pci_vendor_id = PCI_VENDOR_NONE, + .pci_device_id = PCI_DEVICE_NONE, +-- +2.47.1 + diff --git a/0015-bernhard-asan/0081-windowscodecs-Workaround-by-increasing-buffer.patch b/0015-bernhard-asan/0081-windowscodecs-Workaround-by-increasing-buffer.patch new file mode 100644 index 0000000..7835b56 --- /dev/null +++ b/0015-bernhard-asan/0081-windowscodecs-Workaround-by-increasing-buffer.patch @@ -0,0 +1,100 @@ +From 0ca2e56b13c6da5ff09862a8345e7cd0bbf92d58 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 11:33:31 +0100 +Subject: [PATCH 81/86] windowscodecs: Workaround by increasing buffer. + +================================================================= +==716==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f0814161054 at pc 0x6ffff67f2579 bp 0x7ffffe1fd980 sp 0x7ffffe1fd9c8 +READ of size 1 at 0x7f0814161054 thread T0 +02b8:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff67f2578 in tiff_decoder_read_tile /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/libtiff.c:796:27 + #1 0x6ffff67f2578 in tiff_decoder_copy_pixels /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/libtiff.c:954:22 + #2 0x6ffff67b0e27 in CommonDecoderFrame_CopyPixels /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/decoder.c:423:10 + #3 0x0001401023c3 in IWICBitmapFrameDecode_CopyPixels /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\wincodec.h:2018:12 + #4 0x0001401023c3 in test_color_formats /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/tests/tiffformat.c:1247:14 + #5 0x0001401023c3 in func_tiffformat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/tests/tiffformat.c:1339:5 + #6 0x000140113d31 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #7 0x000140113d31 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #8 0x000140115c7f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #9 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f0814161054 is located 0 bytes after 4-byte region [0x7f0814161050,0x7f0814161054) +allocated by thread T0 here: + #0 0x6ffff84ba2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff67f096d in tiff_decoder_read_tile /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/libtiff.c:783:19 + #2 0x6ffff67f096d in tiff_decoder_copy_pixels /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/libtiff.c:954:22 + #3 0x6ffff67b0e27 in CommonDecoderFrame_CopyPixels /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/decoder.c:423:10 + #4 0x0001401023c3 in IWICBitmapFrameDecode_CopyPixels /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\wincodec.h:2018:12 + #5 0x0001401023c3 in test_color_formats /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/tests/tiffformat.c:1247:14 + #6 0x0001401023c3 in func_tiffformat /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/tests/tiffformat.c:1339:5 + #7 0x000140113d31 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #8 0x000140113d31 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #9 0x000140115c7f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #10 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #11 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/windowscodecs/libtiff.c:796:27 in tiff_decoder_read_tile +Shadow bytes around the buggy address: + 0x7f0814160d80: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa + 0x7f0814160e00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa + 0x7f0814160e80: fa fa fd fa fa fa 00 00 fa fa 00 00 fa fa 00 00 + 0x7f0814160f00: fa fa fd fa fa fa fd fd fa fa 04 fa fa fa 04 fa + 0x7f0814160f80: fa fa 04 fa fa fa fd fa fa fa 00 fa fa fa fd fa +=>0x7f0814161000: fa fa 02 fa fa fa 00 fa fa fa[04]fa fa fa fa fa + 0x7f0814161080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0814161100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0814161180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0814161200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0814161280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==716==ABORTING +02b8:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:423367: dlls/windowscodecs/tests/x86_64-windows/tiffformat.ok] Fehler 1 +--- + dlls/windowscodecs/libtiff.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/windowscodecs/libtiff.c b/dlls/windowscodecs/libtiff.c +index 16701a258f9..ca5ccf3237a 100644 +--- a/dlls/windowscodecs/libtiff.c ++++ b/dlls/windowscodecs/libtiff.c +@@ -780,7 +780,7 @@ static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UI + + count = width_bytes * info->tile_height; + +- srcdata = malloc(count); ++ srcdata = malloc(count + 1); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + +@@ -819,7 +819,7 @@ static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UI + + count = width_bytes * info->tile_height; + +- srcdata = malloc(count); ++ srcdata = malloc(count + 2); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + +-- +2.47.1 + diff --git a/0015-bernhard-asan/0082-winhttp-Do-not-overrun-buffer.patch b/0015-bernhard-asan/0082-winhttp-Do-not-overrun-buffer.patch new file mode 100644 index 0000000..0c2a16b --- /dev/null +++ b/0015-bernhard-asan/0082-winhttp-Do-not-overrun-buffer.patch @@ -0,0 +1,91 @@ +From a9b3e2ddcdca7881d0bc5fd1f2eea502396c4308 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 11:13:32 +0100 +Subject: [PATCH 82/86] winhttp: Do not overrun buffer. + +================================================================= +==956==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f63049403bc at pc 0x6ffff7e1cf4a bp 0x7fffff8ff7e0 sp 0x7fffff8ff828 +READ of size 2 at 0x7f63049403bc thread T-1 +03d0:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff7e1cf49 in add_request_headers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/winhttp/request.c:500:16 + #1 0x6ffff7e1d3e2 in WinHttpAddRequestHeaders /home/bernhard/data/entwicklung/2024/wine\wine/dlls/winhttp/request.c:541:11 + #2 0x6ffff7ff55d5 in insert_http_header /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/msg.c:1912:9 + #3 0x6ffff7ff55d5 in message_insert_http_headers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/msg.c:1985:15 + #4 0x6ffff7fd6825 in send_message_bytes /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1560:19 + #5 0x6ffff7fe2103 in send_message /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1731:10 + #6 0x6ffff7fe1e45 in send_message_proc /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1755:10 + #7 0x6ffff7fde5ae in queue_runner /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:133:17 + #8 0x6ffffa903ad9 in tp_object_execute /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\threadpool.c:2233:13 + #9 0x6ffffa90293f in threadpool_worker_proc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\threadpool.c:2364:13 + #10 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #11 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f63049403bc is located 0 bytes after 44-byte region [0x7f6304940390,0x7f63049403bc) +allocated by thread T0 here: + #0 0x6ffff84ba2c1 in malloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:80:3 + #1 0x6ffff7ff5545 in build_http_header /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/msg.c:1899:18 + #2 0x6ffff7ff5545 in message_insert_http_headers /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/msg.c:1972:18 + #3 0x6ffff7fd6825 in send_message_bytes /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1560:19 + #4 0x6ffff7fe2103 in send_message /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1731:10 + #5 0x6ffff7fe1e45 in send_message_proc /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:1755:10 + #6 0x6ffff7fde5ae in queue_runner /home/bernhard/data/entwicklung/2024/wine\wine/dlls/webservices/channel.c:133:17 + #7 0x6ffffa903ad9 in tp_object_execute /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\threadpool.c:2233:13 + #8 0x6ffffa90293f in threadpool_worker_proc /home/bernhard/data/entwicklung/2024/wine/wine/dlls/ntdll\threadpool.c:2364:13 + #9 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/winhttp/request.c:500:16 in add_request_headers +Shadow bytes around the buggy address: + 0x7f6304940100: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa + 0x7f6304940180: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd + 0x7f6304940200: fa fa 00 00 00 00 06 fa fa fa 00 00 00 00 00 02 + 0x7f6304940280: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa + 0x7f6304940300: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 02 +=>0x7f6304940380: fa fa 00 00 00 00 00[04]fa fa fa fa fa fa fa fa + 0x7f6304940400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f6304940480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f6304940500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f6304940580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f6304940600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==956==ABORTING +03d0:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:398531: dlls/webservices/tests/x86_64-windows/proxy.ok] Fehler 1 +--- + dlls/winhttp/request.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c +index cd3e4200e73..0a54e64d093 100644 +--- a/dlls/winhttp/request.c ++++ b/dlls/winhttp/request.c +@@ -497,7 +497,7 @@ DWORD add_request_headers( struct request *request, const WCHAR *headers, DWORD + for (q = p; q < headers + len && *q != '\r' && *q != '\n'; ++q) + ; + end = q; +- while (*q == '\r' || *q == '\n') ++ while ((q < headers + len) && (*q == '\r' || *q == '\n')) + ++q; + + if ((header = parse_header( p, end - p, FALSE ))) +-- +2.47.1 + diff --git a/0015-bernhard-asan/0083-wintrust-Reserve-at-least-sizeof-CRYPT_ATTRIBUTES.patch b/0015-bernhard-asan/0083-wintrust-Reserve-at-least-sizeof-CRYPT_ATTRIBUTES.patch new file mode 100644 index 0000000..f1f1498 --- /dev/null +++ b/0015-bernhard-asan/0083-wintrust-Reserve-at-least-sizeof-CRYPT_ATTRIBUTES.patch @@ -0,0 +1,93 @@ +From a0f09f48ed63d7ef29d5567e631b2aa74e263f15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 11:41:44 +0100 +Subject: [PATCH 83/86] wintrust: Reserve at least sizeof(CRYPT_ATTRIBUTES). + +================================================================= +==664==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f0036560070 at pc 0x6ffff81773cc bp 0x7ffffe1fc3e0 sp 0x7ffffe1fc428 +READ of size 4 at 0x7f0036560070 thread T0 +029c:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff81773cb in SoftpubLoadSignature /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/softpub.c + #1 0x6ffff81800b6 in WINTRUST_ExecuteSteps /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:174:15 + #2 0x6ffff81800b6 in WINTRUST_DefaultVerify /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:289:11 + #3 0x6ffff817f01c in WinVerifyTrust /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:708:19 + #4 0x00014003dd45 in call_winverify /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1611:15 + #5 0x000140032938 in test_wintrust_digest /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1709:9 + #6 0x000140032938 in func_softpub /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1934:5 + #7 0x00014003f407 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #8 0x00014003f407 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #9 0x0001400412ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #10 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #11 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +0x7f0036560071 is located 0 bytes after 1-byte region [0x7f0036560070,0x7f0036560071) +allocated by thread T0 here: + #0 0x6ffff84ba3d6 in calloc /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/asan_malloc_win.cpp:91:3 + #1 0x6ffff8175f71 in load_secondary_signatures /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/softpub.c:842:19 + #2 0x6ffff8175f71 in SoftpubLoadSignature /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/softpub.c:909:13 + #3 0x6ffff81800b6 in WINTRUST_ExecuteSteps /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:174:15 + #4 0x6ffff81800b6 in WINTRUST_DefaultVerify /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:289:11 + #5 0x6ffff817f01c in WinVerifyTrust /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/wintrust_main.c:708:19 + #6 0x00014003dd45 in call_winverify /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1611:15 + #7 0x000140032938 in test_wintrust_digest /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1709:9 + #8 0x000140032938 in func_softpub /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/tests/softpub.c:1934:5 + #9 0x00014003f407 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #10 0x00014003f407 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #11 0x0001400412ef in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #12 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #13 0x6ffffa8afa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +SUMMARY: AddressSanitizer: heap-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/wintrust/softpub.c in SoftpubLoadSignature +Shadow bytes around the buggy address: + 0x7f003655fd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f003655fe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f003655fe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f003655ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7f003655ff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x7f0036560000: fa fa fd fa fa fa 00 00 fa fa 00 fa fa fa[01]fa + 0x7f0036560080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0036560100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0036560180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0036560200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x7f0036560280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==664==ABORTING +029c:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:446808: dlls/wintrust/tests/x86_64-windows/softpub.ok] Fehler 1 +--- + dlls/wintrust/softpub.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wintrust/softpub.c b/dlls/wintrust/softpub.c +index 609d240a738..0cccac47246 100644 +--- a/dlls/wintrust/softpub.c ++++ b/dlls/wintrust/softpub.c +@@ -838,6 +838,7 @@ static void load_secondary_signatures(CRYPT_PROVIDER_DATA *data, HCRYPTMSG msg) + + if (!CryptMsgGetParam(msg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, NULL, &size)) + return; ++ size = max(size, sizeof(*attrs)); + + if (!(attrs = data->psPfns->pfnAlloc(size))) + { +-- +2.47.1 + diff --git a/0015-bernhard-asan/0084-xmllite-Access-memory-with-right-typed-pointer.patch b/0015-bernhard-asan/0084-xmllite-Access-memory-with-right-typed-pointer.patch new file mode 100644 index 0000000..b5cb8f5 --- /dev/null +++ b/0015-bernhard-asan/0084-xmllite-Access-memory-with-right-typed-pointer.patch @@ -0,0 +1,195 @@ +From 836d68ec691fdab35bcff312b430edbb6efd3ae6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 10 Dec 2024 23:29:07 +0100 +Subject: [PATCH 84/86] xmllite: Access memory with right typed pointer. + +/home/bernhard/data/entwicklung/2024/wine/wine/tools/runtest -q -P wine -T . -M xmllite.dll -p dlls/xmllite/tests/x86_64-windows/xmllite_test.exe reader && touch dlls/xmllite/tests/x86_64-windows/reader.ok +06a4:fixme:xmllite:xmlreader_QueryInterface interface {0000000c-0000-0000-c000-000000000046} not implemented +================================================================= +==1696==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1ff8c0 at pc 0x6ffff8583f83 bp 0x7ffffe1fed00 sp 0x7ffffe1fed48 +WRITE of size 8 at 0x7ffffe1ff8c0 thread T0 +06ac:fixme:file:server_get_file_info Unsupported info class e + #0 0x6ffff8583f82 in xmlreader_GetProperty /home/bernhard/data/entwicklung/2024/wine\wine/dlls/xmllite/reader.c:2807:20 + #1 0x000140002254 in IXmlReader_GetProperty /home/bernhard/data/entwicklung/2024/wine/wine-build/build-asan-pe/64/obj\include\xmllite.h:331:12 + #2 0x000140002254 in test_reader_create /home/bernhard/data/entwicklung/2024/wine\wine/dlls/xmllite/tests/reader.c:582:10 + #3 0x000140002254 in func_reader /home/bernhard/data/entwicklung/2024/wine\wine/dlls/xmllite/tests/reader.c:2676:5 + #4 0x00014006bad1 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00014006bad1 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x00014006d94f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x6ffffabf4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #8 0x6ffffadcfa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ff8c0 is located in stack of thread T0 at offset 2784 in frame + #0 0x00014000100f in func_reader /home/bernhard/data/entwicklung/2024/wine\wine/dlls/xmllite/tests/reader.c:2675 + + This frame has 113 object(s): + [32, 36) 'd.i439.i' (line 824) + [48, 52) 'd.i412.i' (line 824) + [64, 68) 'd.i385.i' (line 824) + [80, 84) 'd.i358.i' (line 824) + [96, 100) 'd.i307.i' (line 824) + [112, 116) 'd.i280.i' (line 824) + [128, 132) 'd.i253.i' (line 824) + [144, 148) 'd.i178.i' (line 824) + [160, 164) 'd.i.i2162' (line 824) + [176, 184) 'reader.i2163' (line 2595) + [208, 216) 'reader.i1948' (line 2473) + [240, 248) 'reader.i1791' (line 2407) + [272, 276) 'type.i1792' (line 2408) + [288, 292) 'position.i' (line 2409) + [304, 308) 'd.i320.i' (line 824) + [320, 324) 'd.i294.i' (line 824) + [336, 340) 'd.i267.i' (line 824) + [352, 356) 'd.i240.i' (line 824) + [368, 372) 'd.i177.i' (line 824) + [384, 388) 'd.i150.i' (line 824) + [400, 404) 'd.i.i1643' (line 824) + [416, 420) 'nodetype.i1644' (line 2311) + [432, 440) 'reader.i1645' (line 2313) + [464, 472) 'reader.i1535' (line 2242) + [496, 500) 'type.i1536' (line 2243) + [512, 520) 'reader.i1450' (line 2190) + [544, 548) 'type.i1451' (line 2191) + [560, 568) 'value.i1315' (line 2137) + [592, 600) 'reader.i1316' (line 2138) + [624, 628) 'type.i1317' (line 2139) + [640, 648) 'reader.i1225' (line 2072) + [672, 676) 'type.i1226' (line 2073) + [688, 696) 'local.i1227' (line 2087) + [720, 728) 'qname.i1228' (line 2087) + [752, 756) 'length.i' (line 2088) + [768, 772) 'length2.i' (line 2088) + [784, 792) 'reader.i1156' (line 1998) + [816, 820) 'type.i1157' (line 2006) + [832, 840) 'reader.i1102' (line 1959) + [864, 872) 'value.i1103' (line 1960) + [896, 900) 'd.i723.i' (line 824) + [912, 916) 'd.i473.i' (line 824) + [928, 932) 'd.i.i' (line 824) + [944, 952) 'reader.i985' (line 849) + [976, 980) 'type.i986' (line 852) + [992, 996) 'count.i987' (line 853) + [1008, 1012) 'len.i988' (line 853) + [1024, 1032) 'val.i' (line 855) + [1056, 1064) 'reader.i891' (line 1600) + [1088, 1092) 'type.i892' (line 1601) + [1104, 1232) 'buf.i' (line 1602) + [1264, 1266) 'b.i' (line 1603) + [1280, 1284) 'c.i' (line 1605) + [1296, 1304) 'reader.i812' (line 1564) + [1328, 1336) 'value.i813' (line 1565) + [1360, 1364) 'type.i814' (line 1566) + [1376, 1384) 'reader.i795' (line 1254) + [1408, 1416) 'reader.i668' (line 1763) + [1440, 1444) 'type.i669' (line 1771) + [1456, 1464) 'str.i670' (line 1787) + [1488, 1492) 'len.i671' (line 1788) + [1504, 1512) 'reader.i564' (line 1835) + [1536, 1540) 'type.i565' (line 1836) + [1552, 1560) 'reader.i469' (line 1417) + [1584, 1588) 'type.i470' (line 1418) + [1600, 1604) 'depth.i' (line 1420) + [1616, 1624) 'str.i471' (line 1439) + [1648, 1652) 'len.i472' (line 1440) + [1664, 1668) 'count.i473' (line 1464) + [1680, 1688) 'prefix.i' (line 1476) + [1712, 1720) 'local.i' (line 1485) + [1744, 1752) 'qname.i' (line 1485) + [1776, 1784) 'value.i474' (line 1518) + [1808, 1816) 'reader.i350' (line 1278) + [1840, 1848) 'str.i351' (line 1279) + [1872, 1876) 'type.i352' (line 1280) + [1888, 1892) 'len.i353' (line 1281) + [1904, 1908) 'count.i354' (line 1281) + [1920, 1928) 'reader.i302' (line 1340) + [1952, 1960) 'str.i303' (line 1341) + [1984, 1988) 'type.i304' (line 1342) + [2000, 2004) 'len.i305' (line 1343) + [2016, 2020) 'count.i' (line 1343) + [2032, 2040) 'reader.i232' (line 1159) + [2064, 2068) 'type.i233' (line 1167) + [2080, 2088) 'str.i234' (line 1179) + [2112, 2116) 'len.i235' (line 1180) + [2128, 2136) 'reader.i146' (line 1077) + [2160, 2164) 'type.i147' (line 1078) + [2176, 2184) 'value.i148' (line 1088) + [2208, 2216) 'str.i149' (line 1113) + [2240, 2248) 'reader.i100' (line 1689) + [2272, 2276) 'type.i101' (line 1697) + [2288, 2296) 'str.i102' (line 1717) + [2320, 2324) 'len.i103' (line 1718) + [2336, 2344) 'reader.i70' (line 1906) + [2368, 2372) 'type.i' (line 1914) + [2384, 2392) 'str.i' (line 1926) + [2416, 2420) 'len.i' (line 1927) + [2432, 2436) 'nodetype.i49' (line 780) + [2448, 2456) 'reader.i50' (line 781) + [2480, 2488) 'reader_input.i' (line 616) + [2512, 2520) 'reader.i1' (line 617) + [2544, 2552) 'reader2.i' (line 617) + [2576, 2584) 'obj.i' (line 618) + [2608, 2616) 'stream.i' (line 619) + [2640, 2648) 'stream2.i' (line 619) + [2672, 2676) 'nodetype.i2' (line 620) + [2688, 2696) 'resolver.i' (line 515) + [2720, 2728) 'unk.i' (line 516) + [2752, 2760) 'reader.i' (line 517) + [2784, 2788) 'dtd.i' (line 518) <== Memory access at offset 2784 partially overflows this variable + [2800, 2804) 'nodetype.i' (line 519) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow /home/bernhard/data/entwicklung/2024/wine\wine/dlls/xmllite/reader.c:2807:20 in xmlreader_GetProperty +Shadow bytes around the buggy address: + 0x7ffffe1ff600: f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 + 0x7ffffe1ff680: f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1ff700: f8 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f8 f2 f8 f2 + 0x7ffffe1ff780: f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 + 0x7ffffe1ff800: f2 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f2 00 f2 f2 f2 +=>0x7ffffe1ff880: 00 f2 f2 f2 00 f2 f2 f2[04]f2 04 f3 00 00 00 00 + 0x7ffffe1ff900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ff980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ffb00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==1696==ABORTING +06ac:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:471569: dlls/xmllite/tests/x86_64-windows/reader.ok] Fehler 1 +--- + dlls/xmllite/reader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c +index 1e146493aa6..583a0fa600c 100644 +--- a/dlls/xmllite/reader.c ++++ b/dlls/xmllite/reader.c +@@ -2804,7 +2804,7 @@ static HRESULT WINAPI xmlreader_GetProperty(IXmlReader* iface, UINT property, LO + IXmlResolver_AddRef(This->resolver); + break; + case XmlReaderProperty_DtdProcessing: +- *value = This->dtdmode; ++ *(DtdProcessing*)value = This->dtdmode; + break; + case XmlReaderProperty_ReadState: + *value = This->state; +-- +2.47.1 + diff --git a/0015-bernhard-asan/0085-ntdll-Avoid-merging-of-memcpy-and-memmove.patch b/0015-bernhard-asan/0085-ntdll-Avoid-merging-of-memcpy-and-memmove.patch new file mode 100644 index 0000000..dc13543 --- /dev/null +++ b/0015-bernhard-asan/0085-ntdll-Avoid-merging-of-memcpy-and-memmove.patch @@ -0,0 +1,92 @@ +From 5e10edc1cdc88caabccfb6076e02e3c0ad5d2402 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Tue, 17 Dec 2024 23:25:29 +0100 +Subject: [PATCH 85/86] ntdll: Avoid merging of memcpy and memmove. + +They are identical in Wine, maybe therefore the compiler merges +them into a single _memcpy, so both can handle overlapping areas. + +But ASan does not know Wine's memcpy can handle it +and therefore triggers the error. + + +================================================================= +==640==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x00857b20,0x00857b2e) and [0x00857b21, 0x00857b2f) overlap +02e4:fixme:msvcrt:_set_abort_behavior _WRITE_CALL_REPORTFAULT unhandled +02e4:fixme:file:server_get_file_info Unsupported info class e + #0 0x76e323d1 in memcpy /home/bernhard/data/entwicklung/2024/llvm-mingw/2024-10-18/llvm-mingw/llvm-project/compiler-rt\lib/asan/../sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc:115:5 + #1 0x7891968e in RtlMoveMemory /usr/src/packages/BUILD\dlls/ntdll\string.c:265:13 + #2 0x00655e6e in test_RtlMoveMemory /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/rtl.c:302:22 + #3 0x00655e6e in func_rtl /home/bernhard/data/entwicklung/2024/wine\wine/dlls/ntdll/tests/rtl.c:4077:5 + #4 0x00776711 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #5 0x00776711 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #6 0x0077868b in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #7 0x7877ea3f in BaseThreadInitThunk (C:\windows\system32\kernel32.dll+0x7b80ea3f) + #8 0x788fce82 in call_thread_func_wrapper (C:\windows\system32\ntdll.dll+0x7bc0ce82) + #9 0x789304b4 in call_thread_func /usr/src/packages/BUILD\dlls/ntdll\signal_i386.c:524:9 + +Address 0x00857b20 is a wild pointer inside of access range of size 0x0000000e. +Address 0x00857b21 is a wild pointer inside of access range of size 0x0000000e. +SUMMARY: AddressSanitizer: memcpy-param-overlap /usr/src/packages/BUILD\dlls/ntdll\string.c:265:13 in RtlMoveMemory +==640==ABORTING +make: *** [Makefile:305163: dlls/ntdll/tests/i386-windows/rtl.ok] Fehler 1 + + + +$ i686-w64-mingw32-objdump --disassemble build-32/obj/dlls/ntdll/i386-windows/ntdll.dll | grep -E "RtlMoveMemory|RtlCopyMemory" -A13 +7bc19500 <_RtlCopyMemory@12>: +7bc19500: 55 push %ebp +7bc19501: 89 e5 mov %esp,%ebp +7bc19503: 83 ec 0c sub $0xc,%esp +7bc19506: 8b 45 10 mov 0x10(%ebp),%eax +7bc19509: 89 44 24 08 mov %eax,0x8(%esp) +7bc1950d: 8b 45 0c mov 0xc(%ebp),%eax +7bc19510: 89 44 24 04 mov %eax,0x4(%esp) +7bc19514: 8b 45 08 mov 0x8(%ebp),%eax +7bc19517: 89 04 24 mov %eax,(%esp) +7bc1951a: e8 11 71 03 00 call 7bc50630 <_memcpy> +7bc1951f: c9 leave +7bc19520: c2 0c 00 ret $0xc +7bc19523: 90 nop +-- +7bc29670 <_RtlMoveMemory@12>: +7bc29670: 55 push %ebp +7bc29671: 89 e5 mov %esp,%ebp +7bc29673: 83 ec 0c sub $0xc,%esp +7bc29676: 8b 45 10 mov 0x10(%ebp),%eax +7bc29679: 89 44 24 08 mov %eax,0x8(%esp) +7bc2967d: 8b 45 0c mov 0xc(%ebp),%eax +7bc29680: 89 44 24 04 mov %eax,0x4(%esp) +7bc29684: 8b 45 08 mov 0x8(%ebp),%eax +7bc29687: 89 04 24 mov %eax,(%esp) +7bc2968a: e8 a1 6f 02 00 call 7bc50630 <_memcpy> +7bc2968f: c9 leave +7bc29690: c2 0c 00 ret $0xc +7bc29693: 90 nop + + + +$ i686-w64-mingw32-gcc --version +i686-w64-mingw32-gcc (GCC) 12-win32 +--- + dlls/ntdll/string.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c +index 46fb80a3a69..5881c047c32 100644 +--- a/dlls/ntdll/string.c ++++ b/dlls/ntdll/string.c +@@ -125,8 +125,9 @@ void * __cdecl memcpy( void *dst, const void *src, size_t n ) + */ + void * __cdecl memmove( void *dst, const void *src, size_t n ) + { +- volatile unsigned char *d = dst; /* avoid gcc optimizations */ + const unsigned char *s = src; ++ volatile unsigned char *d = dst; /* avoid gcc optimizations */ ++ /* changed order to avoid merge with memcpy */ + + if ((size_t)dst - (size_t)src >= n) + { +-- +2.47.1 + diff --git a/0015-bernhard-asan/0086-kernel32-tests-Add-SleepEx-to-finish-overlapped-read.patch b/0015-bernhard-asan/0086-kernel32-tests-Add-SleepEx-to-finish-overlapped-read.patch new file mode 100644 index 0000000..53a8ee4 --- /dev/null +++ b/0015-bernhard-asan/0086-kernel32-tests-Add-SleepEx-to-finish-overlapped-read.patch @@ -0,0 +1,286 @@ +From b8b3286ec3c6e5ebb9117173c17ccbe4e2cd8958 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Mon, 9 Dec 2024 17:49:32 +0100 +Subject: [PATCH 86/86] kernel32/tests: Add SleepEx to finish overlapped read. + +================================================================= +==508==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffffe1ea7f8 at pc 0x0001401a4933 bp 0x7ffffe1e2a80 sp 0x7ffffe1e2ac8 +READ of size 8 at 0x7ffffe1ea7f8 thread T0 +0208:fixme:file:server_get_file_info Unsupported info class e + #0 0x0001401a4932 in FileIOComplete /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/file.c:3337:24 + #1 0x6ffffacef75f in KiUserApcDispatcher (C:\windows\system32\ntdll.dll+0x17000f75f) + #2 0x6ffffacedf53 in NtDelayExecution (C:\windows\system32\ntdll.dll+0x17000df53) + #3 0x6ffffa6eec5f in SleepEx /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernelbase\sync.c:346:14 + #4 0x00014015a0e3 in test_read_write /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/file.c:3451:5 + #5 0x00014015a0e3 in func_file /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/file.c:6348:5 + #6 0x0001404d7fa1 in run_test /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:765:5 + #7 0x0001404d7fa1 in main /home/bernhard/data/entwicklung/2024/wine\wine/include/wine/test.h:884:12 + #8 0x0001404d9f8f in mainCRTStartup /home/bernhard/data/entwicklung/2024/wine\wine/dlls/msvcrt/crt_main.c:58:11 + #9 0x6ffffbfd4808 in BaseThreadInitThunk /home/bernhard/data/entwicklung/2024/wine/wine/dlls/kernel32\thread.c:61:5 + #10 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a) + +Address 0x7ffffe1ea7f8 is located in stack of thread T0 at offset 30232 in frame + #0 0x00014013223f in func_file /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/file.c:6296 + + This frame has 205 object(s): + [32, 292) 'cwd.i6426' (line 6001) + [368, 628) 'temp_dir.i6427' (line 6001) + [704, 964) 'cwd.i' (line 5922) + [1040, 1300) 'temp_dir.i' (line 5922) + [1376, 1576) 'name_buffer.i' (line 5922) + [1648, 1668) 'buffer.i6266' (line 5922) + [1712, 1728) 'io.i6267' (line 5924) + [1744, 1748) 'size.i6268' (line 5927) + [1760, 2020) 'path.i6021' (line 4751) + [2096, 2356) 'filename.i6022' (line 4751) + [2432, 2436) 'buffer.i6023' (line 4751) + [2448, 2452) 'size.i6024' (line 4754) + [2464, 2984) 'path.i5885' (line 5880) + [3120, 3640) 'temp_path.i5886' (line 5880) + [3776, 3784) 'ft1.i5887' (line 5881) + [3808, 3816) 'ft2.i5888' (line 5881) + [3840, 3844) 'len.i5889' (line 5882) + [3856, 3878) 'path.i5864' (line 5859) + [3920, 4520) 'data.i5865' (line 5862) + [4656, 4916) 'file_name.i5674' (line 5792) + [4992, 5252) 'file_name2.i' (line 5792) + [5328, 5588) 'temp_path.i5675' (line 5793) + [5664, 5924) 'temp_path.i5568' (line 5730) + [6000, 6260) 'file_name.i5569' (line 5731) + [6336, 6340) 'bytes_count.i' (line 5732) + [6352, 6384) 'ov.i5570' (line 5733) + [6416, 6448) 'ovl.i5347' (line 5618) + [6480, 6512) 'ovl2.i' (line 5618) + [6544, 6552) 'povl.i5348' (line 5618) + [6576, 6640) 'entries.i' (line 5619) + [6672, 6680) 'key.i5349' (line 5620) + [6704, 6708) 'count.i5350' (line 5622) + [6720, 6724) 'size.i5351' (line 5623) + [6736, 6772) 'info.i' (line 5597) + [6816, 7336) 'tempFileFrom.i' (line 5518) + [7472, 7992) 'tempFileTo1.i' (line 5518) + [8128, 8648) 'tempFileTo2.i' (line 5518) + [8784, 9304) 'tempPath.i5155' (line 5519) + [9440, 9448) 'fileattrinfo.i' (line 5401) + [9472, 9588) 'protinfo.i' (line 5402) + [9632, 9656) 'stdinfo.i' (line 5403) + [9696, 9712) 'compressinfo.i' (line 5404) + [9728, 9729) 'dispinfo.i4919' (line 5405) + [9744, 9748) 'hintinfo.i' (line 5406) + [9760, 9800) 'basicinfo.i' (line 5407) + [9840, 10100) 'tempFileName.i4920' (line 5408) + [10176, 10436) 'tempPath.i4921' (line 5409) + [10512, 11032) 'temp_path.i4625' (line 5281) + [11168, 11688) 'test_path.i4626' (line 5281) + [11824, 12344) 'long_path.i4627' (line 5282) + [12480, 13000) 'result_path.i4628' (line 5282) + [13136, 13676) 'dos_path.i4629' (line 5283) + [13808, 14328) 'drive_part.i' (line 5284) + [14464, 15084) 'volume_path.i' (line 5286) + [15216, 16256) 'nt_path.i' (line 5287) + [16384, 16644) 'temp_path.i4444' (line 5193) + [16720, 16980) 'test_path.i' (line 5193) + [17056, 17316) 'long_path.i' (line 5194) + [17392, 17652) 'result_path.i' (line 5194) + [17728, 17993) 'dos_path.i' (line 5195) + [18064, 18324) 'path.i4319' (line 5101) + [18400, 18660) 'fname.i' (line 5101) + [18736, 18752) 'buf.i4320' (line 5102) + [18768, 18776) 'hdup.i' (line 5103) + [18800, 18804) 'bytes.i4321' (line 5104) + [18816, 19076) 'temp_path.i3961' (line 4846) + [19152, 19412) 'filename.i3962' (line 4846) + [19488, 19492) 'size.i' (line 4848) + [19504, 19508) 'tx.i' (line 4848) + [19520, 19528) 'key.i' (line 4849) + [19552, 19568) 'fse.i' (line 4850) + [19584, 19616) 'ovl.i3963' (line 4851) + [19648, 19656) 'povl.i' (line 4851) + [19680, 19728) 'si.i' (line 4852) + [19760, 19764) 'count.i3600' (line 4616) + [19776, 20036) 'path.i' (line 4617) + [20112, 20372) 'filename.i3601' (line 4617) + [20448, 20464) 'privs.i' (line 4618) + [20480, 20488) 'token.i' (line 4619) + [20512, 20772) 'tempPath.i3481' (line 4510) + [20848, 21108) 'tempFileName.i3482' (line 4510) + [21184, 21440) 'buffer.i3483' (line 4510) + [21504, 21760) 'tickCount.i' (line 4510) + [21824, 22344) 'tempFileNameW.i' (line 4511) + [22480, 22484) 'count.i3484' (line 4513) + [22496, 22520) 'fileIdDescr.i' (line 4516) + [22560, 22820) 'tempPath.i' (line 4345) + [22896, 23156) 'tempFileName.i' (line 4345) + [23232, 24256) 'buffer.i3172' (line 4345) + [24384, 24388) 'written.i3173' (line 4347) + [24400, 24404) 'priohintinfo.i' (line 4354) + [24416, 24424) 'allocinfo.i' (line 4355) + [24448, 24449) 'dispinfo.i' (line 4356) + [24464, 24472) 'eofinfo.i' (line 4357) + [24496, 24520) 'renameinfo.i' (line 4358) + [24560, 25080) 'replaced.i' (line 4126) + [25216, 25736) 'replacement.i' (line 4126) + [25872, 26392) 'backup.i' (line 4126) + [26528, 27048) 'temp_path.i3030' (line 4128) + [27184, 27193) 'directory.i' (line 3811) + [27216, 27248) 'ov.i2847' (line 3733) + [27280, 27284) 'result.i2848' (line 3734) + [27296, 27432) 'ofs.i' (line 3551) + [27504, 27764) 'buff.i' (line 3563) + [27840, 28880) 'buff_long.i' (line 3564) + [29008, 29136) 'filled_0xA5.i' (line 3565) + [29168, 29172) 'bytes.i' (line 3392) + [29184, 29188) 'old_prot.i' (line 3392) + [29200, 29460) 'temp_path.i2303' (line 3394) + [29536, 29796) 'filename.i2304' (line 3395) + [29872, 30132) 'szFile.i' (line 3343) + [30208, 30240) 'ovl.i' (line 3347) <== Memory access at offset 30232 is inside this variable + [30272, 30276) 'count.i' (line 3364) + [30288, 30296) 'h.i' (line 3246) + [30320, 30328) 'h2.i' (line 3246) + [30352, 30384) 'ov.i' (line 2212) + [30416, 30420) 'done.i' (line 2213) + [30432, 30688) 'buf.i1791' (line 2215) + [30752, 30757) 'pattern.i' (line 2215) + [30784, 31044) 'temp_path.i1792' (line 2217) + [31120, 31380) 'temp_fname.i' (line 2217) + [31456, 31460) 'written.i1596' (line 2285) + [31472, 31504) 'overlapped.i' (line 2286) + [31536, 31856) 'find_data.i1553' (line 3034) + [31920, 32432) 'correct.i' (line 3145) + [32496, 33008) 'incorrect.i' (line 3146) + [33072, 33584) 'missing.i' (line 3147) + [33648, 33664) 'quoted.i' (line 3157) + [33680, 33940) 'windowsdir.i.i1529' (line 2705) + [34016, 34336) 'search_results.i1530' (line 2913) + [34400, 34405) 'buffer.i1531' (line 2915) + [34432, 34692) 'windowsdir.i.i' (line 2705) + [34768, 35088) 'data.i' (line 2713) + [35152, 35157) 'buffer.i1404' (line 2715) + [35184, 35284) 'buffer2.i' (line 2716) + [35328, 35588) 'nonexistent.i' (line 2717) + [35664, 35924) 'tmp.i' (line 2779) + [36000, 36520) 'temp_path.i1307' (line 2177) + [36656, 37176) 'source.i1308' (line 2178) + [37312, 37832) 'dest.i1309' (line 2178) + [37968, 38228) 'tempdir.i' (line 1996) + [38304, 38564) 'source.i1162' (line 1997) + [38640, 38900) 'dest.i1163' (line 1997) + [38976, 39296) 'find_data.i' (line 1999) + [39360, 39364) 'ret.i' (line 2002) + [39376, 39696) 'fd.i' (line 2146) + [39760, 40020) 'temppath.i' (line 2147) + [40096, 40616) 'pathW.i' (line 1943) + [40752, 41272) 'pathsubW.i' (line 1944) + [41408, 41668) 'temp_path.i945' (line 1867) + [41744, 42004) 'temp_file.i' (line 1867) + [42080, 42088) 'argv.i' (line 1869) + [42112, 42632) 'temp_path.i875' (line 1717) + [42768, 43288) 'filename.i876' (line 1718) + [43424, 43456) 'exparams.i' (line 1719) + [43488, 44008) 'temp_path.i812' (line 1628) + [44144, 44664) 'filename.i813' (line 1629) + [44800, 45060) 'temp_path.i609' (line 1271) + [45136, 45396) 'dirname.i' (line 1271) + [45472, 45732) 'filename.i' (line 1272) + [45808, 46068) 'windowsdir.i610' (line 1274) + [46144, 46404) 'Volume_1.i' (line 1275) + [46480, 46992) 'buffer.i611' (line 1276) + [47056, 47060) 'len.i612' (line 1279) + [47072, 47124) 'Finfo.i' (line 1297) + [47168, 47688) 'curdir.i' (line 1298) + [47824, 48084) 'temp_path.i556' (line 4244) + [48160, 48420) 'file_name.i' (line 4245) + [48496, 48500) 'written.i' (line 4246) + [48512, 48772) 'temp_path.i480' (line 1193) + [48848, 49108) 'source.i481' (line 1194) + [49184, 49444) 'dest.i482' (line 1194) + [49520, 50040) 'source.i416' (line 957) + [50176, 50696) 'dest.i417' (line 957) + [50832, 51352) 'temp_path.i418' (line 957) + [51488, 51520) 'params.i' (line 958) + [51552, 51560) 'ft1.i' (line 960) + [51584, 51592) 'ft2.i' (line 960) + [51616, 51620) 'len.i' (line 961) + [51632, 51642) 'buf.i' (line 962) + [51664, 52184) 'temp_path.i' (line 911) + [52320, 52840) 'source.i' (line 912) + [52976, 53496) 'dest.i' (line 912) + [53632, 53892) 'out.i' (line 1830) + [53968, 54238) 'expected.i' (line 1831) + [54304, 54574) 'windowsdir.i' (line 1832) + [54640, 54643) 'windowsdrive.i' (line 1833) + [54656, 64656) 'buffer.i289' (line 596) + [64912, 64913) 'checksum.i290' (line 603) + [64928, 74928) 'buffer.i245' (line 551) + [75184, 85184) 'buffer.i212' (line 512) + [85440, 85441) 'buffer.i141' (line 474) + [85456, 85472) 'strW.i.i' (line 277) + [85488, 85504) 'str.i.i' (line 278) + [85520, 85536) 'filenameW.i' (line 295) + [85552, 85600) 'attr.i' (line 296) + [85632, 85648) 'io.i' (line 297) + [85664, 95664) 'buffer.i103' (line 299) + [95920, 96240) 'search_results.i' (line 300) + [96304, 96312) 'slashname.i' (line 301) + [96336, 96344) 'file.i' (line 303) + [96368, 106368) 'buffer.i55' (line 170) + [106624, 106625) 'checksum.i' (line 177) + [106640, 116640) 'buffer.i' (line 123) + [116896, 117156) 'temp_path' (line 6297) +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp, SEH and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-use-after-scope /home/bernhard/data/entwicklung/2024/wine\wine/dlls/kernel32/tests/file.c:3337:24 in FileIOComplete +Shadow bytes around the buggy address: + 0x7ffffe1ea500: f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 + 0x7ffffe1ea580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x7ffffe1ea600: 00 00 00 00 00 00 00 00 04 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1ea680: f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ea700: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +=>0x7ffffe1ea780: f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8[f8] + 0x7ffffe1ea800: f2 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f8 + 0x7ffffe1ea880: f8 f8 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ea900: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + 0x7ffffe1ea980: f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 + 0x7ffffe1eaa00: f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==508==ABORTING +0208:fixme:kernelbase:AppPolicyGetProcessTerminationMethod FFFFFFFFFFFFFFFA, 00007FFFFEA8FE80 +make: *** [Makefile:201808: dlls/kernel32/tests/x86_64-windows/file.ok] Fehler 1 +--- + dlls/kernel32/tests/file.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index c57edebb316..33357e27356 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -3378,6 +3378,7 @@ static void test_async_file_errors(void) + } + ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count); + /*printf("Error = %ld\n", GetLastError());*/ ++ SleepEx(0, TRUE); /* Without it ASan would trigger a stack-use-after-scope in SleepEx in test_read_write later. */ + HeapFree(GetProcessHeap(), 0, lpBuffer); + } + +-- +2.47.1 + diff --git a/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch b/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch new file mode 100644 index 0000000..578867c --- /dev/null +++ b/9000-misc-additions/Revert-ntdll-Report-the-space-completely-outside-of-.patch @@ -0,0 +1,61 @@ +From b962e1fd1f8a4eb3a599940b3ae50034fcf31953 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Tue, 10 Dec 2024 01:12:10 -0800 +Subject: [PATCH] Revert "ntdll: Report the space completely outside of + reserved areas as allocated on i386." + +This reverts commit 233f6f288c8a6aa5aae127660ab00f392fe2cf67. + +The commit breaks osu! when WINE_BLOCK_GET_VERSION=0, because it fixes the bug +that the game tries to work around when it knows it's running under wine. +--- + dlls/ntdll/unix/virtual.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index 7330519bbb5..e2c3eb7c339 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -5603,7 +5603,6 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + * so that the app doesn't believe it's fully available */ + { + struct reserved_area *area; +- BOOL in_reserved = FALSE; + + LIST_FOR_EACH_ENTRY( area, &reserved_areas, struct reserved_area, entry ) + { +@@ -5618,7 +5617,6 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + if (area_start <= base || area_start <= (char *)address_space_start) + { + if (area_end < alloc_end) info->RegionSize = area_end - base; +- in_reserved = TRUE; + break; + } + /* report the remaining part of the 64K after the view as free */ +@@ -5629,22 +5627,18 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR + if (base < next) + { + info->RegionSize = min( next, alloc_end ) - base; +- in_reserved = TRUE; + break; + } + else alloc_base = base; + } + /* pretend it's allocated */ + if (area_start < alloc_end) info->RegionSize = area_start - base; +- break; +- } +- if (!in_reserved) +- { + info->State = MEM_RESERVE; + info->Protect = PAGE_NOACCESS; + info->AllocationBase = alloc_base; + info->AllocationProtect = PAGE_NOACCESS; + info->Type = MEM_PRIVATE; ++ break; + } + } + #endif +-- +2.47.1 + diff --git a/9000-misc-additions/always-dynamic-spin.patch b/9000-misc-additions/always-dynamic-spin.patch deleted file mode 100644 index 0006c1e..0000000 --- a/9000-misc-additions/always-dynamic-spin.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 7847d37ffbf..8d97c8593dd 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -227,9 +227,7 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION * - */ - NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULONG spincount, ULONG flags ) - { -- if (NtCurrentTeb()->Peb->OSMajorVersion > 6 || -- (NtCurrentTeb()->Peb->OSMajorVersion == 6 && NtCurrentTeb()->Peb->OSMinorVersion >= 2)) -- flags |= RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN; -+ flags |= RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN; - - if (flags & RTL_CRITICAL_SECTION_FLAG_STATIC_INIT) - FIXME("(%p,%lu,0x%08lx) semi-stub\n", crit, spincount, flags); diff --git a/9500-testing/0001-ntdll-TEST-try-NtFPWB-in-contended-NtWaitForAlertByT.patch b/9500-testing/0001-ntdll-TEST-try-NtFPWB-in-contended-NtWaitForAlertByT.patch new file mode 100644 index 0000000..e3d13f0 --- /dev/null +++ b/9500-testing/0001-ntdll-TEST-try-NtFPWB-in-contended-NtWaitForAlertByT.patch @@ -0,0 +1,33 @@ +From 8031239529c1e56c46184eb3a430b1c61cdee01a Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Sat, 21 Dec 2024 14:46:49 -0800 +Subject: [PATCH] ntdll: TEST: try NtFPWB in contended + NtWaitForAlertByThreadId + +--- + dlls/ntdll/unix/sync.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c +index 67e13bfa6fc..e0962e5af69 100644 +--- a/dlls/ntdll/unix/sync.c ++++ b/dlls/ntdll/unix/sync.c +@@ -3104,6 +3104,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG + end = get_absolute_timeout( timeout ); + } + ++ NtFlushProcessWriteBuffers(); + while (!InterlockedExchange( futex, 0 )) + { + if (timeout) +@@ -3119,6 +3120,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG + ret = futex_wait( futex, 0, NULL ); + + if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT; ++ NtFlushProcessWriteBuffers(); + } + return STATUS_ALERTED; + } +-- +2.47.1 + diff --git a/staging-commit b/staging-commit index 0d63a1b..2b301f4 100644 --- a/staging-commit +++ b/staging-commit @@ -1 +1 @@ -c2de76b8048c67aa33c57cff60f98ba1b1675e72 \ No newline at end of file +f10d2d045221c84cb75e9a85919790c2437a647a \ No newline at end of file diff --git a/staging-exclude b/staging-exclude index f1155f4..9f7d086 100644 --- a/staging-exclude +++ b/staging-exclude @@ -1 +1 @@ --W eventfd_synchronization -W wined3d-unset-flip-gdi \ No newline at end of file +-W eventfd_synchronization \ No newline at end of file diff --git a/wine-commit b/wine-commit index d39c624..34992fd 100644 --- a/wine-commit +++ b/wine-commit @@ -1 +1 @@ -538cae099cde66706428ead4ae8951c1e389d3f2 \ No newline at end of file +e713c3487f9fc9b7ded528f9ce49844facb99a90 \ No newline at end of file