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 #include <string.h>
8 
9 #if defined(MEMORY_SANITIZER)
10 #include <sanitizer/msan_interface.h>
11 #endif
12 
13 #include "native_client/src/trusted/service_runtime/nacl_copy.h"
14 
15 #include "native_client/src/shared/platform/nacl_check.h"
16 #include "native_client/src/shared/platform/nacl_sync_checked.h"
17 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
18 
NaClCopyInFromUser(struct NaClApp * nap,void * dst_sys_ptr,uintptr_t src_usr_addr,size_t num_bytes)19 int NaClCopyInFromUser(struct NaClApp *nap,
20                        void           *dst_sys_ptr,
21                        uintptr_t      src_usr_addr,
22                        size_t         num_bytes) {
23   uintptr_t src_sys_addr;
24 
25   src_sys_addr = NaClUserToSysAddrRange(nap, src_usr_addr, num_bytes);
26   if (kNaClBadAddress == src_sys_addr) {
27     return 0;
28   }
29   NaClCopyTakeLock(nap);
30   memcpy((void *) dst_sys_ptr, (void *) src_sys_addr, num_bytes);
31   NaClCopyDropLock(nap);
32 
33   return 1;
34 }
35 
NaClCopyInFromUserAndDropLock(struct NaClApp * nap,void * dst_sys_ptr,uintptr_t src_usr_addr,size_t num_bytes)36 int NaClCopyInFromUserAndDropLock(struct NaClApp *nap,
37                                   void           *dst_sys_ptr,
38                                   uintptr_t      src_usr_addr,
39                                   size_t         num_bytes) {
40   uintptr_t src_sys_addr;
41 
42   src_sys_addr = NaClUserToSysAddrRange(nap, src_usr_addr, num_bytes);
43   if (kNaClBadAddress == src_sys_addr) {
44     return 0;
45   }
46 
47   memcpy((void *) dst_sys_ptr, (void *) src_sys_addr, num_bytes);
48   NaClCopyDropLock(nap);
49 
50   return 1;
51 }
52 
NaClCopyInFromUserZStr(struct NaClApp * nap,char * dst_buffer,size_t dst_buffer_bytes,uintptr_t src_usr_addr)53 int NaClCopyInFromUserZStr(struct NaClApp *nap,
54                            char           *dst_buffer,
55                            size_t         dst_buffer_bytes,
56                            uintptr_t      src_usr_addr) {
57   uintptr_t src_sys_addr;
58 
59   CHECK(dst_buffer_bytes > 0);
60   src_sys_addr = NaClUserToSysAddr(nap, src_usr_addr);
61   if (kNaClBadAddress == src_sys_addr) {
62     dst_buffer[0] = '\0';
63     return 0;
64   }
65   NaClCopyTakeLock(nap);
66   strncpy(dst_buffer, (char *) src_sys_addr, dst_buffer_bytes);
67   NaClCopyDropLock(nap);
68 
69   /* POSIX strncpy pads with NUL characters */
70   if (dst_buffer[dst_buffer_bytes - 1] != '\0') {
71     dst_buffer[dst_buffer_bytes - 1] = '\0';
72     return 0;
73   }
74   return 1;
75 }
76 
77 
NaClCopyOutToUser(struct NaClApp * nap,uintptr_t dst_usr_addr,const void * src_sys_ptr,size_t num_bytes)78 int NaClCopyOutToUser(struct NaClApp  *nap,
79                       uintptr_t       dst_usr_addr,
80                       const void      *src_sys_ptr,
81                       size_t          num_bytes) {
82   uintptr_t dst_sys_addr;
83 
84   dst_sys_addr = NaClUserToSysAddrRange(nap, dst_usr_addr, num_bytes);
85   if (kNaClBadAddress == dst_sys_addr) {
86     return 0;
87   }
88 
89 #if defined(MEMORY_SANITIZER)
90   /*
91    * Make sure we don't leak information into the sandbox by copying
92    * uninitialized values.
93    */
94   __msan_check_mem_is_initialized(src_sys_ptr, num_bytes);
95 #endif
96 
97   NaClCopyTakeLock(nap);
98   memcpy((void *) dst_sys_addr, src_sys_ptr, num_bytes);
99   NaClCopyDropLock(nap);
100 
101   return 1;
102 }
103