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)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
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 );
CloseHandle( mapping );
......@@ -507,7 +507,7 @@ static void test_MapViewOfFile(void)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
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 );
CloseHandle( mapping );
......
......@@ -353,20 +353,20 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa,
/* fall through */
case PAGE_READONLY:
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;
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;
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;
case PAGE_EXECUTE_READ:
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;
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;
default:
SetLastError( ERROR_INVALID_PARAMETER );
......@@ -469,7 +469,14 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
attr.SecurityQualityOfService = NULL;
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 )))
{
......
......@@ -520,13 +520,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect )
vprot = VPROT_READ | VPROT_WRITE;
break;
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;
break;
case PAGE_EXECUTE:
......@@ -539,7 +532,6 @@ static BYTE VIRTUAL_GetProt( DWORD protect )
vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE;
break;
case PAGE_EXECUTE_WRITECOPY:
/* See comment for PAGE_WRITECOPY above */
vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY;
break;
case PAGE_NOACCESS:
......@@ -2072,10 +2064,11 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
{
NTSTATUS res;
ULONGLONG full_size;
ACCESS_MASK access;
SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1, needs_close;
unsigned int prot;
unsigned int map_vprot, vprot;
void *base;
struct file_view *view;
DWORD header_size;
......@@ -2119,11 +2112,32 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
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 )
{
req->handle = handle;
req->access = access;
res = wine_server_call( req );
prot = reply->protect;
map_vprot = reply->protect;
base = reply->base;
full_size = reply->size;
header_size = reply->header_size;
......@@ -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 (prot & VPROT_IMAGE)
if (map_vprot & VPROT_IMAGE)
{
if (shared_file)
{
......@@ -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 );
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 */
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)
{
server_leave_uninterrupted_section( &csVirtual, &sigset );
......@@ -2211,7 +2202,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
TRACE("handle=%p size=%lx offset=%x%08x\n",
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)
{
*addr_ptr = view->base;
......
......@@ -1716,6 +1716,7 @@ struct get_mapping_info_request
{
struct request_header __header;
obj_handle_t handle;
unsigned int access;
};
struct get_mapping_info_reply
{
......@@ -5070,6 +5071,6 @@ union generic_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 */
......@@ -562,7 +562,7 @@ DECL_HANDLER(get_mapping_info)
struct fd *fd;
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->protect = mapping->protect;
......
......@@ -1351,6 +1351,7 @@ enum char_info_mode
/* Get information about a file mapping */
@REQ(get_mapping_info)
obj_handle_t handle; /* handle to the mapping */
unsigned int access; /* wanted access rights */
@REPLY
file_pos_t size; /* mapping size */
int protect; /* protection flags */
......
......@@ -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 )
{
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 )
......
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