1
0
mirror of https://github.com/janet-lang/janet synced 2026-06-16 01:38:49 +00:00

Fix #1752 - add sandbox flag :exit

This change makes it so top level signals in the main thread will result
in expected error codes. For spawned threads, we will default to
pthread_exit or ExitThread(-1) on Windows after a top level signal.

Using `(sandbox :exit)` will restore the old behavior where a top level
signal will just print an error and call pthread_exit leaving other
thread untouched.
This commit is contained in:
Calvin Rose
2026-05-23 06:13:27 -05:00
parent 2814fc53c2
commit 6292a69aac
5 changed files with 14 additions and 3 deletions
+8 -1
View File
@@ -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
+3 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+1
View File
@@ -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;
+1
View File
@@ -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);