diff --git a/src/core/capi.c b/src/core/capi.c index 7981a6eb..3e397721 100644 --- a/src/core/capi.c +++ b/src/core/capi.c @@ -50,11 +50,18 @@ JANET_NO_RETURN static void janet_top_level_signal(const char *msg) { JANET_TOP_LEVEL_SIGNAL(msg); #else fputs(msg, stdout); + if (!(janet_vm.sandbox_flags & JANET_SANDBOX_EXIT)) { + /* Exit is not forbidden */ + exit(EXIT_FAILURE); + } + /* If not able to signal, then select good default behavior - for single threaded programs, we have no + * choice but to exit. */ # ifdef JANET_SINGLE_THREADED - exit(-1); + exit(EXIT_FAILURE); # elif defined(JANET_WINDOWS) ExitThread(-1); # else + /* Other threads will continue as usual */ pthread_exit(NULL); # endif #endif diff --git a/src/core/corelib.c b/src/core/corelib.c index 8c39268a..93857b74 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -754,6 +754,7 @@ static const SandboxOption sandbox_options[] = { {"chroot", JANET_SANDBOX_CHROOT}, {"compile", JANET_SANDBOX_COMPILE}, {"env", JANET_SANDBOX_ENV}, + {"exit", JANET_SANDBOX_EXIT}, {"ffi", JANET_SANDBOX_FFI}, {"ffi-define", JANET_SANDBOX_FFI_DEFINE}, {"ffi-jit", JANET_SANDBOX_FFI_JIT}, @@ -784,6 +785,7 @@ JANET_CORE_FN(janet_core_sandbox, "* :chroot - disallow calling `os/posix-chroot`\n" "* :compile - disallow calling `compile`. This will disable a lot of functionality, such as `eval`.\n" "* :env - disallow reading and write env variables\n" + "* :exit - disallow calling `os/exit` or otherwise early exiting the process in trivial ways.\n" "* :ffi - disallow FFI (recommended if disabling anything else)\n" "* :ffi-define - disallow loading new FFI modules and binding new functions\n" "* :ffi-jit - disallow calling `ffi/jitfn`\n" @@ -801,7 +803,7 @@ JANET_CORE_FN(janet_core_sandbox, "* :signal - disallow adding or removing signal handlers\n" "* :subprocess - disallow running subprocesses\n" "* :threads - disallow spawning threads with `ev/thread`. Certain helper threads may still be spawned.\n" - "* :unmarshal - disallow calling the unmarshal function.\n") { + "* :unmarshal - disallow calling the `unmarshal` function.\n") { uint32_t flags = 0; for (int32_t i = 0; i < argc; i++) { JanetKeyword kw = janet_getkeyword(argv, i); diff --git a/src/core/ev.c b/src/core/ev.c index 5731bdd3..80bf486b 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -613,7 +613,7 @@ void janet_ev_init_common(void) { #if JANET_ANDROID static void janet_timeout_stop(int sig_num) { if (sig_num == SIGUSR1) { - pthread_exit(0); + pthread_exit(NULL); } } #endif diff --git a/src/core/os.c b/src/core/os.c index bc7b7bd6..c0ab59a4 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -276,6 +276,7 @@ JANET_CORE_FN(os_exit, "the exit with status equal the hash of x. If `force` is truthy will exit immediately and " "skip cleanup code.") { janet_arity(argc, 0, 2); + janet_sandbox_assert(JANET_SANDBOX_EXIT); int status; if (argc == 0) { status = EXIT_SUCCESS; diff --git a/src/include/janet.h b/src/include/janet.h index 3f2ace5f..56e8af8c 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -2024,6 +2024,7 @@ JANET_API void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *pr #define JANET_SANDBOX_ASM 65536 #define JANET_SANDBOX_THREADS 131072 #define JANET_SANDBOX_UNMARSHAL 262144 +#define JANET_SANDBOX_EXIT 524288 #define JANET_SANDBOX_ALL (UINT32_MAX) JANET_API void janet_sandbox(uint32_t flags); JANET_API void janet_sandbox_assert(uint32_t forbidden_flags);