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 /* |
47 if (MinsfiGetActiveSandbox() == NULL) | 50 * Arguments are passed to the sandbox with a single pointer to an array of |
51 * integers called 'info' where: | |
52 * info[0] = argc | |
53 * info[j+1] = untrusted pointer to argv[j] (for 0 <= j < argc) | |
54 * The sandbox will expect this array to be stored at the bottom of the | |
55 * untrusted stack and will start growing the stack backwards from the given | |
56 * address. | |
57 * | |
58 * This function will iterate over the arguments, store the argv[*] strings | |
59 * at the bottom of the untrusted stack and prepend it with the 'info' data | |
60 * structure as described above. | |
61 */ | |
62 static sfiptr_t CopyArguments(int argc, char *argv[], const MinsfiSandbox *sb) { | |
63 int arg_index; | |
64 size_t arg_length, info_length; | |
65 sfiptr_t *info; | |
66 char *stack_base, *stack_ptr; | |
67 | |
68 if (argc < 0) | |
69 return 0; | |
70 | |
71 /* Allocate memory for the info data structure. */ | |
72 info_length = (argc + 1) * sizeof(sfiptr_t); | |
73 info = (sfiptr_t*) malloc(info_length); | |
74 info[0] = argc; | |
75 | |
76 /* Compute the bounds of the stack. */ | |
77 stack_base = sb->mem_base + sb->mem_layout.stack.offset; | |
78 stack_ptr = stack_base + sb->mem_layout.stack.length; | |
79 | |
80 /* Copy the argv[*] strings onto the stack. Return NULL if the stack is not | |
81 * large enough. */ | |
82 for (arg_index = 0; arg_index < argc; ++arg_index) { | |
83 arg_length = strlen(argv[arg_index]) + 1; | |
84 stack_ptr -= arg_length; | |
85 if (stack_ptr < stack_base) | |
86 return 0; | |
jvoung (off chromium)
2014/09/10 17:04:29
free(info), on early exit?
dbrazdil
2014/09/10 18:49:47
Done. Thanks
| |
87 | |
88 memcpy(stack_ptr, argv[arg_index], arg_length); | |
89 info[arg_index + 1] = ToMinsfiPtr(stack_ptr, sb); | |
90 } | |
91 | |
92 /* Copy the info data structure across. */ | |
93 stack_ptr -= info_length; | |
94 if (stack_ptr < stack_base) | |
95 return 0; | |
jvoung (off chromium)
2014/09/10 17:04:29
free(info)?
dbrazdil
2014/09/10 18:49:47
Done.
| |
96 memcpy(stack_ptr, (char*) info, info_length); | |
97 | |
98 /* Clean up. */ | |
99 free(info); | |
100 | |
101 /* Return untrusted pointer to the beginning of the data structure. */ | |
102 return ToMinsfiPtr(stack_ptr, sb); | |
103 } | |
104 | |
105 int MinsfiInvokeSandbox(int argc, char *argv[]) { | |
106 const MinsfiSandbox *sb; | |
107 sfiptr_t info; | |
108 | |
109 if ((sb = MinsfiGetActiveSandbox()) == NULL) | |
48 return EXIT_FAILURE; | 110 return EXIT_FAILURE; |
49 | 111 |
50 return _start_minsfi(0); | 112 if ((info = CopyArguments(argc, argv, sb)) == 0) |
113 return EXIT_FAILURE; | |
114 | |
115 return _start_minsfi(info); | |
51 } | 116 } |
52 | 117 |
53 bool MinsfiDestroySandbox(void) { | 118 bool MinsfiDestroySandbox(void) { |
54 const MinsfiSandbox *sb; | 119 const MinsfiSandbox *sb; |
55 | 120 |
56 if ((sb = MinsfiGetActiveSandbox()) == NULL) | 121 if ((sb = MinsfiGetActiveSandbox()) == NULL) |
57 return true; | 122 return true; |
58 | 123 |
59 if (MinsfiUnmapSandbox(sb)) { | 124 if (MinsfiUnmapSandbox(sb)) { |
60 MinsfiSetActiveSandbox(NULL); | 125 MinsfiSetActiveSandbox(NULL); |
61 return true; | 126 return true; |
62 } | 127 } |
63 | 128 |
64 return false; | 129 return false; |
65 } | 130 } |
OLD | NEW |