Commit 5e2ed6bf authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll,server: Fixed access checks for OpenFileMapping and MapViewOfFile.

parent 0f928343
...@@ -482,7 +482,7 @@ static void test_MapViewOfFile(void) ...@@ -482,7 +482,7 @@ static void test_MapViewOfFile(void)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State ); ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect ); ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
} }
else todo_wine win_skip( "no access checks on win9x\n" ); else win_skip( "no access checks on win9x\n" );
UnmapViewOfFile( ptr ); UnmapViewOfFile( ptr );
CloseHandle( mapping ); CloseHandle( mapping );
...@@ -507,7 +507,7 @@ static void test_MapViewOfFile(void) ...@@ -507,7 +507,7 @@ static void test_MapViewOfFile(void)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State ); ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect ); ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
} }
else todo_wine win_skip( "no access checks on win9x\n" ); else win_skip( "no access checks on win9x\n" );
UnmapViewOfFile( ptr ); UnmapViewOfFile( ptr );
CloseHandle( mapping ); CloseHandle( mapping );
......
...@@ -353,20 +353,20 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa, ...@@ -353,20 +353,20 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa,
/* fall through */ /* fall through */
case PAGE_READONLY: case PAGE_READONLY:
case PAGE_WRITECOPY: case PAGE_WRITECOPY:
access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ; access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE;
break; break;
case PAGE_READWRITE: case PAGE_READWRITE:
access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE; access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE;
break; break;
case PAGE_EXECUTE: case PAGE_EXECUTE:
access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_EXECUTE; access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_EXECUTE | SECTION_MAP_EXECUTE_EXPLICIT;
break; break;
case PAGE_EXECUTE_READ: case PAGE_EXECUTE_READ:
case PAGE_EXECUTE_WRITECOPY: case PAGE_EXECUTE_WRITECOPY:
access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE; access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_EXECUTE_EXPLICIT;
break; break;
case PAGE_EXECUTE_READWRITE: case PAGE_EXECUTE_READWRITE:
access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE; access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE | SECTION_MAP_EXECUTE_EXPLICIT;
break; break;
default: default:
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
...@@ -469,7 +469,14 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name) ...@@ -469,7 +469,14 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
attr.SecurityQualityOfService = NULL; attr.SecurityQualityOfService = NULL;
RtlInitUnicodeString( &nameW, name ); RtlInitUnicodeString( &nameW, name );
if (access == FILE_MAP_COPY) access = FILE_MAP_READ; if (access & FILE_MAP_COPY) access |= SECTION_MAP_READ;
access |= STANDARD_RIGHTS_REQUIRED | SECTION_QUERY;
if (GetVersion() & 0x80000000)
{
/* win9x doesn't do access checks, so try with full access first */
if (!NtOpenSection( &ret, access | SECTION_MAP_READ | SECTION_MAP_WRITE, &attr )) return ret;
}
if ((status = NtOpenSection( &ret, access, &attr ))) if ((status = NtOpenSection( &ret, access, &attr )))
{ {
......
...@@ -520,13 +520,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect ) ...@@ -520,13 +520,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect )
vprot = VPROT_READ | VPROT_WRITE; vprot = VPROT_READ | VPROT_WRITE;
break; break;
case PAGE_WRITECOPY: case PAGE_WRITECOPY:
/* MSDN CreateFileMapping() states that if PAGE_WRITECOPY is given,
* that the hFile must have been opened with GENERIC_READ and
* GENERIC_WRITE access. This is WRONG as tests show that you
* only need GENERIC_READ access (at least for Win9x,
* FIXME: what about NT?). Thus, we don't put VPROT_WRITE in
* PAGE_WRITECOPY and PAGE_EXECUTE_WRITECOPY.
*/
vprot = VPROT_READ | VPROT_WRITECOPY; vprot = VPROT_READ | VPROT_WRITECOPY;
break; break;
case PAGE_EXECUTE: case PAGE_EXECUTE:
...@@ -539,7 +532,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect ) ...@@ -539,7 +532,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect )
vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE; vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE;
break; break;
case PAGE_EXECUTE_WRITECOPY: case PAGE_EXECUTE_WRITECOPY:
/* See comment for PAGE_WRITECOPY above */
vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY; vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY;
break; break;
case PAGE_NOACCESS: case PAGE_NOACCESS:
...@@ -2072,10 +2064,11 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2072,10 +2064,11 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
{ {
NTSTATUS res; NTSTATUS res;
ULONGLONG full_size; ULONGLONG full_size;
ACCESS_MASK access;
SIZE_T size = 0; SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits ); SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1, needs_close; int unix_handle = -1, needs_close;
unsigned int prot; unsigned int map_vprot, vprot;
void *base; void *base;
struct file_view *view; struct file_view *view;
DWORD header_size; DWORD header_size;
...@@ -2119,11 +2112,32 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2119,11 +2112,32 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
return result.map_view.status; return result.map_view.status;
} }
switch(protect)
{
case PAGE_NOACCESS:
access = SECTION_QUERY;
break;
case PAGE_READWRITE:
case PAGE_EXECUTE_READWRITE:
access = SECTION_QUERY | SECTION_MAP_WRITE;
break;
case PAGE_READONLY:
case PAGE_WRITECOPY:
case PAGE_EXECUTE:
case PAGE_EXECUTE_READ:
case PAGE_EXECUTE_WRITECOPY:
access = SECTION_QUERY | SECTION_MAP_READ;
break;
default:
return STATUS_INVALID_PARAMETER;
}
SERVER_START_REQ( get_mapping_info ) SERVER_START_REQ( get_mapping_info )
{ {
req->handle = handle; req->handle = handle;
req->access = access;
res = wine_server_call( req ); res = wine_server_call( req );
prot = reply->protect; map_vprot = reply->protect;
base = reply->base; base = reply->base;
full_size = reply->size; full_size = reply->size;
header_size = reply->header_size; header_size = reply->header_size;
...@@ -2140,7 +2154,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2140,7 +2154,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, NULL ))) goto done; if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, NULL ))) goto done;
if (prot & VPROT_IMAGE) if (map_vprot & VPROT_IMAGE)
{ {
if (shared_file) if (shared_file)
{ {
...@@ -2171,35 +2185,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2171,35 +2185,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
if (*size_ptr) size = ROUND_SIZE( offset.u.LowPart, *size_ptr ); if (*size_ptr) size = ROUND_SIZE( offset.u.LowPart, *size_ptr );
else size = size - offset.QuadPart; else size = size - offset.QuadPart;
switch(protect)
{
case PAGE_NOACCESS:
break;
case PAGE_READWRITE:
case PAGE_EXECUTE_READWRITE:
if (!(prot & VPROT_WRITE))
{
res = STATUS_INVALID_PARAMETER;
goto done;
}
/* fall through */
case PAGE_READONLY:
case PAGE_WRITECOPY:
case PAGE_EXECUTE:
case PAGE_EXECUTE_READ:
case PAGE_EXECUTE_WRITECOPY:
if (prot & VPROT_READ) break;
/* fall through */
default:
res = STATUS_INVALID_PARAMETER;
goto done;
}
/* Reserve a properly aligned area */ /* Reserve a properly aligned area */
server_enter_uninterrupted_section( &csVirtual, &sigset ); server_enter_uninterrupted_section( &csVirtual, &sigset );
res = map_view( &view, *addr_ptr, size, mask, FALSE, prot ); vprot = VIRTUAL_GetProt( protect ) | (map_vprot & VPROT_COMMITTED);
res = map_view( &view, *addr_ptr, size, mask, FALSE, vprot );
if (res) if (res)
{ {
server_leave_uninterrupted_section( &csVirtual, &sigset ); server_leave_uninterrupted_section( &csVirtual, &sigset );
...@@ -2211,7 +2202,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2211,7 +2202,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
TRACE("handle=%p size=%lx offset=%x%08x\n", TRACE("handle=%p size=%lx offset=%x%08x\n",
handle, size, offset.u.HighPart, offset.u.LowPart ); handle, size, offset.u.HighPart, offset.u.LowPart );
res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, prot, !dup_mapping ); res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, vprot, !dup_mapping );
if (res == STATUS_SUCCESS) if (res == STATUS_SUCCESS)
{ {
*addr_ptr = view->base; *addr_ptr = view->base;
......
...@@ -1716,6 +1716,7 @@ struct get_mapping_info_request ...@@ -1716,6 +1716,7 @@ struct get_mapping_info_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
unsigned int access;
}; };
struct get_mapping_info_reply struct get_mapping_info_reply
{ {
...@@ -5070,6 +5071,6 @@ union generic_reply ...@@ -5070,6 +5071,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 345 #define SERVER_PROTOCOL_VERSION 346
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -562,7 +562,7 @@ DECL_HANDLER(get_mapping_info) ...@@ -562,7 +562,7 @@ DECL_HANDLER(get_mapping_info)
struct fd *fd; struct fd *fd;
if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
0, &mapping_ops ))) req->access | SECTION_QUERY, &mapping_ops )))
{ {
reply->size = mapping->size; reply->size = mapping->size;
reply->protect = mapping->protect; reply->protect = mapping->protect;
......
...@@ -1351,6 +1351,7 @@ enum char_info_mode ...@@ -1351,6 +1351,7 @@ enum char_info_mode
/* Get information about a file mapping */ /* Get information about a file mapping */
@REQ(get_mapping_info) @REQ(get_mapping_info)
obj_handle_t handle; /* handle to the mapping */ obj_handle_t handle; /* handle to the mapping */
unsigned int access; /* wanted access rights */
@REPLY @REPLY
file_pos_t size; /* mapping size */ file_pos_t size; /* mapping size */
int protect; /* protection flags */ int protect; /* protection flags */
......
...@@ -1769,7 +1769,8 @@ static void dump_open_mapping_reply( const struct open_mapping_reply *req ) ...@@ -1769,7 +1769,8 @@ static void dump_open_mapping_reply( const struct open_mapping_reply *req )
static void dump_get_mapping_info_request( const struct get_mapping_info_request *req ) static void dump_get_mapping_info_request( const struct get_mapping_info_request *req )
{ {
fprintf( stderr, " handle=%p", req->handle ); fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " access=%08x", req->access );
} }
static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *req ) static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *req )
......
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