From: Jinoh Kang jinoh.kang.kr@gmail.com
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ntdll/tests/exception.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 820e435bc1b..ee486380b8d 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -10673,6 +10673,90 @@ static void test_copy_context(void) dst_xs->Mask == 4, sizeof(dst_xs->YmmContext)); } } + +static DWORD WINAPI signal_and_wait_proc( void *arg ) +{ + HANDLE *events = arg; + /* Atomically signal and wait to put thread in blocking state */ + return SignalObjectAndWait(events[0], events[1], INFINITE, FALSE); +} + +static void test_eflags_sanitization(void) +{ +#if defined(__x86_64__) + static const DWORD max_eflags = 0x00210fd5; + static const DWORD min_eflags = 0x00000200; +#elif defined(__i386__) + static const DWORD max_eflags = 0x003f0fd7; + static const DWORD min_eflags = 0x00000202; +#endif + HANDLE event_in, event_out; + HANDLE thread; + HANDLE thread_args[2]; + HANDLE waits[2]; + NTSTATUS status; + CONTEXT context; + DWORD result, old_eflags; + int i; + + event_in = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(event_in != NULL, "CreateEventW failed with %#lx\n", GetLastError()); + event_out = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(event_out != NULL, "CreateEventW failed with %#lx\n", GetLastError()); + + thread_args[0] = event_in; + thread_args[1] = event_out; + thread = CreateThread(NULL, 0, signal_and_wait_proc, thread_args, CREATE_SUSPENDED, NULL); + ok(thread != NULL, "CreateThread failed with %#lx.\n", GetLastError()); + + for (i = 0; ; i++) + { + context.ContextFlags = CONTEXT_CONTROL; + status = pNtGetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); + old_eflags = context.EFlags; + + context.EFlags = -1; + status = pNtSetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); + status = pNtGetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); + todo_wine + ok(context.EFlags == max_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags); + + context.EFlags = 0; + status = pNtSetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); + status = pNtGetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); + todo_wine + ok(context.EFlags == min_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags); + + context.EFlags = old_eflags; + status = pNtSetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); + + if (i == 1) break; + + ResumeThread(thread); + waits[0] = event_in; + waits[1] = thread; + result = WaitForMultipleObjects(2, waits, FALSE, INFINITE); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + } + + ok(SetEvent(event_out), "SetEvent failed: %#lx\n", GetLastError()); + + result = WaitForSingleObject(thread, INFINITE); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + + ok(GetExitCodeThread(thread, &result), "Failed to get thread exit code: %#lx\n", GetLastError()); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + + CloseHandle(thread); + CloseHandle(event_in); + CloseHandle(event_out); +} #endif
START_TEST(exception) @@ -10847,6 +10931,7 @@ START_TEST(exception) test_kiuserexceptiondispatcher(); test_extended_context(); test_copy_context(); + test_eflags_sanitization();
#elif defined(__x86_64__)
@@ -10891,6 +10976,7 @@ START_TEST(exception) test_copy_context(); test_unwind_from_apc(); test_syscall_clobbered_regs(); + test_eflags_sanitization();
#elif defined(__aarch64__)