From 13b77a54bad4d9b390d2e31f70d8f130eab48635 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 28 Apr 2016 17:01:16 +0200 Subject: [PATCH] libs/wine: Allow to modify reserved LDT entries. Some implementation notes: 1. Some copy protections call NtSetLdtEntries(0x000f) and then with 'retf' instruction jump to that selector expecting that it works (the tests show that NtSetLdtEntries(0x000f,0x001f) should succeed). In order to make this work a limitation to set only selectors > LDT_FIRST_ENTRY (512) in wine_ldt_set_entry() was removed. 2. wine_ldt_set_entry() was made to always mark modified selector entries as WINE_LDT_FLAGS_ALLOCATED, otherwise get_selector_entry() server call returns entries without that flag set and NtQueryInformationThread(ThreadDescriptorTableEntry) fails. --- dlls/kernel32/tests/thread.c | 4 ---- dlls/ntdll/unix/signal_i386.c | 2 -- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index a76d74cb698..881db6d6513 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -1341,16 +1341,12 @@ static void test_NtSetLdtEntries(void) { memset(&sel.entry, 0x9a, sizeof(sel.entry)); ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry); - todo_wine ok(ret, "GetThreadSelectorEntry failed\n"); - todo_wine 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); - todo_wine ok(ret, "GetThreadSelectorEntry failed\n"); - todo_wine ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n"); } } diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 30f1aee4d62..0ab09c1b4df 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2098,8 +2098,6 @@ NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_E sigset_t sigset; if (sel1 >> 16 || sel2 >> 16) return STATUS_INVALID_LDT_DESCRIPTOR; - if (sel1 && (sel1 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR; - if (sel2 && (sel2 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR; server_enter_uninterrupted_section( &ldt_mutex, &sigset ); if (sel1) ldt_set_entry( sel1, entry1 ); -- 2.27.0