Similar to 4e4847dd71 which disabled writes to fs and gs register in "cleared segment registers" test: https://bugs.winehq.org/show_bug.cgi?id=51152
Followup to 03fe2b36cd.
The [test pattern page](https://test.winehq.org/data/patterns.html#ntdll:exception) shows several 64-bit linux machines suffering from this.
-- v2: ntdll/tests: Check if writing to fs and gs causes child processes to crash.
From: Bernhard Übelacker bernhardu@mailbox.org
Similar to 4e4847dd71 which disabled writes to fs and gs register in "cleared segment registers" test: https://bugs.winehq.org/show_bug.cgi?id=51152
Followup to 03fe2b36cd. --- dlls/ntdll/tests/exception.c | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 025923b7d8e..28f8f38f3e1 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -9453,11 +9453,55 @@ static void test_debuggee_segments(void) { void (CDECL *func)(void) = code_mem;
+ if (GetEnvironmentVariableA("AVOID_FS_GS_WRITE", NULL, 0)) + { + skip("Processes modifying fs/gs registers are crashing, skipping test.\n"); + return; + } + memcpy( code_mem, except_code_segments, sizeof(except_code_segments)); func(); } #endif
+#if defined(__x86_64__) +static void fs_gs_write(void) +{ + __asm__( + "mov %fs,%eax; " + "mov %eax,%fs; " + "mov %gs,%eax; " + "mov %eax,%gs" + ); + trace("Wrote to fs and gs registers.\n"); +} + +static void fs_gs_write_check(void) +{ + char **argv; + char cmdline[MAX_PATH]; + STARTUPINFOA si = {.cb = sizeof(si)}; + PROCESS_INFORMATION pi; + DWORD ret; + + if (!winetest_platform_is_wine) + return; + + winetest_get_mainargs(&argv); + sprintf(cmdline, "%s exception fs_gs_write", argv[0]); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); + ok(ret, "Failed to create target process.\n"); + + WaitForSingleObject(pi.hProcess, 30000); + ok(GetExitCodeProcess(pi.hProcess, &ret), "GetExitCodeProcess failed.\n"); + if (ret) + SetEnvironmentVariableA("AVOID_FS_GS_WRITE", "1"); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} +#endif + static DWORD invalid_handle_exceptions;
static LONG CALLBACK invalid_handle_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) @@ -12081,6 +12125,14 @@ START_TEST(exception) return; }
+#if defined(__x86_64__) + if (my_argc >= 3 && !strcmp(my_argv[2], "fs_gs_write")) + { + fs_gs_write(); + return; + } +#endif + code_mem = VirtualAlloc(NULL, 65536, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!code_mem) { trace("VirtualAlloc failed\n"); @@ -12333,6 +12385,9 @@ START_TEST(exception) test_KiUserApcDispatcher(); test_KiUserCallbackDispatcher(); test_rtlraiseexception(); +#if defined(__x86_64__) + fs_gs_write_check(); +#endif test_debugger(DBG_EXCEPTION_HANDLED, FALSE); test_debugger(DBG_CONTINUE, FALSE); test_debugger(DBG_EXCEPTION_HANDLED, TRUE);
v2: - Use this only at x86_64.