Commit 63bff093 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Check buffer for access in NtReadFile before performing I/O.

This also triggers page faults needed for write watches.
parent 39d4f9e2
......@@ -568,6 +568,12 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
&needs_close, &type, &options );
if (status) return status;
if (!virtual_check_buffer_for_write( buffer, length ))
{
status = STATUS_ACCESS_VIOLATION;
goto done;
}
if (type == FD_TYPE_FILE && offset && offset->QuadPart != (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */ )
{
/* async I/O doesn't make sense on regular files */
......@@ -615,14 +621,11 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
}
else if (type == FD_TYPE_FILE) continue; /* no async I/O on regular files */
}
else
else if (errno != EAGAIN)
{
if (errno == EINTR) continue;
if (errno != EAGAIN)
{
status = FILE_GetNtStatus();
goto done;
}
if (!total) status = FILE_GetNtStatus();
goto done;
}
if (!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
......
......@@ -142,6 +142,7 @@ extern void virtual_clear_thread_stack(void);
extern BOOL virtual_handle_stack_fault( void *addr );
extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err );
extern BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size );
extern BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size );
extern void VIRTUAL_SetForceExec( BOOL enable );
extern void VIRTUAL_UseLargeAddressSpace(void);
extern struct _KUSER_SHARED_DATA *user_shared_data;
......
......@@ -1551,6 +1551,39 @@ BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size )
/***********************************************************************
* virtual_check_buffer_for_write
*
* Check if a memory buffer can be written to, triggering page faults if needed for write watches.
*/
BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size )
{
if (!size) return TRUE;
if (!ptr) return FALSE;
__TRY
{
volatile char *p = ptr;
SIZE_T count = size;
while (count > page_size)
{
*p |= 0;
p += page_size;
count -= page_size;
}
p[0] |= 0;
p[count - 1] |= 0;
}
__EXCEPT_PAGE_FAULT
{
return FALSE;
}
__ENDTRY
return TRUE;
}
/***********************************************************************
* VIRTUAL_SetForceExec
*
* Whether to force exec prot on all views.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment