2020-04-29 15:28:10 -07:00
|
|
|
From 09846b453dae490f5496a6ca2ac110b712542357 Mon Sep 17 00:00:00 2001
|
2016-04-28 08:13:03 -07:00
|
|
|
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
|
|
|
Date: Thu, 28 Apr 2016 17:01:16 +0200
|
2020-04-01 16:08:55 -07:00
|
|
|
Subject: [PATCH] libs/wine: Allow to modify reserved LDT entries.
|
2016-04-28 08:13:03 -07:00
|
|
|
|
|
|
|
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 ----
|
2020-04-01 16:08:55 -07:00
|
|
|
dlls/ntdll/signal_i386.c | 2 --
|
2016-04-28 08:13:03 -07:00
|
|
|
libs/wine/ldt.c | 4 +---
|
2020-04-01 16:08:55 -07:00
|
|
|
3 files changed, 1 insertion(+), 9 deletions(-)
|
2016-04-28 08:13:03 -07:00
|
|
|
|
|
|
|
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c
|
2020-04-29 07:16:09 -07:00
|
|
|
index ae67a9aa0a0..6149be8cf4a 100644
|
2016-04-28 08:13:03 -07:00
|
|
|
--- a/dlls/kernel32/tests/thread.c
|
|
|
|
+++ b/dlls/kernel32/tests/thread.c
|
2020-04-29 07:16:09 -07:00
|
|
|
@@ -1339,16 +1339,12 @@ static void test_NtSetLdtEntries(void)
|
2016-04-28 08:13:03 -07:00
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
2020-04-01 16:08:55 -07:00
|
|
|
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
2020-04-29 15:28:10 -07:00
|
|
|
index 98ce76c8e27..e31c3d6b0b8 100644
|
2020-04-01 16:08:55 -07:00
|
|
|
--- a/dlls/ntdll/signal_i386.c
|
|
|
|
+++ b/dlls/ntdll/signal_i386.c
|
2020-04-29 15:28:10 -07:00
|
|
|
@@ -2534,8 +2534,6 @@ NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_E
|
|
|
|
sigset_t sigset;
|
|
|
|
|
2020-04-01 16:08:55 -07:00
|
|
|
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;
|
|
|
|
|
2020-04-29 15:28:10 -07:00
|
|
|
server_enter_uninterrupted_section( &ldt_section, &sigset );
|
2020-04-01 16:08:55 -07:00
|
|
|
if (sel1) ldt_set_entry( sel1, entry1 );
|
2016-04-28 08:13:03 -07:00
|
|
|
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
2020-04-29 07:16:09 -07:00
|
|
|
index 18b0b9be9bf..30d9b945f73 100644
|
2016-04-28 08:13:03 -07:00
|
|
|
--- a/libs/wine/ldt.c
|
|
|
|
+++ b/libs/wine/ldt.c
|
2020-04-29 07:16:09 -07:00
|
|
|
@@ -200,8 +200,6 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
|
2016-04-28 08:13:03 -07:00
|
|
|
{
|
|
|
|
int ret = 0, index = sel >> 3;
|
|
|
|
|
|
|
|
- if (index < LDT_FIRST_ENTRY) return 0; /* cannot modify reserved entries */
|
|
|
|
-
|
|
|
|
#ifdef linux
|
|
|
|
{
|
|
|
|
struct modify_ldt_s ldt_info;
|
2020-04-29 07:16:09 -07:00
|
|
|
@@ -253,7 +251,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
|
2020-04-03 14:55:44 -07:00
|
|
|
wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
|
|
|
|
wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
|
2016-04-28 08:13:03 -07:00
|
|
|
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
|
2020-04-03 14:55:44 -07:00
|
|
|
- (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED));
|
2016-04-28 08:13:03 -07:00
|
|
|
+ WINE_LDT_FLAGS_ALLOCATED);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
--
|
2020-04-29 07:16:09 -07:00
|
|
|
2.26.2
|
2016-04-28 08:13:03 -07:00
|
|
|
|