ntdll,server: Fixed access checks for OpenFileMapping and MapViewOfFile.
This commit is contained in:
parent
0f9283437c
commit
5e2ed6bfe9
|
@ -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)
|
||||||
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,
|
||||||
/* 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)
|
||||||
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 )
|
||||||
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 )
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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)
|
||||||
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
|
||||||
/* 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 )
|
||||||
|
|
||||||
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 )
|
||||||
|
|
Loading…
Reference in New Issue