OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 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 | 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 /* | 7 /* |
8 * NaCl Simple/secure ELF loader (NaCl SEL). | 8 * NaCl Simple/secure ELF loader (NaCl SEL). |
9 */ | 9 */ |
10 #include "native_client/src/include/build_config.h" | 10 #include "native_client/src/include/build_config.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 /* NOTREACHED */ | 120 /* NOTREACHED */ |
121 } | 121 } |
122 | 122 |
123 static void PrintUsage(void) { | 123 static void PrintUsage(void) { |
124 /* NOTE: this is broken up into multiple statements to work around | 124 /* NOTE: this is broken up into multiple statements to work around |
125 the constant string size limit */ | 125 the constant string size limit */ |
126 fprintf(stderr, | 126 fprintf(stderr, |
127 "Usage: sel_ldr [-h d:D] [-r d:D] [-w d:D] [-i d:D]\n" | 127 "Usage: sel_ldr [-h d:D] [-r d:D] [-w d:D] [-i d:D]\n" |
128 " [-f nacl_file]\n" | 128 " [-f nacl_file]\n" |
129 " [-l log_file]\n" | 129 " [-l log_file]\n" |
| 130 " [-m fs_root]\n" |
130 " [-X d] [-acFglQRsSQv]\n" | 131 " [-X d] [-acFglQRsSQv]\n" |
131 " -- [nacl_file] [args]\n" | 132 " -- [nacl_file] [args]\n" |
132 "\n"); | 133 "\n"); |
133 fprintf(stderr, | 134 fprintf(stderr, |
134 " -h\n" | 135 " -h\n" |
135 " -r\n" | 136 " -r\n" |
136 " -w associate a host POSIX descriptor D with app desc d\n" | 137 " -w associate a host POSIX descriptor D with app desc d\n" |
137 " that was opened in O_RDWR, O_RDONLY, and O_WRONLY modes\n" | 138 " that was opened in O_RDWR, O_RDONLY, and O_WRONLY modes\n" |
138 " respectively\n" | 139 " respectively\n" |
139 " -i associates an IMC handle D with app desc d\n" | 140 " -i associates an IMC handle D with app desc d\n" |
140 " -f file to load; if omitted, 1st arg after \"--\" is loaded\n" | 141 " -f file to load; if omitted, 1st arg after \"--\" is loaded\n" |
141 " -B additional ELF file to load as a blob library\n" | 142 " -B additional ELF file to load as a blob library\n" |
142 " -v increases verbosity\n" | 143 " -v increases verbosity\n" |
143 " -e enable hardware exception handling\n" | 144 " -e enable hardware exception handling\n" |
144 " -X create a bound socket and export the address via an\n" | 145 " -X create a bound socket and export the address via an\n" |
145 " IMC message to a corresponding inherited IMC app descriptor\n" | 146 " IMC message to a corresponding inherited IMC app descriptor\n" |
146 " (use -1 to create the bound socket / address descriptor\n" | 147 " (use -1 to create the bound socket / address descriptor\n" |
147 " pair, but that no export via IMC should occur)\n" | 148 " pair, but that no export via IMC should occur)\n" |
148 " -E <name=value>|<name> set an environment variable\n" | 149 " -E <name=value>|<name> set an environment variable\n" |
149 " -p pass through all environment variables\n"); | 150 " -p pass through all environment variables\n"); |
150 fprintf(stderr, | 151 fprintf(stderr, |
151 " -R an RPC supplies the NaCl module.\n" | 152 " -R an RPC supplies the NaCl module.\n" |
152 " No nacl_file argument is expected, and the -f flag cannot be\n" | 153 " No nacl_file argument is expected, and the -f flag cannot be\n" |
153 " used with this flag.\n" | 154 " used with this flag.\n" |
| 155 " -m directory to mount as root.\n" |
| 156 " If not provided (and -a is also missing), no filesystem access\n" |
| 157 " of any kind is allowed. If provided, safely allows read/write\n" |
| 158 " access to just the provided folder as if it were the FS root.\n" |
| 159 " If read-only access is desired, setting appropriate " |
| 160 " filesystem-level permissions for the user sel_ldr runs as\n" |
| 161 " should be adequate. If both -m and -a are passed, -m behavior\n" |
| 162 " supersedes -a for filesystem operations.\n" |
154 "\n" | 163 "\n" |
155 " (testing flags)\n" | 164 " (testing flags)\n" |
156 " -a allow file access plus some other syscalls! dangerous!\n" | 165 " -a allow file access plus some other syscalls! dangerous!\n" |
157 " -c ignore validator! dangerous! Repeating this option twice skips\n" | 166 " -c ignore validator! dangerous! Repeating this option twice skips\n" |
158 " validation completely.\n" | 167 " validation completely.\n" |
159 " -F fuzz testing; quit after loading NaCl app\n" | 168 " -F fuzz testing; quit after loading NaCl app\n" |
160 " -g enable gdb debug stub. Not secure on x86-64 Windows.\n" | 169 " -g enable gdb debug stub. Not secure on x86-64 Windows.\n" |
161 " -l <file> write log output to the given file\n" | 170 " -l <file> write log output to the given file\n" |
162 " -q quiet; suppress diagnostic/warning messages at startup\n" | 171 " -q quiet; suppress diagnostic/warning messages at startup\n" |
163 " -Q disable platform qualification (dangerous!)\n" | 172 " -Q disable platform qualification (dangerous!)\n" |
(...skipping 15 matching lines...) Expand all Loading... |
179 static int my_getopt(int argc, char *const *argv, const char *shortopts) { | 188 static int my_getopt(int argc, char *const *argv, const char *shortopts) { |
180 return getopt_long(argc, argv, shortopts, longopts, NULL); | 189 return getopt_long(argc, argv, shortopts, longopts, NULL); |
181 } | 190 } |
182 #else | 191 #else |
183 #define my_getopt getopt | 192 #define my_getopt getopt |
184 #endif | 193 #endif |
185 | 194 |
186 struct SelLdrOptions { | 195 struct SelLdrOptions { |
187 char *nacl_file; | 196 char *nacl_file; |
188 char *blob_library_file; | 197 char *blob_library_file; |
| 198 char *root_mount; |
189 int app_argc; | 199 int app_argc; |
190 char **app_argv; | 200 char **app_argv; |
191 | 201 |
192 int quiet; | 202 int quiet; |
193 int verbosity; | 203 int verbosity; |
194 int fuzzing_quit_after_load; | 204 int fuzzing_quit_after_load; |
195 int skip_qualification; | 205 int skip_qualification; |
196 int handle_signals; | 206 int handle_signals; |
197 int enable_env_passthrough; | 207 int enable_env_passthrough; |
198 int enable_exception_handling; | 208 int enable_exception_handling; |
199 int enable_debug_stub; | 209 int enable_debug_stub; |
200 int rpc_supplies_nexe; | 210 int rpc_supplies_nexe; |
201 int export_addr_to; | 211 int export_addr_to; |
202 int debug_mode_bypass_acl_checks; | 212 int debug_mode_bypass_acl_checks; |
203 int debug_mode_ignore_validator; | 213 int debug_mode_ignore_validator; |
204 int debug_mode_startup_signal; | 214 int debug_mode_startup_signal; |
205 struct redir *redir_queue; | 215 struct redir *redir_queue; |
206 struct redir **redir_qend; | 216 struct redir **redir_qend; |
207 }; | 217 }; |
208 | 218 |
209 static void SelLdrOptionsCtor(struct SelLdrOptions *options) { | 219 static void SelLdrOptionsCtor(struct SelLdrOptions *options) { |
210 /* Just to be safe. */ | 220 /* Just to be safe. */ |
211 memset(options, 0, sizeof(*options)); | 221 memset(options, 0, sizeof(*options)); |
212 | 222 |
213 options->nacl_file = NULL; | 223 options->nacl_file = NULL; |
214 options->blob_library_file = NULL; | 224 options->blob_library_file = NULL; |
| 225 options->root_mount = NULL; |
215 options->app_argc = 0; | 226 options->app_argc = 0; |
216 options->app_argv = NULL; | 227 options->app_argv = NULL; |
217 | 228 |
218 options->quiet = 0; | 229 options->quiet = 0; |
219 options->verbosity = 0; | 230 options->verbosity = 0; |
220 options->fuzzing_quit_after_load = 0; | 231 options->fuzzing_quit_after_load = 0; |
221 options->skip_qualification = 0; | 232 options->skip_qualification = 0; |
222 options->handle_signals = 0; | 233 options->handle_signals = 0; |
223 options->enable_env_passthrough = 0; | 234 options->enable_env_passthrough = 0; |
224 options->enable_exception_handling = 0; | 235 options->enable_exception_handling = 0; |
(...skipping 27 matching lines...) Expand all Loading... |
252 * sel_ldr foo.nexe -vvv | 263 * sel_ldr foo.nexe -vvv |
253 * | 264 * |
254 * the -vvv flags are made available to the nexe, rather than being | 265 * the -vvv flags are made available to the nexe, rather than being |
255 * consumed by getopt. This makes the behavior of the Linux build | 266 * consumed by getopt. This makes the behavior of the Linux build |
256 * of sel_ldr consistent with the Windows and OSX builds. | 267 * of sel_ldr consistent with the Windows and OSX builds. |
257 */ | 268 */ |
258 while ((opt = my_getopt(argc, argv, | 269 while ((opt = my_getopt(argc, argv, |
259 #if NACL_LINUX | 270 #if NACL_LINUX |
260 "+D:z:" | 271 "+D:z:" |
261 #endif | 272 #endif |
262 "aB:cdeE:f:Fgh:i:l:pqQr:RsSvw:X:Z")) != -1) { | 273 "aB:cdeE:f:Fgh:i:l:m:pqQr:RsSvw:X:Z")) != -1) { |
263 switch (opt) { | 274 switch (opt) { |
264 case 'a': | 275 case 'a': |
265 if (!options->quiet) | 276 if (!options->quiet) |
266 fprintf(stderr, "DEBUG MODE ENABLED (bypass acl)\n"); | 277 fprintf(stderr, "DEBUG MODE ENABLED (bypass acl)\n"); |
267 options->debug_mode_bypass_acl_checks = 1; | 278 options->debug_mode_bypass_acl_checks = 1; |
268 break; | 279 break; |
269 case 'B': | 280 case 'B': |
270 options->blob_library_file = optarg; | 281 options->blob_library_file = optarg; |
271 break; | 282 break; |
272 case 'c': | 283 case 'c': |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 if (NULL != optarg) { | 356 if (NULL != optarg) { |
346 /* | 357 /* |
347 * change stdout/stderr to log file now, so that subsequent error | 358 * change stdout/stderr to log file now, so that subsequent error |
348 * messages will go there. unfortunately, error messages that | 359 * messages will go there. unfortunately, error messages that |
349 * result from getopt processing -- usually out-of-memory, which | 360 * result from getopt processing -- usually out-of-memory, which |
350 * shouldn't happen -- won't show up. | 361 * shouldn't happen -- won't show up. |
351 */ | 362 */ |
352 NaClLogSetFile(optarg); | 363 NaClLogSetFile(optarg); |
353 } | 364 } |
354 break; | 365 break; |
| 366 case 'm': |
| 367 options->root_mount = optarg; |
| 368 break; |
355 case 'p': | 369 case 'p': |
356 options->enable_env_passthrough = 1; | 370 options->enable_env_passthrough = 1; |
357 break; | 371 break; |
358 case 'q': | 372 case 'q': |
359 options->quiet = 1; | 373 options->quiet = 1; |
360 break; | 374 break; |
361 case 'Q': | 375 case 'Q': |
362 if (!options->quiet) | 376 if (!options->quiet) |
363 fprintf(stderr, "PLATFORM QUALIFICATION DISABLED BY -Q - " | 377 fprintf(stderr, "PLATFORM QUALIFICATION DISABLED BY -Q - " |
364 "Native Client's sandbox will be unreliable!\n"); | 378 "Native Client's sandbox will be unreliable!\n"); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 */ | 608 */ |
595 NaClLog(LOG_ERROR, "DEBUG taking startup signal (SIGCONT) now\n"); | 609 NaClLog(LOG_ERROR, "DEBUG taking startup signal (SIGCONT) now\n"); |
596 raise(SIGCONT); | 610 raise(SIGCONT); |
597 #endif | 611 #endif |
598 } | 612 } |
599 | 613 |
600 if (options->debug_mode_bypass_acl_checks) { | 614 if (options->debug_mode_bypass_acl_checks) { |
601 NaClInsecurelyBypassAllAclChecks(); | 615 NaClInsecurelyBypassAllAclChecks(); |
602 } | 616 } |
603 | 617 |
| 618 if (options->root_mount != NULL) { |
| 619 if (!NaClMountRootDir(options->root_mount)) { |
| 620 NaClLog(LOG_ERROR, "Failed to mount root dir " |
| 621 "(not supported on Windows)\n"); |
| 622 return -1; |
| 623 } |
| 624 } |
| 625 |
604 nap->ignore_validator_result = (options->debug_mode_ignore_validator > 0); | 626 nap->ignore_validator_result = (options->debug_mode_ignore_validator > 0); |
605 nap->skip_validator = (options->debug_mode_ignore_validator > 1); | 627 nap->skip_validator = (options->debug_mode_ignore_validator > 1); |
606 nap->enable_exception_handling = options->enable_exception_handling; | 628 nap->enable_exception_handling = options->enable_exception_handling; |
607 | 629 |
608 /* | 630 /* |
609 * TODO(mseaborn): Always enable the Mach exception handler on Mac | 631 * TODO(mseaborn): Always enable the Mach exception handler on Mac |
610 * OS X, and remove handle_signals and sel_ldr's "-S" option. | 632 * OS X, and remove handle_signals and sel_ldr's "-S" option. |
611 */ | 633 */ |
612 if (nap->enable_exception_handling || options->enable_debug_stub || | 634 if (nap->enable_exception_handling || options->enable_debug_stub || |
613 (options->handle_signals && NACL_OSX)) { | 635 (options->handle_signals && NACL_OSX)) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 * possible. | 797 * possible. |
776 * | 798 * |
777 * This must come after NaClWaitForLoadModuleCommand(), which waits | 799 * This must come after NaClWaitForLoadModuleCommand(), which waits |
778 * for another thread to have called NaClAppLoadFile(). | 800 * for another thread to have called NaClAppLoadFile(). |
779 * NaClAppLoadFile() does not work inside the Mac outer sandbox in | 801 * NaClAppLoadFile() does not work inside the Mac outer sandbox in |
780 * standalone sel_ldr when using a dynamic code area because it uses | 802 * standalone sel_ldr when using a dynamic code area because it uses |
781 * NaClCreateMemoryObject() which opens a file in /tmp. | 803 * NaClCreateMemoryObject() which opens a file in /tmp. |
782 * | 804 * |
783 * We cannot enable the sandbox if file access is enabled. | 805 * We cannot enable the sandbox if file access is enabled. |
784 */ | 806 */ |
785 if (!NaClAclBypassChecks && g_enable_outer_sandbox_func != NULL) { | 807 if (!NaClFileAccessEnabled() && g_enable_outer_sandbox_func != NULL) { |
786 g_enable_outer_sandbox_func(); | 808 g_enable_outer_sandbox_func(); |
787 } | 809 } |
788 | 810 |
789 if (NULL != options->blob_library_file) { | 811 if (NULL != options->blob_library_file) { |
790 if (LOAD_OK == errcode) { | 812 if (LOAD_OK == errcode) { |
791 errcode = NaClMainLoadIrt(nap, blob_file, NULL); | 813 errcode = NaClMainLoadIrt(nap, blob_file, NULL); |
792 if (LOAD_OK != errcode) { | 814 if (LOAD_OK != errcode) { |
793 NaClLog(LOG_ERROR, "Error while loading \"%s\": %s\n", | 815 NaClLog(LOG_ERROR, "Error while loading \"%s\": %s\n", |
794 options->blob_library_file, | 816 options->blob_library_file, |
795 NaClErrorString(errcode)); | 817 NaClErrorString(errcode)); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 #if NACL_LINUX | 925 #if NACL_LINUX |
904 NaClSignalHandlerFini(); | 926 NaClSignalHandlerFini(); |
905 #endif | 927 #endif |
906 NaClAllModulesFini(); | 928 NaClAllModulesFini(); |
907 | 929 |
908 NaClExit(ret_code); | 930 NaClExit(ret_code); |
909 | 931 |
910 /* Unreachable, but having the return prevents a compiler error. */ | 932 /* Unreachable, but having the return prevents a compiler error. */ |
911 return ret_code; | 933 return ret_code; |
912 } | 934 } |
OLD | NEW |