Module: wine Branch: master Commit: 53b305c35e6cfb489e2e9f4996d36ae82cac5e6c URL: https://source.winehq.org/git/wine.git/?a=commit;h=53b305c35e6cfb489e2e9f499...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Apr 29 19:53:57 2020 +0200
ntdll: Use server_enter_uninterrupted_section() for LDT locking.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/signal_i386.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 4743f095f0..2f2a36a579 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2328,30 +2328,9 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = 0, 0, { (DWORD_PTR)(__FILE__ ": ldt_section") } }; static RTL_CRITICAL_SECTION ldt_section = { &critsect_debug, -1, 0, 0, 0, 0 }; -static sigset_t ldt_sigset;
static const LDT_ENTRY null_entry;
-static void ldt_lock(void) -{ - sigset_t sigset; - - pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset ); - RtlEnterCriticalSection( &ldt_section ); - if (ldt_section.RecursionCount == 1) ldt_sigset = sigset; -} - -static void ldt_unlock(void) -{ - if (ldt_section.RecursionCount == 1) - { - sigset_t sigset = ldt_sigset; - RtlLeaveCriticalSection( &ldt_section ); - pthread_sigmask( SIG_SETMASK, &sigset, NULL ); - } - else RtlLeaveCriticalSection( &ldt_section ); -} - static inline void *ldt_get_base( LDT_ENTRY ent ) { return (void *)(ent.BaseLow | @@ -2510,14 +2489,16 @@ NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_ */ NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 ) { + 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;
- ldt_lock(); + server_enter_uninterrupted_section( &ldt_section, &sigset ); if (sel1) ldt_set_entry( sel1, entry1 ); if (sel2) ldt_set_entry( sel2, entry2 ); - ldt_unlock(); + server_leave_uninterrupted_section( &ldt_section, &sigset ); return STATUS_SUCCESS; }
@@ -2555,6 +2536,7 @@ NTSTATUS signal_alloc_thread( TEB *teb ) if (!gdt_fs_sel) { static int first_thread = 1; + sigset_t sigset; int idx; LDT_ENTRY entry = ldt_make_entry( teb, teb_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
@@ -2568,14 +2550,14 @@ NTSTATUS signal_alloc_thread( TEB *teb ) } else { - ldt_lock(); + server_enter_uninterrupted_section( &ldt_section, &sigset ); for (idx = first_ldt_entry; idx < LDT_SIZE; idx++) { if (__wine_ldt_copy.flags[idx]) continue; ldt_set_entry( (idx << 3) | 7, entry ); break; } - ldt_unlock(); + server_leave_uninterrupted_section( &ldt_section, &sigset ); if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS; } thread_data->fs = (idx << 3) | 7; @@ -2592,12 +2574,13 @@ NTSTATUS signal_alloc_thread( TEB *teb ) void signal_free_thread( TEB *teb ) { struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2; + sigset_t sigset;
if (gdt_fs_sel) return;
- ldt_lock(); + server_enter_uninterrupted_section( &ldt_section, &sigset ); __wine_ldt_copy.flags[thread_data->fs >> 3] = 0; - ldt_unlock(); + server_leave_uninterrupted_section( &ldt_section, &sigset ); }