[PATCH v3 0/1] MR8987: ntdll/tests: Add some tests for NtSetLdtEntries.
-- v3: ntdll/tests: Add some tests for NtSetLdtEntries. https://gitlab.winehq.org/wine/wine/-/merge_requests/8987
From: Dmitry Timoshkov <dmitry(a)baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru> --- dlls/ntdll/tests/wow64.c | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 544290c3273..6555d2742dc 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -42,6 +42,7 @@ static NTSTATUS (WINAPI *pRtlWow64GetSharedInfoProcess)(HANDLE,BOOLEAN*,WOW64INF static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE,WOW64_CONTEXT*); static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*); static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE,HANDLE,PVOID*,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG); +static NTSTATUS (WINAPI *pNtSetLdtEntries)(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG); #ifdef _WIN64 static NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*); static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*); @@ -117,6 +118,7 @@ static void init(void) #define GET_PROC(func) p##func = (void *)GetProcAddress( ntdll, #func ) GET_PROC( NtMapViewOfSectionEx ); + GET_PROC( NtSetLdtEntries ); GET_PROC( NtQuerySystemInformation ); GET_PROC( NtQuerySystemInformationEx ); GET_PROC( RtlGetNativeSystemInformation ); @@ -3181,6 +3183,78 @@ static void test_arm64ec(void) #endif } +static void test_NtSetLdtEntries(void) +{ + THREAD_DESCRIPTOR_INFORMATION tdi; + LDT_ENTRY ds_entry; + CONTEXT ctx; + DWORD ret; + union + { + LDT_ENTRY entry; + DWORD dw[2]; + } sel; + + if (!pNtSetLdtEntries) + { + win_skip("NtSetLdtEntries is not available on this platform\n"); + return; + } + + if (pNtSetLdtEntries(0, 0, 0, 0, 0, 0) == STATUS_NOT_IMPLEMENTED) /* WoW64 */ + { + skip("NtSetLdtEntries is not implemented on this platform\n"); + return; + } + + ret = pNtSetLdtEntries(0, 0, 0, 0, 0, 0); + ok(!ret, "NtSetLdtEntries failed: %08lx\n", ret); + + ctx.ContextFlags = CONTEXT_SEGMENTS; + ret = GetThreadContext(GetCurrentThread(), &ctx); + ok(ret, "GetThreadContext failed\n"); + + tdi.Selector = ctx.SegDs; + ret = NtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret); + ok(!ret, "NtQueryInformationThread failed: %08lx\n", ret); + ds_entry = tdi.Entry; + + tdi.Selector = 0x000f; + ret = NtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret); + ok(ret == STATUS_UNSUCCESSFUL, "got %08lx\n", ret); + + tdi.Selector = 0x001f; + ret = NtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret); + ok(ret == STATUS_UNSUCCESSFUL, "NtQueryInformationThread returned %08lx\n", ret); + + ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry); + ok(!ret, "GetThreadSelectorEntry should fail\n"); + + ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry); + ok(!ret, "GetThreadSelectorEntry should fail\n"); + + memset(&sel.entry, 0x9a, sizeof(sel.entry)); + ret = GetThreadSelectorEntry(GetCurrentThread(), ctx.SegDs, &sel.entry); + ok(ret, "GetThreadSelectorEntry failed\n"); + ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n"); + + ret = pNtSetLdtEntries(0x000f, sel.dw[0], sel.dw[1], 0x001f, sel.dw[0], sel.dw[1]); + ok(!ret || broken(ret == STATUS_INVALID_LDT_DESCRIPTOR) /*XP*/, "NtSetLdtEntries failed: %08lx\n", ret); + + if (!ret) + { + memset(&sel.entry, 0x9a, sizeof(sel.entry)); + ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry); + ok(ret, "GetThreadSelectorEntry failed\n"); + ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n"); + + memset(&sel.entry, 0x9a, sizeof(sel.entry)); + ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry); + ok(ret, "GetThreadSelectorEntry failed\n"); + ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n"); + } +} + START_TEST(wow64) { init(); @@ -3202,4 +3276,5 @@ START_TEST(wow64) test_cpu_area(); test_exception_dispatcher(); test_arm64ec(); + test_NtSetLdtEntries(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8987
v3: Move tests to dlls/ntdll/tests/wow64.c. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8987#note_116111
The tests for invalid selectors are part of the test to make sure that the modified LDT entries didn't exist before initializing them.
I'm not sure how useful that is, but if you need it you should add it in the existing checks, there's no need to duplicate them. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8987#note_116112
participants (3)
-
Alexandre Julliard (@julliard) -
Dmitry Timoshkov -
Dmitry Timoshkov (@dmitry)