From 94d5531e6febebcdf82d07d4593b9afede53ed79 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 16 Jan 2004 04:52:17 +0000 Subject: [PATCH] Check for overlapping memory views and delete the offending view if necessary, to ensure we never have two views covering the same address. --- dlls/ntdll/virtual.c | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 3245854c842..84dbe56da9e 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -238,6 +238,27 @@ static FILE_VIEW *VIRTUAL_FindView( const void *addr ) /* [in] Address */ /*********************************************************************** + * VIRTUAL_DeleteView + * Deletes a view. + * + * RETURNS + * None + */ +static void VIRTUAL_DeleteView( FILE_VIEW *view ) /* [in] View */ +{ + RtlEnterCriticalSection(&csVirtual); + if (!(view->flags & VFLAG_SYSTEM)) + munmap( (void *)view->base, view->size ); + if (view->next) view->next->prev = view->prev; + if (view->prev) view->prev->next = view->next; + else VIRTUAL_FirstView = view->next; + RtlLeaveCriticalSection(&csVirtual); + if (view->mapping) NtClose( view->mapping ); + free( view ); +} + + +/*********************************************************************** * VIRTUAL_CreateView * * Create a new view and add it in the linked list. @@ -290,6 +311,27 @@ static FILE_VIEW *VIRTUAL_CreateView( void *base, UINT size, UINT flags, view->prev = prev; if (view->next) view->next->prev = view; prev->next = view; + + /* Check for overlapping views. This can happen if the previous view + * was a system view that got unmapped behind our back. In that case + * we recover by simply deleting it. */ + if ((char *)prev->base + prev->size > (char *)base) + { + TRACE( "overlapping prev view %p-%p for %p-%p\n", + prev->base, (char *)prev->base + prev->size, + base, (char *)base + view->size ); + assert( view->prev->flags & VFLAG_SYSTEM ); + VIRTUAL_DeleteView( view->prev ); + } + } + /* check for overlap with next too */ + if (view->next && (char *)base + view->size > (char *)view->next->base) + { + TRACE( "overlapping next view %p-%p for %p-%p\n", + view->next->base, (char *)view->next->base + view->next->size, + base, (char *)base + view->size ); + assert( view->next->flags & VFLAG_SYSTEM ); + VIRTUAL_DeleteView( view->next ); } RtlLeaveCriticalSection(&csVirtual); VIRTUAL_DEBUG_DUMP_VIEW( view ); @@ -298,27 +340,6 @@ static FILE_VIEW *VIRTUAL_CreateView( void *base, UINT size, UINT flags, /*********************************************************************** - * VIRTUAL_DeleteView - * Deletes a view. - * - * RETURNS - * None - */ -static void VIRTUAL_DeleteView( FILE_VIEW *view ) /* [in] View */ -{ - if (!(view->flags & VFLAG_SYSTEM)) - munmap( (void *)view->base, view->size ); - RtlEnterCriticalSection(&csVirtual); - if (view->next) view->next->prev = view->prev; - if (view->prev) view->prev->next = view->next; - else VIRTUAL_FirstView = view->next; - RtlLeaveCriticalSection(&csVirtual); - if (view->mapping) NtClose( view->mapping ); - free( view ); -} - - -/*********************************************************************** * VIRTUAL_GetUnixProt * * Convert page protections to protection for mmap/mprotect. -- 2.11.4.GIT