diff --git a/src/core/corelib.c b/src/core/corelib.c index b30a4a2c..4f2b5237 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -746,6 +746,7 @@ typedef struct SandboxOption { static const SandboxOption sandbox_options[] = { {"all", JANET_SANDBOX_ALL}, + {"chroot", JANET_SANDBOX_CHROOT}, {"env", JANET_SANDBOX_ENV}, {"ffi", JANET_SANDBOX_FFI}, {"ffi-define", JANET_SANDBOX_FFI_DEFINE}, @@ -771,6 +772,7 @@ JANET_CORE_FN(janet_core_sandbox, "Disable feature sets to prevent the interpreter from using certain system resources. " "Once a feature is disabled, there is no way to re-enable it. Capabilities can be:\n\n" "* :all - disallow all (except IO to stdout, stderr, and stdin)\n" + "* :chroot - disallow calling `os/posix-chroot`\n" "* :env - disallow reading and write env variables\n" "* :ffi - disallow FFI (recommended if disabling anything else)\n" "* :ffi-define - disallow loading new FFI modules and binding new functions\n" diff --git a/src/core/os.c b/src/core/os.c index 2e638775..6a06efa7 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -1541,6 +1541,27 @@ JANET_CORE_FN(os_posix_fork, #endif } +JANET_CORE_FN(os_posix_chroot, + "(os/posix-chroot dirname)", + "Call `chroot` to change the root directory to `dirname`. " + "Not supported on all systems (POSIX only).") { + janet_sandbox_assert(JANET_SANDBOX_CHROOT); + janet_fixarity(argc, 1); +#ifdef JANET_WINDOWS + janet_panic("not supported on Windows"); +#else + const char *root = janet_getcstring(argv, 0); + int result; + do { + result = chroot(root); + } while (result == -1 && errno == EINTR); + if (result == -1) { + janet_panic(janet_strerror(errno)); + } + return janet_wrap_nil(); +#endif +} + #ifdef JANET_EV /* Runs in a separate thread */ static JanetEVGenericMessage os_shell_subr(JanetEVGenericMessage args) { @@ -2849,6 +2870,7 @@ void janet_lib_os(JanetTable *env) { JANET_CORE_REG("os/touch", os_touch), JANET_CORE_REG("os/realpath", os_realpath), JANET_CORE_REG("os/cd", os_cd), + JANET_CORE_REG("os/posix-chroot", os_posix_chroot), #ifndef JANET_NO_UMASK JANET_CORE_REG("os/umask", os_umask), #endif diff --git a/src/include/janet.h b/src/include/janet.h index 729adc44..2084418a 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1899,6 +1899,7 @@ JANET_API void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *pr #define JANET_SANDBOX_FFI_USE 2048 #define JANET_SANDBOX_FFI_JIT 4096 #define JANET_SANDBOX_SIGNAL 8192 +#define JANET_SANDBOX_CHROOT 16384 #define JANET_SANDBOX_FFI (JANET_SANDBOX_FFI_DEFINE | JANET_SANDBOX_FFI_USE | JANET_SANDBOX_FFI_JIT) #define JANET_SANDBOX_FS (JANET_SANDBOX_FS_WRITE | JANET_SANDBOX_FS_READ | JANET_SANDBOX_FS_TEMP) #define JANET_SANDBOX_NET (JANET_SANDBOX_NET_CONNECT | JANET_SANDBOX_NET_LISTEN)