Alexandre Julliard : ntdll: Check buffer for access in NtReadFile before performing I/O.
Alexandre Julliard
julliard at winehq.org
Thu Jan 15 08:50:56 CST 2009
Module: wine
Branch: master
Commit: 63bff0937f949379193b6d3b87b03edeaaf77d52
URL: http://source.winehq.org/git/wine.git/?a=commit;h=63bff0937f949379193b6d3b87b03edeaaf77d52
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jan 14 20:17:52 2009 +0100
ntdll: Check buffer for access in NtReadFile before performing I/O.
This also triggers page faults needed for write watches.
---
dlls/ntdll/file.c | 15 +++++++++------
dlls/ntdll/ntdll_misc.h | 1 +
dlls/ntdll/virtual.c | 33 +++++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 60aec8a..cbb0eac 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -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)))
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 2fcdb1a..306b36d 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -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;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 33c946f..74e72fd 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -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.
More information about the wine-cvs
mailing list