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.
This commit is contained in:
Kartik K. Agaram 2022-03-07 21:57:11 -08:00
parent 2d393bfb80
commit 2b47f76308
6 changed files with 26 additions and 10 deletions

View File

@ -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')

View File

@ -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. */

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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