| 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 |