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 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_NACL_COPY_H_
8 : #define NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_NACL_COPY_H_
9 :
10 : #include "native_client/src/include/nacl_base.h"
11 : #include "native_client/src/include/nacl_compiler_annotations.h"
12 : #include "native_client/src/include/portability.h"
13 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
14 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
15 :
16 : EXTERN_C_BEGIN
17 :
18 : struct NaClApp;
19 :
20 : /*
21 : * NaClCopyInFromUser copies a region of memory starting at
22 : * |src_usr_addr| of length |num_bytes| to a target buffer at
23 : * |dst_sys_ptr|, which is a pointer (in kernel/system address space).
24 : * The |src_usr_addr| is in user addresses and is checked to ensure
25 : * that it resides within the user's address space. If it is not, 0
26 : * (false) is returned. Otherwise, the address is properly translated
27 : * and the copy attempted. Note that we do not (currently) check
28 : * whether the source memory region is actually mapped, so a trusted
29 : * code fault may occur. If the function returns successfully, it
30 : * returns non-zero (true). NB: the caller needs to translate failure
31 : * to -NACL_ABI_EFAULT or -NACL_ABI_EINVAL as appropriate. (In Unix,
32 : * EFAULT is for when the syscall handler immediately uses the address
33 : * and is generated by triggering the kernel fault handler.)
34 : *
35 : * NB: |src_usr_addr| should be a 32-bit quantity and typically user
36 : * addresses are stored in 32-bit variables. However, we accept an
37 : * uintptr_t since on 64-bit systems we may have relying code that
38 : * saved an user address in a 64-bit variable, and if such a value
39 : * were clobbered so that the low-order 32-bits would validate in
40 : * checks done here and elsewhere (due to the integral type narrowing)
41 : * but the high-order 32-bits are non-zero, and the relying code,
42 : * after having used the NaClCopy functions assumed that the value has
43 : * been checked and then uses it directly, then declaring the formal
44 : * parameter |src_usr_addr| as an uint32_t would not detect the error
45 : * but declaring it as uintptr_t would.
46 : */
47 : int NaClCopyInFromUser(struct NaClApp *nap,
48 : void *dst_sys_ptr,
49 : uintptr_t src_usr_addr,
50 : size_t num_bytes) NACL_WUR;
51 :
52 : int NaClCopyInFromUserAndDropLock(struct NaClApp *nap,
53 : void *dst_sys_ptr,
54 : uintptr_t src_usr_addr,
55 : size_t num_bytes) NACL_WUR;
56 :
57 : /*
58 : * Similarly to strncpy from untrusted address space to trusted
59 : * address space, except returns success/failure (bool as int) and the
60 : * destination string is always NUL terminated. If the untrusted user
61 : * address is invalid or there isn't enough space, returns 0 with
62 : * either a zero-length string in the buffer or the partially copied
63 : * (but still NUL-terminated) string in the buffer respectively.
64 : * (Former case probably would result in EFAULT, whereas the latter
65 : * case would result in ENAMETOOLONG.)
66 : *
67 : * It is an error to invoke this with dst_buffer_bytes == 0.
68 : */
69 : int NaClCopyInFromUserZStr(struct NaClApp *nap,
70 : char *dst_buffer,
71 : size_t dst_buffer_bytes,
72 : uintptr_t src_usr_addr) NACL_WUR;
73 :
74 : /*
75 : * NaClCopyOutToUser perform the reverse analogous service as
76 : * NaClCopyInFromUser.
77 : */
78 : int NaClCopyOutToUser(struct NaClApp *nap,
79 : uintptr_t dst_usr_addr,
80 : void *src_sys_ptr,
81 : size_t num_bytes) NACL_WUR;
82 :
83 : /*
84 : * We use locking to prevent reads/writes of untrusted address space
85 : * while a hole is opened up in untrusted address space.
86 : *
87 : * Address space holes only occur on Windows, so we don't need this
88 : * locking in non-Windows builds, but we enable it in non-Windows
89 : * debug builds to help with earlier detection of deadlocks during
90 : * development.
91 : */
92 : #if NACL_WINDOWS || defined(_DEBUG)
93 :
94 4368218 : static INLINE void NaClCopyTakeLock(struct NaClApp *nap) {
95 4368218 : NaClXMutexLock(&nap->mu);
96 4368218 : }
97 :
98 4266226 : static INLINE void NaClCopyDropLock(struct NaClApp *nap) {
99 4266226 : NaClXMutexUnlock(&nap->mu);
100 4266226 : }
101 :
102 : #else
103 :
104 : static INLINE void NaClCopyTakeLock(struct NaClApp *nap) {
105 : UNREFERENCED_PARAMETER(nap);
106 : }
107 :
108 : static INLINE void NaClCopyDropLock(struct NaClApp *nap) {
109 : UNREFERENCED_PARAMETER(nap);
110 : }
111 :
112 : #endif
113 :
114 : EXTERN_C_END
115 :
116 : #endif
|