1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 :
8 : /* NaCl inter-module communication primitives. */
9 :
10 : #include <windows.h>
11 :
12 : #include "native_client/src/shared/imc/nacl_imc_c.h"
13 : #include "native_client/src/shared/platform/nacl_check.h"
14 : #include "native_client/src/shared/platform/nacl_log.h"
15 : #include "native_client/src/trusted/desc/nacl_desc_effector.h"
16 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
17 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
18 :
19 : /*
20 : * This function is a no-op on Windows because there is no need to
21 : * override the Windows definition of NaClCreateMemoryObject(): it
22 : * already works inside the outer sandbox.
23 : */
24 0 : void NaClSetCreateMemoryObjectFunc(NaClCreateMemoryObjectFunc func) {
25 0 : }
26 :
27 1 : NaClHandle NaClCreateMemoryObject(size_t length, int executable) {
28 : NaClHandle memory;
29 1 : if (length % NACL_MAP_PAGESIZE) {
30 0 : SetLastError(ERROR_INVALID_PARAMETER);
31 0 : return NACL_INVALID_HANDLE;
32 : }
33 : DWORD flags;
34 1 : if (executable) {
35 : /*
36 : * Passing SEC_RESERVE overrides the implicit default of
37 : * SEC_COMMIT, and it means that we do not allocate swap space for
38 : * the pages initially. These uncommitted pages will be
39 : * inaccessible even if they are mapped with PAGE_EXECUTE_READ,
40 : * and nacl_text.c relies on this.
41 : */
42 1 : flags = PAGE_EXECUTE_READWRITE | SEC_RESERVE;
43 1 : } else {
44 1 : flags = PAGE_READWRITE;
45 : }
46 : memory = CreateFileMapping(
47 : INVALID_HANDLE_VALUE,
48 : NULL,
49 : flags,
50 : (DWORD) (((unsigned __int64) length) >> 32),
51 1 : (DWORD) (length & 0xFFFFFFFF), NULL);
52 1 : return (memory == NULL) ? NACL_INVALID_HANDLE : memory;
53 1 : }
54 :
55 : /*
56 : * TODO(mseaborn): Reduce duplication between this function and
57 : * NaClHostDescMap().
58 : */
59 : void* NaClMap(struct NaClDescEffector* effp,
60 : void* start, size_t length, int prot, int flags,
61 0 : NaClHandle memory, off_t offset) {
62 : static DWORD prot_to_access[] = {
63 : 0, /* NACL_ABI_PROT_NONE is not accepted: see below. */
64 : FILE_MAP_READ,
65 : FILE_MAP_WRITE,
66 : FILE_MAP_ALL_ACCESS,
67 : FILE_MAP_EXECUTE,
68 : FILE_MAP_READ | FILE_MAP_EXECUTE,
69 : FILE_MAP_WRITE | FILE_MAP_EXECUTE,
70 : FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE
71 : };
72 : DWORD desired_access;
73 : size_t chunk_offset;
74 :
75 0 : if (prot == NACL_ABI_PROT_NONE) {
76 : /*
77 : * There is no corresponding FILE_MAP_* option for PROT_NONE. In
78 : * any case, this would not be very useful because the permissions
79 : * cannot later be increased beyond what was passed to
80 : * MapViewOfFileEx(), unlike in Unix.
81 : */
82 0 : NaClLog(LOG_INFO, "NaClMap: PROT_NONE not supported\n");
83 0 : SetLastError(ERROR_INVALID_PARAMETER);
84 0 : return NACL_MAP_FAILED;
85 : }
86 :
87 0 : if (!(flags & (NACL_MAP_SHARED | NACL_MAP_PRIVATE))) {
88 0 : SetLastError(ERROR_INVALID_PARAMETER);
89 0 : return NACL_MAP_FAILED;
90 : }
91 :
92 : /* Convert prot to the desired access type for MapViewOfFileEx(). */
93 0 : desired_access = prot_to_access[prot & 0x7];
94 0 : if (flags & NACL_MAP_PRIVATE) {
95 0 : desired_access = FILE_MAP_COPY;
96 : }
97 :
98 0 : CHECK((flags & NACL_MAP_FIXED) != 0);
99 0 : for (chunk_offset = 0;
100 0 : chunk_offset < length;
101 0 : chunk_offset += NACL_MAP_PAGESIZE) {
102 0 : uintptr_t chunk_addr = (uintptr_t) start + chunk_offset;
103 : void* mapped;
104 :
105 0 : (*effp->vtbl->UnmapMemory)(effp, chunk_addr, NACL_MAP_PAGESIZE);
106 :
107 : mapped = MapViewOfFileEx(memory, desired_access,
108 : 0, (off_t) (offset + chunk_offset),
109 : NACL_MAP_PAGESIZE,
110 0 : (void*) chunk_addr);
111 0 : if (mapped != (void*) chunk_addr) {
112 : NaClLog(LOG_FATAL, "nacl::Map: MapViewOfFileEx() failed, error %d\n",
113 0 : GetLastError());
114 : }
115 0 : }
116 0 : return start;
117 0 : }
118 :
119 0 : int NaClUnmap(void* start, size_t length) {
120 : /* TODO(shiki): Try from start to start + length */
121 0 : UnmapViewOfFile(start);
122 0 : return 0;
123 0 : }
|