[4/5] ntdll: prevent thread suspend inside critical sections
Thomas Kho
tkho at ucla.edu
Fri Aug 18 03:25:49 CDT 2006
[4/5] ntdll: prevent thread suspend inside critical sections
This patch causes SIGUSR1 to be blocked inside ntdll critical sections to
ensure integrity of critical sections if remote operations are to be executed
inside the suspend/SIGUSR1 handler.
Thomas Kho
Copyright 2006 Google (Thomas Kho)
License: LGPL
---
dlls/ntdll/critsection.c | 28 +++++++++++++++++++++
dlls/ntdll/loader.c | 55 +++++++++++++++++++++++++----------------
dlls/ntdll/ntdll_misc.h | 7 +++++
dlls/ntdll/server.c | 29 ++++++++++++++++++++++
dlls/ntdll/thread.c | 28 +++++++++++++++++----
dlls/ntdll/virtual.c | 61 +++++++++++++++++++++++++++-------------------
6 files changed, 155 insertions(+), 53 deletions(-)
diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index 581875f..6885141 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -37,6 +37,9 @@ #include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
WINE_DECLARE_DEBUG_CHANNEL(relay);
+extern void wine_unblock_unix_signals(sigset_t *old_set);
+extern void wine_block_unix_signals(sigset_t *old_set);
+
inline static LONG interlocked_inc( PLONG dest )
{
return interlocked_xchg_add( (int *)dest, 1 ) + 1;
@@ -580,3 +583,28 @@ NTSTATUS WINAPI RtlLeaveCriticalSection(
}
return STATUS_SUCCESS;
}
+
+
+/***********************************************************************
+ * NTDLL_EnterUninterruptedCriticalSection
+ *
+ * NOTE: These functions exist to ensure that threads are not suspended inside
+ * ntdll critical sections and that remote operations succeed.
+ */
+void NTDLL_EnterUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+ sigset_t *sigset )
+{
+ wine_block_suspend_signal(sigset);
+ RtlEnterCriticalSection(cs);
+}
+
+
+/***********************************************************************
+ * NTDLL_LeaveUninterruptedCriticalSection
+ */
+void NTDLL_LeaveUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+ sigset_t *sigset )
+{
+ RtlLeaveCriticalSection(cs);
+ wine_unblock_suspend_signal(sigset);
+}
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 184f64f..4e6640e 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -964,8 +964,9 @@ static void process_detach( BOOL bForceD
{
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
+ sigset_t sigset;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
if (bForceDetach) process_detaching = 1;
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
do
@@ -991,7 +992,7 @@ static void process_detach( BOOL bForceD
}
} while (entry != mark);
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
}
/*************************************************************************
@@ -1006,12 +1007,13 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
NTSTATUS status;
+ sigset_t sigset;
/* don't do any attach calls if process is exiting */
if (process_detaching) return STATUS_SUCCESS;
/* FIXME: there is still a race here */
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
@@ -1030,7 +1032,7 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID
}
done:
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
return status;
}
@@ -1042,8 +1044,9 @@ NTSTATUS WINAPI LdrDisableThreadCallouts
{
WINE_MODREF *wm;
NTSTATUS ret = STATUS_SUCCESS;
+ sigset_t sigset;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
wm = get_modref( hModule );
if (!wm || wm->ldr.TlsIndex != -1)
@@ -1051,7 +1054,7 @@ NTSTATUS WINAPI LdrDisableThreadCallouts
else
wm->ldr.Flags |= LDR_NO_DLL_CALLS;
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
return ret;
}
@@ -1124,6 +1127,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
UNICODE_STRING str;
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
+ sigset_t sigset;
if (x != 0 || y != 0)
FIXME("Unknown behavior, please report\n");
@@ -1138,7 +1142,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
name = &str;
}
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
if (cached_modref)
{
@@ -1166,7 +1170,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
}
}
done:
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
TRACE("%lx %lx %s -> %p\n", x, y, debugstr_us(name), status ? NULL : *base);
return status;
}
@@ -1181,8 +1185,9 @@ NTSTATUS WINAPI LdrGetProcedureAddress(H
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
NTSTATUS ret = STATUS_PROCEDURE_NOT_FOUND;
+ sigset_t sigset;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
/* check if the module itself is invalid to return the proper error */
if (!get_modref( module )) ret = STATUS_DLL_NOT_FOUND;
@@ -1198,7 +1203,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(H
}
}
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
return ret;
}
@@ -1793,8 +1798,9 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_
{
WINE_MODREF *wm;
NTSTATUS nts;
+ sigset_t sigset;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
nts = load_dll( path_name, libname->Buffer, flags, &wm );
@@ -1810,7 +1816,7 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_
}
*hModule = (wm) ? wm->ldr.BaseAddress : NULL;
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
return nts;
}
@@ -1828,10 +1834,11 @@ NTSTATUS WINAPI LdrQueryProcessModuleInf
char* ptr;
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
+ sigset_t sigset;
smi->ModulesCount = 0;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
@@ -1859,7 +1866,7 @@ NTSTATUS WINAPI LdrQueryProcessModuleInf
}
else nts = STATUS_INFO_LENGTH_MISMATCH;
}
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
if (req_size) *req_size = size;
@@ -1884,6 +1891,7 @@ void WINAPI LdrShutdownThread(void)
{
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
+ sigset_t sigset;
TRACE("()\n");
@@ -1891,7 +1899,7 @@ void WINAPI LdrShutdownThread(void)
if (process_detaching) return;
/* FIXME: there is still a race here */
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
for (entry = mark->Blink; entry != mark; entry = entry->Blink)
@@ -1907,7 +1915,7 @@ void WINAPI LdrShutdownThread(void)
DLL_THREAD_DETACH, NULL );
}
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->ThreadLocalStoragePointer );
}
@@ -2016,10 +2024,11 @@ static void MODULE_DecRefCount( WINE_MOD
NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
{
NTSTATUS retv = STATUS_SUCCESS;
+ sigset_t sigset;
TRACE("(%p)\n", hModule);
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
/* if we're stopping the whole process (and forcing the removal of all
* DLLs) the library will be freed anyway
@@ -2051,7 +2060,7 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hM
free_lib_count--;
}
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
return retv;
}
@@ -2094,6 +2103,7 @@ void WINAPI LdrInitializeThunk( ULONG un
LPCWSTR load_path;
PEB *peb = NtCurrentTeb()->Peb;
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
+ sigset_t sigset;
if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
@@ -2134,7 +2144,7 @@ void WINAPI LdrInitializeThunk( ULONG un
if (status != STATUS_SUCCESS) goto error;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
@@ -2148,7 +2158,7 @@ void WINAPI LdrInitializeThunk( ULONG un
}
attach_implicitly_loaded_dlls( (LPVOID)1 );
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
return;
@@ -2232,10 +2242,11 @@ PVOID WINAPI RtlPcToFileHeader( PVOID pc
{
LDR_MODULE *module;
PVOID ret = NULL;
+ sigset_t sigset;
- RtlEnterCriticalSection( &loader_section );
+ NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
if (!LdrFindEntryForAddress( pc, &module )) ret = module->BaseAddress;
- RtlLeaveCriticalSection( &loader_section );
+ NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
*address = ret;
return ret;
}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 03110a4..ab01bde 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -107,6 +107,13 @@ extern BOOL DIR_is_hidden_file( const UN
extern NTSTATUS DIR_unmount_device( HANDLE handle );
extern NTSTATUS DIR_get_unix_cwd( char **cwd );
+/* critical sections */
+extern RTL_CRITICAL_SECTION csThread;
+extern void NTDLL_EnterUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+ sigset_t *sigset );
+extern void NTDLL_LeaveUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+ sigset_t *sigset );
+
/* virtual memory */
extern NTSTATUS VIRTUAL_HandleFault(LPCVOID addr);
extern BOOL VIRTUAL_HasMapping( LPCVOID addr );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 97be8ec..702980f 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -455,8 +455,10 @@ #endif
int wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attributes, obj_handle_t *handle )
{
int ret;
+ sigset_t sigset;
*handle = 0;
+ NTDLL_EnterUninterruptedCriticalSection( &csThread, &sigset );
wine_server_send_fd( fd );
SERVER_START_REQ( alloc_file_handle )
@@ -467,6 +469,7 @@ int wine_server_fd_to_handle( int fd, un
if (!(ret = wine_server_call( req ))) *handle = reply->handle;
}
SERVER_END_REQ;
+ NTDLL_LeaveUninterruptedCriticalSection( &csThread, &sigset );
return ret;
}
@@ -953,3 +956,29 @@ #endif
(version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
return info_size;
}
+
+
+/***********************************************************************
+ * wine_block_suspend_signal
+ */
+void wine_block_suspend_signal(sigset_t *old_set)
+{
+ static sigset_t suspend_set;
+ static unsigned first_time = 1;
+ if (first_time)
+ {
+ first_time = 0;
+ sigemptyset( &suspend_set );
+ sigaddset( &suspend_set, SIGUSR1 );
+ }
+ pthread_functions.sigprocmask( SIG_BLOCK, &suspend_set, old_set );
+}
+
+
+/***********************************************************************
+ * wine_unblock_suspend_signal
+ */
+void wine_unblock_suspend_signal(sigset_t *old_set)
+{
+ pthread_functions.sigprocmask( SIG_SETMASK, old_set, NULL );
+}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index dbcc5a6..f732573 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -63,6 +63,15 @@ static ULONG sigstack_zero_bits;
struct wine_pthread_functions pthread_functions = { NULL };
+RTL_CRITICAL_SECTION csThread;
+static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &csThread,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": csThread") }
+};
+RTL_CRITICAL_SECTION csThread = { &critsect_debug, -1, 0, 0, 0, 0 };
+
/***********************************************************************
* init_teb
*/
@@ -359,7 +368,8 @@ static void start_thread( struct wine_pt
/* setup the guard page */
size = page_size;
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL );
- RtlFreeHeap( GetProcessHeap(), 0, info );
+ size = 0;
+ NtFreeVirtualMemory( NtCurrentProcess(), (PVOID *) &info, &size, MEM_RELEASE );
RtlAcquirePebLock();
InsertHeadList( &tls_links, &teb->TlsLinks );
@@ -405,6 +415,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
int request_pipe[2];
NTSTATUS status;
SIZE_T size, page_size = getpagesize();
+ sigset_t sigset;
if( ! is_current_process( process ) )
{
@@ -414,6 +425,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
if (pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
fcntl( request_pipe[1], F_SETFD, 1 ); /* set close on exec flag */
+ NTDLL_EnterUninterruptedCriticalSection( &csThread, &sigset );
wine_server_send_fd( request_pipe[0] );
SERVER_START_REQ( new_thread )
@@ -430,14 +442,14 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
close( request_pipe[0] );
}
SERVER_END_REQ;
+ NTDLL_LeaveUninterruptedCriticalSection( &csThread, &sigset );
if (status) goto error;
- if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) )))
- {
- status = STATUS_NO_MEMORY;
+ size = sizeof(*info);
+ if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), (PVOID *) &info, 0,
+ &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
goto error;
- }
addr = NULL;
size = sigstack_total_size;
@@ -503,7 +515,11 @@ error:
SIZE_T size = 0;
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
}
- RtlFreeHeap( GetProcessHeap(), 0, info );
+ if (info)
+ {
+ SIZE_T size = 0;
+ NtFreeVirtualMemory( NtCurrentProcess(), (PVOID *) &info, &size, MEM_RELEASE );
+ }
if (handle) NtClose( handle );
close( request_pipe[1] );
return status;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index f7b829f..8c6de4a 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -201,15 +201,16 @@ static void VIRTUAL_DumpView( FILE_VIEW
#if WINE_VM_DEBUG
static void VIRTUAL_Dump(void)
{
+ sigset_t sigset;
struct file_view *view;
TRACE( "Dump of all virtual memory views:\n" );
- RtlEnterCriticalSection(&csVirtual);
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
LIST_FOR_EACH_ENTRY( view, &views_list, FILE_VIEW, entry )
{
VIRTUAL_DumpView( view );
}
- RtlLeaveCriticalSection(&csVirtual);
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
}
#endif
@@ -925,13 +926,14 @@ static NTSTATUS map_image( HANDLE hmappi
NTSTATUS status = STATUS_CONFLICTING_ADDRESSES;
int i;
off_t pos;
+ sigset_t sigset;
struct stat st;
struct file_view *view = NULL;
char *ptr, *header_end;
/* zero-map the whole range */
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if (base >= (char *)0x110000) /* make sure the DOS area remains free */
status = map_view( &view, base, total_size, mask, FALSE,
@@ -1176,14 +1178,14 @@ static NTSTATUS map_image( HANDLE hmappi
NtCurrentProcess(), &view->mapping,
0, 0, DUPLICATE_SAME_ACCESS );
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
*addr_ptr = ptr;
return STATUS_SUCCESS;
error:
if (view) delete_view( view );
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return status;
}
@@ -1251,8 +1253,9 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
{
FILE_VIEW *view;
NTSTATUS ret = STATUS_ACCESS_VIOLATION;
+ sigset_t sigset;
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if ((view = VIRTUAL_FindView( addr )))
{
void *page = ROUND_ADDR( addr, page_mask );
@@ -1263,7 +1266,7 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
ret = STATUS_GUARD_PAGE_VIOLATION;
}
}
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return ret;
}
@@ -1276,10 +1279,11 @@ BOOL VIRTUAL_HasMapping( LPCVOID addr )
{
FILE_VIEW *view;
BOOL ret = FALSE;
+ sigset_t sigset;
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if ((view = VIRTUAL_FindView( addr ))) ret = (view->mapping != 0);
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return ret;
}
@@ -1309,6 +1313,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
SIZE_T size = *size_ptr;
SIZE_T mask = get_mask( zero_bits );
NTSTATUS status = STATUS_SUCCESS;
+ sigset_t sigset;
struct file_view *view;
TRACE("%p %p %08lx %lx %08lx\n", process, *ret, size, type, protect );
@@ -1361,7 +1366,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
/* Reserve the memory */
- if (use_locks) RtlEnterCriticalSection( &csVirtual );
+ if (use_locks) NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if (type & MEM_SYSTEM)
{
@@ -1389,7 +1394,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
else if (!VIRTUAL_SetProt( view, base, size, vprot )) status = STATUS_ACCESS_DENIED;
}
- if (use_locks) RtlLeaveCriticalSection( &csVirtual );
+ if (use_locks) NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
if (status == STATUS_SUCCESS)
{
@@ -1411,6 +1416,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
NTSTATUS status = STATUS_SUCCESS;
LPVOID addr = *addr_ptr;
SIZE_T size = *size_ptr;
+ sigset_t sigset;
TRACE("%p %p %08lx %lx\n", process, addr, size, type );
@@ -1425,7 +1431,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
size = ROUND_SIZE( addr, size );
base = ROUND_ADDR( addr, page_mask );
- RtlEnterCriticalSection(&csVirtual);
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if (!(view = VIRTUAL_FindView( base )) ||
(base + size > (char *)view->base + view->size) ||
@@ -1469,7 +1475,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
status = STATUS_INVALID_PARAMETER;
}
- RtlLeaveCriticalSection(&csVirtual);
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return status;
}
@@ -1489,6 +1495,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(
ULONG prot;
SIZE_T size = *size_ptr;
LPVOID addr = *addr_ptr;
+ sigset_t sigset;
TRACE("%p %p %08lx %08lx\n", process, addr, size, new_prot );
@@ -1503,7 +1510,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(
size = ROUND_SIZE( addr, size );
base = ROUND_ADDR( addr, page_mask );
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if (!(view = VIRTUAL_FindView( base )) || (base + size > (char *)view->base + view->size))
{
@@ -1530,7 +1537,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(
if (!VIRTUAL_SetProt( view, base, size, vprot )) status = STATUS_ACCESS_DENIED;
}
}
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
if (status == STATUS_SUCCESS)
{
@@ -1558,6 +1565,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
struct list *ptr;
SIZE_T size = 0;
MEMORY_BASIC_INFORMATION *info = buffer;
+ sigset_t sigset;
if (info_class != MemoryBasicInformation)
{
@@ -1586,7 +1594,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
/* Find the view containing the address */
- RtlEnterCriticalSection(&csVirtual);
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
ptr = list_head( &views_list );
for (;;)
{
@@ -1598,7 +1606,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
{
if (user_space_limit && base >= (char *)user_space_limit)
{
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return STATUS_WORKING_SET_LIMIT_RANGE;
}
size = (char *)user_space_limit - alloc_base;
@@ -1645,7 +1653,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
for (size = base - alloc_base; size < view->size; size += page_size)
if (view->prot[size >> page_shift] != vprot) break;
}
- RtlLeaveCriticalSection(&csVirtual);
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
info->BaseAddress = (LPVOID)base;
info->AllocationBase = (LPVOID)alloc_base;
@@ -1774,6 +1782,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
HANDLE shared_file;
BOOL removable = FALSE;
LARGE_INTEGER offset;
+ sigset_t sigset;
offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
@@ -1881,12 +1890,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
/* Reserve a properly aligned area */
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
res = map_view( &view, *addr_ptr, size, mask, FALSE, prot );
if (res)
{
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
goto done;
}
@@ -1913,7 +1922,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
delete_view( view );
}
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
done:
wine_server_release_fd( handle, unix_handle );
@@ -1929,6 +1938,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HA
{
FILE_VIEW *view;
NTSTATUS status = STATUS_INVALID_PARAMETER;
+ sigset_t sigset;
void *base = ROUND_ADDR( addr, page_mask );
if (!is_current_process( process ))
@@ -1936,13 +1946,13 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HA
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
}
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if ((view = VIRTUAL_FindView( base )) && (base == view->base))
{
delete_view( view );
status = STATUS_SUCCESS;
}
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return status;
}
@@ -1956,6 +1966,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
{
FILE_VIEW *view;
NTSTATUS status = STATUS_SUCCESS;
+ sigset_t sigset;
void *addr = ROUND_ADDR( *addr_ptr, page_mask );
if (!is_current_process( process ))
@@ -1963,7 +1974,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
}
- RtlEnterCriticalSection( &csVirtual );
+ NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
if (!(view = VIRTUAL_FindView( addr ))) status = STATUS_INVALID_PARAMETER;
else
{
@@ -1971,7 +1982,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
*addr_ptr = addr;
if (msync( addr, *size_ptr, MS_SYNC )) status = STATUS_NOT_MAPPED_DATA;
}
- RtlLeaveCriticalSection( &csVirtual );
+ NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
return status;
}
More information about the wine-patches
mailing list