From dca48fae3613b99de69a57200a536030fd28ce9c Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 17 Feb 2024 14:55:39 +0000 Subject: [PATCH] Some test fixes, and introduce some pledge and unveil for OpenBSD. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4851 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- src/main.c | 15 +++++++++++++++ src/task.c | 10 ++++++++++ src/tests.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 9d745954..ee1809a9 100644 --- a/src/main.c +++ b/src/main.c @@ -395,6 +395,21 @@ static void _shed_privileges() } #endif #endif + +#if defined(__OpenBSD__) + /* How do I unveil nothing? */ + if (unveil("/dev/null", "r") || + unveil(NULL, NULL)) + { + perror("unveil"); + exit(-1); + } + if (pledge("stdio unveil", NULL)) + { + perror("pledge"); + exit(-1); + } +#endif } static int _tf_command_run(const char* file, int argc, char* argv[]) diff --git a/src/task.c b/src/task.c index 98a7cdbd..65806f85 100644 --- a/src/task.c +++ b/src/task.c @@ -193,6 +193,7 @@ static bool _export_record_release(tf_task_t* task, export_record_t** export) } static JSValue _tf_task_setTimeout(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +static JSValue _tf_task_pokeSandbox(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id); static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promiseId, exportid_t exportId, JSValue result); static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name); @@ -1769,6 +1770,7 @@ void tf_task_activate(tf_task_t* task) JS_SetPropertyStr(context, global, "platform", JS_NewCFunction(context, _tf_task_platform, "platform", 0)); JS_SetPropertyStr(context, global, "getFile", JS_NewCFunction(context, _tf_task_getFile, "getFile", 1)); JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _tf_task_setTimeout, "setTimeout", 2)); + JS_SetPropertyStr(context, global, "pokeSandbox", JS_NewCFunction(context, _tf_task_pokeSandbox, "pokeSandbox", 0)); JS_FreeValue(context, global); } @@ -2129,3 +2131,11 @@ static JSValue _tf_task_setTimeout(JSContext* context, JSValueConst this_val, in } return JS_NULL; } + +static JSValue _tf_task_pokeSandbox(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_printf("Poking sandbox.\n"); + system("pwd"); + tf_printf("Sandbox poked.\n"); + return JS_UNDEFINED; +} diff --git a/src/tests.c b/src/tests.c index 8b8c3978..92e8ba2c 100644 --- a/src/tests.c +++ b/src/tests.c @@ -34,7 +34,7 @@ #if !TARGET_OS_IPHONE static void _write_file(const char* path, const char* contents) { - FILE* file = fopen("out/test.js", "w"); + FILE* file = fopen(path, "w"); if (!file) { printf("Unable to write %s: %s.\n", path, strerror(errno)); @@ -58,12 +58,48 @@ static void _test_nop(const tf_test_options_t* options) assert(WEXITSTATUS(result) == 0); } +static void _test_sandbox(const tf_test_options_t* options) +{ + _write_file("out/test.js", + "var task = new Task();\n" + "task.onExit = function(code, signal) {\n" + " print('child exited', code, signal);\n" + " if (code === 0 && signal === 0) {\n" + " exit(1);\n" + " }\n" + "};\n" + "task.activate();\n" + "File.readFile('out/child.js').then(function(data) {\n" + " task.execute({name: 'child.js', source: utf8Decode(data)}).then(function() {\n" + " print('child started');\n" + " });\n" + "});"); + + _write_file("out/child.js", + "print('Poking the sandbox. This should fail.');\n" + "pokeSandbox();\n" + "print('We poked the sandbox without failing.');\n" + "exit(0);\n"); + + char command[256]; + snprintf(command, sizeof(command), "%s run --db-path=:memory: -s out/test.js" TEST_ARGS, options->exe_path); + tf_printf("%s\n", command); + int result = system(command); + (void)result; + assert(WIFEXITED(result)); + assert(WEXITSTATUS(result) == 0); + + unlink("out/test.js"); + unlink("out/child.js"); +} + static void _test_child(const tf_test_options_t* options) { _write_file("out/test.js", "var task = new Task();\n" - "task.onExit = function() {\n" - " print('child exited');\n" + "task.onExit = function(code, signal) {\n" + " print('child exited', code, signal);\n" + " exit(code || signal);\n" "};\n" "task.activate();\n" "File.readFile('out/child.js').then(function(data) {\n" @@ -846,6 +882,7 @@ void tf_tests(const tf_test_options_t* options) _tf_test_run(options, "ssb_id", tf_ssb_test_id_conversion, false); _tf_test_run(options, "ssb_following", tf_ssb_test_following, false); _tf_test_run(options, "nop", _test_nop, false); + _tf_test_run(options, "sandbox", _test_sandbox, false); _tf_test_run(options, "child", _test_child, false); _tf_test_run(options, "promise", _test_promise, false); _tf_test_run(options, "promise_remote_throw", _test_promise_remote_throw, false);