OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
| 7 #include <string.h> |
| 8 |
7 #include "native_client/src/include/minsfi.h" | 9 #include "native_client/src/include/minsfi.h" |
8 #include "native_client/src/include/minsfi_priv.h" | 10 #include "native_client/src/include/minsfi_priv.h" |
| 11 #include "native_client/src/include/minsfi_ptr.h" |
9 | 12 |
10 /* | 13 /* |
11 * Fixed offset of the data segment. This must be kept in sync with the | 14 * Fixed offset of the data segment. This must be kept in sync with the |
12 * AllocateDataSegment compiler pass. | 15 * AllocateDataSegment compiler pass. |
13 */ | 16 */ |
14 #define DATASEG_OFFSET 0x10000 | 17 #define DATASEG_OFFSET 0x10000 |
15 | 18 |
16 /* Globals exported by the sandbox, aka the manifest. */ | 19 /* Globals exported by the sandbox, aka the manifest. */ |
17 extern uint32_t __sfi_pointer_size; | 20 extern uint32_t __sfi_pointer_size; |
18 extern const char __sfi_data_segment[]; | 21 extern const char __sfi_data_segment[]; |
19 extern uint32_t __sfi_data_segment_size; | 22 extern uint32_t __sfi_data_segment_size; |
20 | 23 |
21 /* Entry point of the sandbox */ | 24 /* Entry point of the sandbox */ |
22 extern uint32_t _start_minsfi(uint32_t info); | 25 extern uint32_t _start_minsfi(sfiptr_t info); |
23 | 26 |
24 static inline void GetManifest(MinsfiManifest *sb) { | 27 static inline void GetManifest(MinsfiManifest *sb) { |
25 sb->ptr_size = __sfi_pointer_size; | 28 sb->ptr_size = __sfi_pointer_size; |
26 sb->dataseg_offset = DATASEG_OFFSET; | 29 sb->dataseg_offset = DATASEG_OFFSET; |
27 sb->dataseg_size = __sfi_data_segment_size; | 30 sb->dataseg_size = __sfi_data_segment_size; |
28 sb->dataseg_template = __sfi_data_segment; | 31 sb->dataseg_template = __sfi_data_segment; |
29 } | 32 } |
30 | 33 |
31 bool MinsfiInitializeSandbox(void) { | 34 bool MinsfiInitializeSandbox(void) { |
32 MinsfiManifest manifest; | 35 MinsfiManifest manifest; |
33 MinsfiSandbox sb; | 36 MinsfiSandbox sb; |
34 | 37 |
35 if (MinsfiGetActiveSandbox() != NULL) | 38 if (MinsfiGetActiveSandbox() != NULL) |
36 return true; | 39 return true; |
37 | 40 |
38 GetManifest(&manifest); | 41 GetManifest(&manifest); |
39 if (!MinsfiInitSandbox(&manifest, &sb)) | 42 if (!MinsfiInitSandbox(&manifest, &sb)) |
40 return false; | 43 return false; |
41 | 44 |
42 MinsfiSetActiveSandbox(&sb); | 45 MinsfiSetActiveSandbox(&sb); |
43 return true; | 46 return true; |
44 } | 47 } |
45 | 48 |
46 int MinsfiInvokeSandbox(void) { | 49 sfiptr_t MinsfiCopyArguments(int argc, char *argv[], const MinsfiSandbox *sb) { |
47 if (MinsfiGetActiveSandbox() == NULL) | 50 int arg_index; |
| 51 size_t arg_length, info_length; |
| 52 sfiptr_t *info; |
| 53 char *stack_base, *stack_ptr; |
| 54 |
| 55 if (argc < 0) |
| 56 return 0; |
| 57 |
| 58 /* Allocate memory for the info data structure. */ |
| 59 info_length = (argc + 1) * sizeof(sfiptr_t); |
| 60 info = (sfiptr_t*) malloc(info_length); |
| 61 info[0] = argc; |
| 62 |
| 63 /* Compute the bounds of the stack. */ |
| 64 stack_base = sb->mem_base + sb->mem_layout.stack.offset; |
| 65 stack_ptr = stack_base + sb->mem_layout.stack.length; |
| 66 |
| 67 /* Copy the argv[*] strings onto the stack. Return NULL if the stack is not |
| 68 * large enough. */ |
| 69 for (arg_index = 0; arg_index < argc; ++arg_index) { |
| 70 arg_length = strlen(argv[arg_index]) + 1; |
| 71 stack_ptr -= arg_length; |
| 72 if (stack_ptr < stack_base) { |
| 73 free(info); |
| 74 return 0; |
| 75 } |
| 76 |
| 77 memcpy(stack_ptr, argv[arg_index], arg_length); |
| 78 info[arg_index + 1] = ToMinsfiPtr(stack_ptr, sb); |
| 79 } |
| 80 |
| 81 /* Copy the info data structure across. */ |
| 82 stack_ptr -= info_length; |
| 83 if (stack_ptr < stack_base) { |
| 84 free(info); |
| 85 return 0; |
| 86 } |
| 87 memcpy(stack_ptr, (char*) info, info_length); |
| 88 |
| 89 /* Clean up. */ |
| 90 free(info); |
| 91 |
| 92 /* Return untrusted pointer to the beginning of the data structure. */ |
| 93 return ToMinsfiPtr(stack_ptr, sb); |
| 94 } |
| 95 |
| 96 int MinsfiInvokeSandbox(int argc, char *argv[]) { |
| 97 const MinsfiSandbox *sb; |
| 98 sfiptr_t info; |
| 99 |
| 100 if ((sb = MinsfiGetActiveSandbox()) == NULL) |
48 return EXIT_FAILURE; | 101 return EXIT_FAILURE; |
49 | 102 |
50 return _start_minsfi(0); | 103 if ((info = MinsfiCopyArguments(argc, argv, sb)) == 0) |
| 104 return EXIT_FAILURE; |
| 105 |
| 106 return _start_minsfi(info); |
51 } | 107 } |
52 | 108 |
53 bool MinsfiDestroySandbox(void) { | 109 bool MinsfiDestroySandbox(void) { |
54 const MinsfiSandbox *sb; | 110 const MinsfiSandbox *sb; |
55 | 111 |
56 if ((sb = MinsfiGetActiveSandbox()) == NULL) | 112 if ((sb = MinsfiGetActiveSandbox()) == NULL) |
57 return true; | 113 return true; |
58 | 114 |
59 if (MinsfiUnmapSandbox(sb)) { | 115 if (MinsfiUnmapSandbox(sb)) { |
60 MinsfiSetActiveSandbox(NULL); | 116 MinsfiSetActiveSandbox(NULL); |
61 return true; | 117 return true; |
62 } | 118 } |
63 | 119 |
64 return false; | 120 return false; |
65 } | 121 } |
OLD | NEW |