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_MOJO_SYSCALL_INTERNAL_H_ 6 #define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ 7 8 #include "native_client/src/trusted/service_runtime/nacl_copy.h" 9 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 10 11 namespace { 12 13 class ScopedCopyLock { 14 public: 15 explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) { 16 NaClCopyTakeLock(nap_); 17 } 18 ~ScopedCopyLock() { 19 NaClCopyDropLock(nap_); 20 } 21 private: 22 struct NaClApp* nap_; 23 }; 24 25 static inline uintptr_t NaClUserToSysAddrArray( 26 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 template <typename T> bool ConvertScalarInput( 36 struct NaClApp* nap, 37 uint32_t user_ptr, 38 T* value) { 39 if (user_ptr) { 40 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 41 if (temp != kNaClBadAddress) { 42 *value = *reinterpret_cast<T volatile*>(temp); 43 return true; 44 } 45 } 46 return false; 47 } 48 49 template <typename T> bool ConvertScalarOutput( 50 struct NaClApp* nap, 51 uint32_t user_ptr, 52 T volatile** sys_ptr) { 53 if (user_ptr) { 54 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 55 if (temp != kNaClBadAddress) { 56 *sys_ptr = reinterpret_cast<T volatile*>(temp); 57 return true; 58 } 59 } 60 *sys_ptr = 0; // Paranoia. 61 return false; 62 } 63 64 template <typename T> bool ConvertScalarInOut( 65 struct NaClApp* nap, 66 uint32_t user_ptr, 67 bool optional, 68 T* value, 69 T volatile** sys_ptr) { 70 if (user_ptr) { 71 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 72 if (temp != kNaClBadAddress) { 73 T volatile* converted = reinterpret_cast<T volatile*>(temp); 74 *sys_ptr = converted; 75 *value = *converted; 76 return true; 77 } 78 } else if (optional) { 79 *sys_ptr = 0; 80 *value = static_cast<T>(0); // Paranoia. 81 return true; 82 } 83 *sys_ptr = 0; // Paranoia. 84 *value = static_cast<T>(0); // Paranoia. 85 return false; 86 } 87 88 template <typename T> bool ConvertArray( 89 struct NaClApp* nap, 90 uint32_t user_ptr, 91 uint32_t length, 92 size_t element_size, 93 bool optional, 94 T** sys_ptr) { 95 if (user_ptr) { 96 uintptr_t temp = NaClUserToSysAddrArray(nap, user_ptr, length, 97 element_size); 98 if (temp != kNaClBadAddress) { 99 *sys_ptr = reinterpret_cast<T*>(temp); 100 return true; 101 } 102 } else if (optional) { 103 *sys_ptr = 0; 104 return true; 105 } 106 return false; 107 } 108 109 template <typename T> bool ConvertBytes( 110 struct NaClApp* nap, 111 uint32_t user_ptr, 112 uint32_t length, 113 bool optional, 114 T** sys_ptr) { 115 if (user_ptr) { 116 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length); 117 if (temp != kNaClBadAddress) { 118 *sys_ptr = reinterpret_cast<T*>(temp); 119 return true; 120 } 121 } else if (optional) { 122 *sys_ptr = 0; 123 return true; 124 } 125 return false; 126 } 127 128 // TODO(ncbray): size validation and complete copy. 129 // TODO(ncbray): ensure non-null / missized structs are covered by a test case. 130 template <typename T> bool ConvertStruct( 131 struct NaClApp* nap, 132 uint32_t user_ptr, 133 bool optional, 134 T** sys_ptr) { 135 if (user_ptr) { 136 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 137 if (temp != kNaClBadAddress) { 138 *sys_ptr = reinterpret_cast<T*>(temp); 139 return true; 140 } 141 } else if (optional) { 142 *sys_ptr = 0; 143 return true; 144 } 145 return false; 146 } 147 148 } // namespace 149 150 #endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ 151