file permissions: decide based on calling function

This commit is contained in:
Kartik K. Agaram 2022-02-01 20:59:53 -08:00
parent 88404d41ea
commit 90904f344a
4 changed files with 30 additions and 15 deletions

View File

@ -1358,7 +1358,7 @@ void editFilePermissions(char* filename) {
editorRefreshScreen(editorNonCodeMenu); editorRefreshScreen(editorNonCodeMenu);
int y, x; int y, x;
getyx(stdscr, y, x); getyx(stdscr, y, x);
mvaddstr(0, 0, "function file_operation_permitted(filename, mode)"); mvaddstr(0, 0, "function file_operation_permitted(caller, filename, mode)");
mvaddstr(MIN(E.startrow + E.numrows, E.endrow), 0, "end"); mvaddstr(MIN(E.startrow + E.numrows, E.endrow), 0, "end");
mvaddstr(y, x, ""); mvaddstr(y, x, "");
int c = getch(); int c = getch();
@ -1465,7 +1465,7 @@ void resumeFilePermissionsEdit() {
editorRefreshScreen(editorNonCodeMenu); editorRefreshScreen(editorNonCodeMenu);
int y, x; int y, x;
getyx(stdscr, y, x); getyx(stdscr, y, x);
mvaddstr(0, 0, "function file_operation_permitted(filename, mode)"); mvaddstr(0, 0, "function file_operation_permitted(caller, filename, mode)");
mvaddstr(MIN(E.startrow + E.numrows, E.endrow), 0, "end"); mvaddstr(MIN(E.startrow + E.numrows, E.endrow), 0, "end");
mvaddstr(y, x, ""); mvaddstr(y, x, "");
int c = getch(); int c = getch();

View File

@ -137,7 +137,7 @@ static int io_open (lua_State *L) {
snprintf(buffer, 1020, "io.open(\"%s\", \"%s\")", filename, mode); snprintf(buffer, 1020, "io.open(\"%s\", \"%s\")", filename, mode);
append_to_audit_log(L, buffer); append_to_audit_log(L, buffer);
FILE **pf = newfile(L); FILE **pf = newfile(L);
if (file_operation_permitted(filename, mode)) if (file_operation_permitted(caller(L), filename, mode))
*pf = fopen(filename, mode); *pf = fopen(filename, mode);
else { else {
snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename); snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename);
@ -178,7 +178,7 @@ static int io_lines (lua_State *L) {
memset(buffer, '\0', 1024); memset(buffer, '\0', 1024);
snprintf(buffer, 1020, "io.lines(\"%s\", \"r\")", filename); snprintf(buffer, 1020, "io.lines(\"%s\", \"r\")", filename);
append_to_audit_log(L, buffer); append_to_audit_log(L, buffer);
if (file_operation_permitted(filename, "r")) if (file_operation_permitted(caller(L), filename, "r"))
*pf = fopen(filename, "r"); *pf = fopen(filename, "r");
else { else {
snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename); snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename);

View File

@ -313,6 +313,17 @@ void save_caller(lua_State* L, const char* name, int call_graph_depth) {
else if (call_graph_depth == 2) save_caller_as(L, name, "main"); // the way Teliva calls `main` messes with debug info else if (call_graph_depth == 2) save_caller_as(L, name, "main"); // the way Teliva calls `main` messes with debug info
} }
char* caller(lua_State* L) {
static char result[1024] = {0};
lua_Debug ar;
lua_getstack(L, 1, &ar);
lua_getinfo(L, "n", &ar);
memset(result, '\0', 1024);
if (ar.name)
strncpy(result, ar.name, 1020);
return result;
}
void save_caller_as(lua_State* L, const char* name, const char* caller_name) { void save_caller_as(lua_State* L, const char* name, const char* caller_name) {
// push table of caller tables // push table of caller tables
luaL_newmetatable(L, "__teliva_caller"); luaL_newmetatable(L, "__teliva_caller");
@ -1269,18 +1280,19 @@ static const char* user_configuration_filename() {
memset(config_filename, '\0', 1024); memset(config_filename, '\0', 1024);
const char* config_home = getenv("XDG_CONFIG_HOME"); const char* config_home = getenv("XDG_CONFIG_HOME");
if (config_home == NULL) if (config_home == NULL)
snprintf(config_filename, 1024, "%s/.teliva", home); snprintf(config_filename, 1020, "%s/.teliva", home);
else else
snprintf(config_filename, 1024, "%s/.teliva", config_home); snprintf(config_filename, 1020, "%s/.teliva", config_home);
return config_filename; return config_filename;
} }
int file_operation_permitted(const char* filename, const char* mode) { int file_operation_permitted(const char* caller, const char* filename, const char* mode) {
int oldtop = lua_gettop(trustedL); int oldtop = lua_gettop(trustedL);
lua_getglobal(trustedL, "file_operation_permitted"); lua_getglobal(trustedL, "file_operation_permitted");
lua_pushstring(trustedL, caller);
lua_pushstring(trustedL, filename); lua_pushstring(trustedL, filename);
lua_pushstring(trustedL, mode); lua_pushstring(trustedL, mode);
if (lua_pcall(trustedL, 2 /*args*/, 1 /*result*/, /*errfunc*/0)) { if (lua_pcall(trustedL, 3 /*args*/, 1 /*result*/, /*errfunc*/0)) {
/* TODO: error handling. Or should we use errfunc above? */ /* TODO: error handling. Or should we use errfunc above? */
} }
if (!lua_isboolean(trustedL, -1)) { if (!lua_isboolean(trustedL, -1)) {
@ -1315,9 +1327,10 @@ void characterize_file_operations_predicate() {
for (const char** test_filename = test_filenames; *test_filename; ++test_filename) { for (const char** test_filename = test_filenames; *test_filename; ++test_filename) {
for (const char** test_mode = test_modes; *test_mode; ++test_mode) { for (const char** test_mode = test_modes; *test_mode; ++test_mode) {
lua_getglobal(trustedL, "file_operation_permitted"); lua_getglobal(trustedL, "file_operation_permitted");
lua_pushstring(trustedL, "___");
lua_pushstring(trustedL, *test_filename); lua_pushstring(trustedL, *test_filename);
lua_pushstring(trustedL, *test_mode); lua_pushstring(trustedL, *test_mode);
if (lua_pcall(trustedL, 2 /*args*/, 1 /*result*/, /*errfunc*/0)) { if (lua_pcall(trustedL, 3 /*args*/, 1 /*result*/, /*errfunc*/0)) {
/* TODO: error handling. Or should we use errfunc above? */ /* TODO: error handling. Or should we use errfunc above? */
} }
++num_attempts; ++num_attempts;
@ -1368,7 +1381,7 @@ static void render_permissions_screen() {
attrset(A_NORMAL); attrset(A_NORMAL);
mvaddstr(7, 5, "File operations"); mvaddstr(7, 5, "File operations");
mvaddstr(7, 30, "function file_operation_permitted(filename, mode)"); mvaddstr(7, 30, "function file_operation_permitted(caller, filename, mode)");
int y = render_wrapped_text(8, 32, COLS-5, file_operations_predicate_body); int y = render_wrapped_text(8, 32, COLS-5, file_operations_predicate_body);
mvaddstr(y, 30, "end"); mvaddstr(y, 30, "end");
y++; y++;
@ -1437,9 +1450,10 @@ static void render_permissions_screen() {
* on the stack and return non-zero */ * on the stack and return non-zero */
int validate_file_operations_predicate() { int validate_file_operations_predicate() {
lua_getglobal(trustedL, "file_operation_permitted"); lua_getglobal(trustedL, "file_operation_permitted");
lua_pushstring(trustedL, "foo"); lua_pushstring(trustedL, "caller");
lua_pushstring(trustedL, "r"); lua_pushstring(trustedL, "filename");
if (lua_pcall(trustedL, 2 /*args*/, 1 /*result*/, /*errfunc*/0)) { lua_pushstring(trustedL, "r"); /* open mode */
if (lua_pcall(trustedL, 3 /*args*/, 1 /*result*/, /*errfunc*/0)) {
/* TODO: error handling. Or should we use errfunc above? */ /* TODO: error handling. Or should we use errfunc above? */
} }
int status = 1; int status = 1;
@ -1452,7 +1466,7 @@ int validate_file_operations_predicate() {
static int load_file_operations_predicate(const char* body) { static int load_file_operations_predicate(const char* body) {
char buffer[1024] = {0}; char buffer[1024] = {0};
strcpy(buffer, "function file_operation_permitted(filename, mode)\n"); strcpy(buffer, "function file_operation_permitted(caller, filename, mode)\n");
strncat(buffer, body, 1020); strncat(buffer, body, 1020);
if (buffer[strlen(buffer)-1] != '\n') if (buffer[strlen(buffer)-1] != '\n')
strncat(buffer, "\n", 1020); strncat(buffer, "\n", 1020);

View File

@ -155,7 +155,7 @@ extern char* Previous_message;
extern int handle_image(lua_State* L, char** argv, int n); extern int handle_image(lua_State* L, char** argv, int n);
extern void developer_mode(lua_State* L); extern void developer_mode(lua_State* L);
extern void permissions_mode(lua_State* L); extern void permissions_mode(lua_State* L);
extern int file_operation_permitted(const char* filename, const char* mode); extern int file_operation_permitted(const char* caller, const char* filename, const char* mode);
extern int net_operations_permitted; extern int net_operations_permitted;
extern void load_editor_buffer_to_current_definition_in_image(lua_State* L); extern void load_editor_buffer_to_current_definition_in_image(lua_State* L);
@ -164,6 +164,7 @@ extern void save_to_current_definition_and_editor_buffer(lua_State* L, const cha
extern void save_editor_state(int rowoff, int coloff, int cy, int cx); extern void save_editor_state(int rowoff, int coloff, int cy, int cx);
extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name); extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name);
extern char* caller(lua_State* L);
extern void save_caller(lua_State* L, const char* name, int call_graph_depth); extern void save_caller(lua_State* L, const char* name, int call_graph_depth);
extern void draw_callers_of_current_definition(lua_State* L); extern void draw_callers_of_current_definition(lua_State* L);
extern void append_to_audit_log(lua_State* L, const char* buffer); extern void append_to_audit_log(lua_State* L, const char* buffer);