OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ | 5 #ifndef MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ |
6 #define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ | 6 #define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ |
7 | 7 |
8 #include "native_client/src/trusted/service_runtime/nacl_copy.h" | 8 #include "native_client/src/trusted/service_runtime/nacl_copy.h" |
9 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 9 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 static inline uintptr_t NaClUserToSysAddrArray( | 25 static inline uintptr_t NaClUserToSysAddrArray( |
26 struct NaClApp* nap, | 26 struct NaClApp* nap, |
27 uint32_t uaddr, | 27 uint32_t uaddr, |
28 size_t count, | 28 size_t count, |
29 size_t size) { | 29 size_t size) { |
30 // TODO(ncbray): overflow checking | 30 // TODO(ncbray): overflow checking |
31 size_t range = count * size; | 31 size_t range = count * size; |
32 return NaClUserToSysAddrRange(nap, uaddr, range); | 32 return NaClUserToSysAddrRange(nap, uaddr, range); |
33 } | 33 } |
34 | 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( |
| 46 void volatile* dst, |
| 47 const void* src, |
| 48 size_t n) { |
| 49 char volatile* c_dst = static_cast<char volatile*>(dst); |
| 50 const char* c_src = static_cast<const char*>(src); |
| 51 for (size_t i = 0; i < n; i++) { |
| 52 c_dst[i] = c_src[i]; |
| 53 } |
| 54 } |
| 55 |
35 template <typename T> bool ConvertScalarInput( | 56 template <typename T> bool ConvertScalarInput( |
36 struct NaClApp* nap, | 57 struct NaClApp* nap, |
37 uint32_t user_ptr, | 58 uint32_t user_ptr, |
38 T* value) { | 59 T* value) { |
39 if (user_ptr) { | 60 if (user_ptr) { |
40 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); | 61 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); |
41 if (temp != kNaClBadAddress) { | 62 if (temp != kNaClBadAddress) { |
42 *value = *reinterpret_cast<T volatile*>(temp); | 63 *value = *reinterpret_cast<T volatile*>(temp); |
43 return true; | 64 return true; |
44 } | 65 } |
45 } | 66 } |
46 return false; | 67 return false; |
47 } | 68 } |
48 | 69 |
49 template <typename T> bool ConvertScalarOutput( | 70 template <typename T> bool ConvertScalarOutput( |
50 struct NaClApp* nap, | 71 struct NaClApp* nap, |
51 uint32_t user_ptr, | 72 uint32_t user_ptr, |
| 73 bool optional, |
52 T volatile** sys_ptr) { | 74 T volatile** sys_ptr) { |
53 if (user_ptr) { | 75 if (user_ptr) { |
54 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); | 76 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); |
55 if (temp != kNaClBadAddress) { | 77 if (temp != kNaClBadAddress) { |
56 *sys_ptr = reinterpret_cast<T volatile*>(temp); | 78 *sys_ptr = reinterpret_cast<T volatile*>(temp); |
57 return true; | 79 return true; |
| 80 } else if (optional) { |
| 81 *sys_ptr = 0; |
| 82 return true; |
58 } | 83 } |
59 } | 84 } |
60 *sys_ptr = 0; // Paranoia. | 85 *sys_ptr = 0; // Paranoia. |
61 return false; | 86 return false; |
62 } | 87 } |
63 | 88 |
64 template <typename T> bool ConvertScalarInOut( | 89 template <typename T> bool ConvertScalarInOut( |
65 struct NaClApp* nap, | 90 struct NaClApp* nap, |
66 uint32_t user_ptr, | 91 uint32_t user_ptr, |
67 bool optional, | 92 bool optional, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 } | 145 } |
121 } else if (optional) { | 146 } else if (optional) { |
122 *sys_ptr = 0; | 147 *sys_ptr = 0; |
123 return true; | 148 return true; |
124 } | 149 } |
125 return false; | 150 return false; |
126 } | 151 } |
127 | 152 |
128 // TODO(ncbray): size validation and complete copy. | 153 // TODO(ncbray): size validation and complete copy. |
129 // TODO(ncbray): ensure non-null / missized structs are covered by a test case. | 154 // TODO(ncbray): ensure non-null / missized structs are covered by a test case. |
130 template <typename T> bool ConvertStruct( | 155 template <typename T> bool ConvertExtensibleStructInput( |
131 struct NaClApp* nap, | 156 struct NaClApp* nap, |
132 uint32_t user_ptr, | 157 uint32_t user_ptr, |
133 bool optional, | 158 bool optional, |
134 T** sys_ptr) { | 159 T** sys_ptr) { |
135 if (user_ptr) { | 160 if (user_ptr) { |
136 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); | 161 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); |
137 if (temp != kNaClBadAddress) { | 162 if (temp != kNaClBadAddress) { |
138 *sys_ptr = reinterpret_cast<T*>(temp); | 163 *sys_ptr = reinterpret_cast<T*>(temp); |
139 return true; | 164 return true; |
140 } | 165 } |
141 } else if (optional) { | 166 } else if (optional) { |
142 *sys_ptr = 0; | 167 *sys_ptr = 0; |
143 return true; | 168 return true; |
144 } | 169 } |
145 return false; | 170 return false; |
146 } | 171 } |
147 | 172 |
148 } // namespace | 173 } // namespace |
149 | 174 |
150 #endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ | 175 #endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ |
OLD | NEW |