Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: mojo/nacl/sfi/nacl_bindings/mojo_syscall_internal.h

Issue 2051163002: Nuke NaCl SFI, part 1. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_NACL_SFI_NACL_BINDINGS_MOJO_SYSCALL_INTERNAL_H_
6 #define MOJO_NACL_SFI_NACL_BINDINGS_MOJO_SYSCALL_INTERNAL_H_
7
8 #include <type_traits>
9
10 #include "native_client/src/trusted/service_runtime/nacl_copy.h"
11 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
12
13 namespace {
14
15 class ScopedCopyLock {
16 public:
17 explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) {
18 NaClCopyTakeLock(nap_);
19 }
20 ~ScopedCopyLock() { NaClCopyDropLock(nap_); }
21
22 private:
23 struct NaClApp* nap_;
24 };
25
26 static inline uintptr_t NaClUserToSysAddrArray(struct NaClApp* nap,
27 uint32_t uaddr,
28 size_t count,
29 size_t size) {
30 // TODO(ncbray): overflow checking
31 size_t range = count * size;
32 return NaClUserToSysAddrRange(nap, uaddr, range);
33 }
34
35 // We don't use plain-old memcpy because reads and writes to the untrusted
36 // address space from trusted code must be volatile. Non-volatile memory
37 // operations are dangerous because a compiler would be free to materialize a
38 // second load from the same memory address or materialize a load from a memory
39 // address that was stored, and assume the materialized load would return the
40 // same value as the previous load or store. Data races could cause the
41 // materialized load to return a different value, however, which could lead to
42 // time of check vs. time of use problems, or worse. For this binding code in
43 // particular, where memcpy is being called with a constant size, it is entirely
44 // conceivable the function will be inlined, unrolled, and optimized.
45 static inline void memcpy_volatile_out(void volatile* dst,
46 const void* src,
47 size_t n) {
48 char volatile* c_dst = static_cast<char volatile*>(dst);
49 const char* c_src = static_cast<const char*>(src);
50 for (size_t i = 0; i < n; i++) {
51 c_dst[i] = c_src[i];
52 }
53 }
54
55 template <typename T>
56 bool ConvertPointerInput(struct NaClApp* nap, uint32_t user_ptr, T** value) {
57 if (user_ptr) {
58 uintptr_t temp = NaClUserToSysAddr(nap, user_ptr);
59 if (temp != kNaClBadAddress) {
60 *value = reinterpret_cast<T*>(temp);
61 return true;
62 }
63 } else {
64 *value = nullptr;
65 return true;
66 }
67 *value = nullptr; // Paranoia.
68 return false;
69 }
70
71 template <typename T>
72 bool ConvertPointerInOut(struct NaClApp* nap,
73 uint32_t user_ptr,
74 bool optional,
75 T** value,
76 uint32_t volatile** sys_ptr) {
77 if (user_ptr) {
78 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(uint32_t));
79 if (temp != kNaClBadAddress) {
80 uint32_t volatile* converted_ptr =
81 reinterpret_cast<uint32_t volatile*>(temp);
82 uint32_t raw_value = *converted_ptr;
83 if (!raw_value) {
84 *sys_ptr = converted_ptr;
85 *value = nullptr;
86 return true;
87 }
88 uintptr_t temp = NaClUserToSysAddr(nap, raw_value);
89 if (temp != kNaClBadAddress) {
90 *sys_ptr = converted_ptr;
91 *value = reinterpret_cast<T*>(temp);
92 return true;
93 }
94 }
95 } else if (optional) {
96 *sys_ptr = nullptr;
97 *value = nullptr; // Paranoia.
98 return true;
99 }
100 *sys_ptr = nullptr; // Paranoia.
101 *value = nullptr; // Paranoia.
102 return false;
103 }
104
105 template <typename T>
106 void CopyOutPointer(struct NaClApp* nap, T* value, uint32_t volatile* sys_ptr) {
107 if (value) {
108 // Will kill the process if value if the pointer does not lie in the
109 // sandbox.
110 uintptr_t temp = NaClSysToUser(nap, reinterpret_cast<uintptr_t>(value));
111 *sys_ptr = static_cast<uint32_t>(temp);
112 } else {
113 *sys_ptr = 0;
114 }
115 }
116
117 template <typename T>
118 bool ConvertScalarInput(struct NaClApp* nap, uint32_t user_ptr, T* value) {
119 static_assert(!std::is_pointer<T>::value, "do not use for pointer types");
120 if (user_ptr) {
121 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
122 if (temp != kNaClBadAddress) {
123 *value = *reinterpret_cast<T volatile*>(temp);
124 return true;
125 }
126 }
127 return false;
128 }
129
130 template <typename T>
131 bool ConvertScalarOutput(struct NaClApp* nap,
132 uint32_t user_ptr,
133 bool optional,
134 T volatile** sys_ptr) {
135 static_assert(!std::is_pointer<T>::value, "do not use for pointer types");
136 if (user_ptr) {
137 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
138 if (temp != kNaClBadAddress) {
139 *sys_ptr = reinterpret_cast<T volatile*>(temp);
140 return true;
141 }
142 } else if (optional) {
143 *sys_ptr = 0;
144 return true;
145 }
146 *sys_ptr = 0; // Paranoia.
147 return false;
148 }
149
150 template <typename T>
151 bool ConvertScalarInOut(struct NaClApp* nap,
152 uint32_t user_ptr,
153 bool optional,
154 T* value,
155 T volatile** sys_ptr) {
156 static_assert(!std::is_pointer<T>::value, "do not use for pointer types");
157 if (user_ptr) {
158 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
159 if (temp != kNaClBadAddress) {
160 T volatile* converted = reinterpret_cast<T volatile*>(temp);
161 *sys_ptr = converted;
162 *value = *converted;
163 return true;
164 }
165 } else if (optional) {
166 *sys_ptr = 0;
167 *value = static_cast<T>(0); // Paranoia.
168 return true;
169 }
170 *sys_ptr = 0; // Paranoia.
171 *value = static_cast<T>(0); // Paranoia.
172 return false;
173 }
174
175 template <typename T>
176 bool ConvertArray(struct NaClApp* nap,
177 uint32_t user_ptr,
178 uint32_t length,
179 size_t element_size,
180 bool optional,
181 T** sys_ptr) {
182 if (user_ptr) {
183 uintptr_t temp =
184 NaClUserToSysAddrArray(nap, user_ptr, length, element_size);
185 if (temp != kNaClBadAddress) {
186 *sys_ptr = reinterpret_cast<T*>(temp);
187 return true;
188 }
189 } else if (optional) {
190 *sys_ptr = 0;
191 return true;
192 }
193 return false;
194 }
195
196 template <typename T>
197 bool ConvertBytes(struct NaClApp* nap,
198 uint32_t user_ptr,
199 uint32_t length,
200 bool optional,
201 T** sys_ptr) {
202 if (user_ptr) {
203 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length);
204 if (temp != kNaClBadAddress) {
205 *sys_ptr = reinterpret_cast<T*>(temp);
206 return true;
207 }
208 } else if (optional) {
209 *sys_ptr = 0;
210 return true;
211 }
212 return false;
213 }
214
215 // TODO(ncbray): size validation and complete copy.
216 // TODO(ncbray): ensure non-null / missized structs are covered by a test case.
217 template <typename T>
218 bool ConvertExtensibleStructInput(struct NaClApp* nap,
219 uint32_t user_ptr,
220 bool optional,
221 T** sys_ptr) {
222 static_assert(!std::is_pointer<T>::value, "do not use for pointer types");
223 if (user_ptr) {
224 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
225 if (temp != kNaClBadAddress) {
226 *sys_ptr = reinterpret_cast<T*>(temp);
227 return true;
228 }
229 } else if (optional) {
230 *sys_ptr = 0;
231 return true;
232 }
233 return false;
234 }
235
236 } // namespace
237
238 #endif // MOJO_NACL_SFI_NACL_BINDINGS_MOJO_SYSCALL_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/nacl/sfi/nacl_bindings/mojo_syscall.cc ('k') | mojo/nacl/sfi/nacl_bindings/monacl_sel_main.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698