From 2b47f763086cba3369a928c8e9d9d9543b844e37 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 7 Mar 2022 21:57:11 -0800 Subject: [PATCH] just always temp files to be created Implication: os.rename now needs to be sandboxed. Hopefully it's tractable to treat it as conceptually identical to opening two files. --- src/file.lua | 2 +- src/kilo.c | 4 ---- src/liolib.c | 4 +++- src/loslib.c | 15 +++++++++++++++ src/teliva.c | 8 ++++---- src/teliva.h | 3 +++ 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/file.lua b/src/file.lua index 17e543c..81fe68d 100644 --- a/src/file.lua +++ b/src/file.lua @@ -44,7 +44,7 @@ function temporary_filename_in_same_volume(filename) -- so that a future rename works local i = 1 while true do - temporary_filename = 'teliva_temp_'..filename..'_'..i + temporary_filename = 'teliva_tmp_'..filename..'_'..i if io.open(temporary_filename) == nil then -- file doesn't exist yet; create a placeholder and return it local handle = io.open(temporary_filename, 'w') diff --git a/src/kilo.c b/src/kilo.c index da58368..0f652cf 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -167,10 +167,6 @@ static int is_separator(int c) { return c == '\0' || isspace(c) || strchr(",.()+-/*=~%[];",c) != NULL; } -static int starts_with(const char* s, const char* prefix) { - return strncmp(prefix, s, strlen(prefix)) == 0; -} - /* Return true if the specified row last char is part of a multi line comment * that starts at this row or at one before, and does not end at the end * of the row but spawns to the next row. */ diff --git a/src/liolib.c b/src/liolib.c index b6cff86..6fb3359 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -132,7 +132,9 @@ static int io_open (lua_State *L) { snprintf(buffer, 1020, "io.open(\"%s\", \"%s\")", filename, mode); append_to_audit_log(L, buffer); FILE **pf = newfile(L); - if (file_operation_permitted(filename, mode)) + if (file_operation_permitted(filename, mode) + /* filenames starting with teliva_tmp_ are always ok */ + || starts_with(filename, "teliva_tmp_")) *pf = fopen(filename, mode); else { snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename); diff --git a/src/loslib.c b/src/loslib.c index 785447c..09a00c3 100644 --- a/src/loslib.c +++ b/src/loslib.c @@ -18,6 +18,7 @@ #include "lauxlib.h" #include "lualib.h" +#include "teliva.h" static int os_pushresult (lua_State *L, int i, const char *filename) { @@ -41,9 +42,23 @@ static int os_remove (lua_State *L) { } +static char oslib_errbuf[1024] = {0}; static int os_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); + /* A rename is like reading from one file and writing to another file. */ + if (!file_operation_permitted(fromname, "r") + && !starts_with(fromname, "teliva_tmp_")) { + snprintf(oslib_errbuf, 1024, "app tried to open file '%s' for reading; adjust its permissions (ctrl-p) if that is expected", fromname); + Previous_message = oslib_errbuf; + return os_pushresult(L, 0, fromname); + } + if (!file_operation_permitted(toname, "w") + && !starts_with(fromname, "teliva_tmp_")) { + snprintf(oslib_errbuf, 1024, "app tried to open file '%s' for writing; adjust its permissions (ctrl-p) if that is expected", toname); + Previous_message = oslib_errbuf; + return os_pushresult(L, 0, toname); + } return os_pushresult(L, rename(fromname, toname) == 0, fromname); } diff --git a/src/teliva.c b/src/teliva.c index 9ae7328..b604524 100644 --- a/src/teliva.c +++ b/src/teliva.c @@ -16,6 +16,10 @@ #include "teliva.h" #include "tlv.h" +int starts_with(const char* s, const char* prefix) { + return strncmp(s, prefix, strlen(prefix)) == 0; +} + /*** Standard UI elements */ int menu_column = 0; @@ -361,10 +365,6 @@ static void clear_caller(lua_State* L) { assert(lua_gettop(L) == oldtop); } -static int starts_with(const char* s, const char* pre) { - return strncmp(pre, s, strlen(pre)) == 0; -} - /* return true if submitted */ static int edit_current_definition(lua_State* L); static void recent_changes_view(lua_State* L); diff --git a/src/teliva.h b/src/teliva.h index f07b761..2e79956 100644 --- a/src/teliva.h +++ b/src/teliva.h @@ -190,4 +190,7 @@ extern int report_in_developer_mode(lua_State* L, int status); extern void render_previous_error(void); +/* Misc */ +extern int starts_with(const char* s, const char* prefix); + #endif