From 51f6aeb462ba645c3978773a91a106d76b5d3344 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 13 Apr 2000 17:21:36 +0000 Subject: [PATCH] Implemented guard pages and stack overflow exceptions. --- dlls/ntdll/signal_i386.c | 5 +++-- include/global.h | 2 +- memory/virtual.c | 28 ++++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 02a932b0a96..e964f8f00bb 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -475,13 +475,14 @@ static HANDLER_DEF(segv_handler) { EXCEPTION_RECORD rec; CONTEXT context; + DWORD page_fault_code = EXCEPTION_ACCESS_VIOLATION; handler_init( &context, HANDLER_CONTEXT ); #ifdef CR2_sig /* we want the page-fault case to be fast */ if (get_trap_code(HANDLER_CONTEXT) == T_PAGEFLT) - if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return; + if (!(page_fault_code = VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) ))) return; #endif save_context( &context, HANDLER_CONTEXT ); @@ -520,7 +521,7 @@ static HANDLER_DEF(segv_handler) #endif /* ERROR_sig */ rec.ExceptionInformation[1] = CR2_sig(HANDLER_CONTEXT); #endif /* CR2_sig */ - rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION; + rec.ExceptionCode = page_fault_code; break; case T_ALIGNFLT: /* Alignment check exception */ /* FIXME: pass through exception handler first? */ diff --git a/include/global.h b/include/global.h index aa93047cb9e..65897108474 100644 --- a/include/global.h +++ b/include/global.h @@ -37,7 +37,7 @@ extern LPVOID VIRTUAL_MapFileW( LPCWSTR name ); typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID); extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg); -extern BOOL VIRTUAL_HandleFault(LPCVOID addr); +extern DWORD VIRTUAL_HandleFault(LPCVOID addr); /* memory/atom.c */ extern BOOL ATOM_Init( WORD globalTableSel ); diff --git a/memory/virtual.c b/memory/virtual.c index 21dd40faee3..f23bc3f7be5 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -510,13 +510,33 @@ BOOL VIRTUAL_SetFaultHandler( LPCVOID addr, HANDLERPROC proc, LPVOID arg ) /*********************************************************************** * VIRTUAL_HandleFault */ -BOOL VIRTUAL_HandleFault( LPCVOID addr ) +DWORD VIRTUAL_HandleFault( LPCVOID addr ) { FILE_VIEW *view = VIRTUAL_FindView((UINT)addr); + DWORD ret = EXCEPTION_ACCESS_VIOLATION; - if (view && view->handlerProc) - return view->handlerProc(view->handlerArg, addr); - return FALSE; + if (view) + { + if (view->handlerProc) + { + if (view->handlerProc(view->handlerArg, addr)) ret = 0; /* handled */ + } + else + { + BYTE vprot = view->prot[((UINT)addr - view->base) >> page_shift]; + UINT page = (UINT)addr & ~page_mask; + char *stack = (char *)NtCurrentTeb()->stack_base + SIGNAL_STACK_SIZE + page_mask + 1; + if (vprot & VPROT_GUARD) + { + VIRTUAL_SetProt( view, page, page_mask + 1, vprot & ~VPROT_GUARD ); + ret = STATUS_GUARD_PAGE_VIOLATION; + } + /* is it inside the stack guard pages? */ + if (((char *)addr >= stack) && ((char *)addr < stack + 2*(page_mask+1))) + ret = STATUS_STACK_OVERFLOW; + } + } + return ret; }