about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-12-25 18:55:01 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-12-25 18:55:01 -0800
commit16d949e2596fa56003cf01e3c78fa901e0614c0a (patch)
tree5da7d6af63f1a7a7932d1bcef22da61d5df30990
parent33bcd5c871c58d423b57616c324a8f0fa6c07524 (diff)
downloadteliva-16d949e2596fa56003cf01e3c78fa901e0614c0a.tar.gz
file open() is now sandboxed
In the process we now also have a mechanism for Teliva to overlay errors
while apps run. Might make sense to make that available to apps as well.
But I'm starting to realize that any app access to the Teliva areas of
the screen is fraught with risk.
-rw-r--r--src/liolib.c17
-rw-r--r--src/teliva.c33
-rw-r--r--src/teliva.h1
3 files changed, 36 insertions, 15 deletions
diff --git a/src/liolib.c b/src/liolib.c
index 6092cac..b0148e8 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -14,9 +14,9 @@
 #define LUA_LIB
 
 #include "lua.h"
-
 #include "lauxlib.h"
 #include "lualib.h"
+#include "teliva.h"
 
 
 
@@ -128,11 +128,17 @@ static int io_tostring (lua_State *L) {
 }
 
 
+static char iolib_errbuf[1024] = {0};
 static int io_open (lua_State *L) {
   const char *filename = luaL_checkstring(L, 1);
   const char *mode = luaL_optstring(L, 2, "r");
   FILE **pf = newfile(L);
-  *pf = fopen(filename, mode);
+  if (file_operations_allowed)
+    *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);
+    Previous_message = iolib_errbuf;
+  }
   return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
 }
 
@@ -164,7 +170,12 @@ static int f_lines (lua_State *L) {
 static int io_lines (lua_State *L) {
   const char *filename = luaL_checkstring(L, 1);
   FILE **pf = newfile(L);
-  *pf = fopen(filename, "r");
+  if (file_operations_allowed)
+    *pf = fopen(filename, "r");
+  else {
+    snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename);
+    Previous_message = iolib_errbuf;
+  }
   if (*pf == NULL)
     fileerror(L, 1, filename);
   aux_lines(L, lua_gettop(L), 1);
diff --git a/src/teliva.c b/src/teliva.c
index f2814c2..1129dc3 100644
--- a/src/teliva.c
+++ b/src/teliva.c
@@ -32,6 +32,7 @@ void draw_menu_item(const char* key, const char* name) {
 }
 
 static void render_permissions(lua_State* L);
+char* Previous_message;
 static void draw_menu(lua_State* L) {
   attron(A_BOLD|A_REVERSE);
   color_set(COLOR_PAIR_MENU, NULL);
@@ -42,20 +43,28 @@ static void draw_menu(lua_State* L) {
   draw_menu_item("^e", "edit");
   draw_menu_item("^p", "perms");
 
-  /* render any app-specific items */
-  lua_getglobal(L, "menu");
-  int table = lua_gettop(L);
-  if (lua_istable(L, -1)) {
-    for (int i = 1; i <= luaL_getn(L, table); ++i) {
-      lua_rawgeti(L, table, i);
-      int menu_item = lua_gettop(L);
-      lua_rawgeti(L, menu_item, 1);  /* key */
-      lua_rawgeti(L, menu_item, 2);  /* value */
-      draw_menu_item(lua_tostring(L, -2), lua_tostring(L, -1));
-      lua_pop(L, 3);
+  /* if app ran successfully, render any app-specific items */
+  if (Previous_message == NULL) {
+    lua_getglobal(L, "menu");
+    int table = lua_gettop(L);
+    if (lua_istable(L, -1)) {
+      for (int i = 1; i <= luaL_getn(L, table); ++i) {
+        lua_rawgeti(L, table, i);
+        int menu_item = lua_gettop(L);
+        lua_rawgeti(L, menu_item, 1);  /* key */
+        lua_rawgeti(L, menu_item, 2);  /* value */
+        draw_menu_item(lua_tostring(L, -2), lua_tostring(L, -1));
+        lua_pop(L, 3);
+      }
     }
+    lua_pop(L, 1);
+  }
+  else {
+    /* otherwise render the flash message */
+    attron(COLOR_PAIR(COLOR_PAIR_ERROR));
+    addstr(Previous_message);
+    attroff(COLOR_PAIR(COLOR_PAIR_ERROR));
   }
-  lua_pop(L, 1);
 
   /* render app permissions on the right */
   render_permissions(L);
diff --git a/src/teliva.h b/src/teliva.h
index bf01c11..42ebdc7 100644
--- a/src/teliva.h
+++ b/src/teliva.h
@@ -151,6 +151,7 @@ enum color_pair {
 
 /* Integrate with Lua VM */
 extern char** Argv;
+extern char* Previous_message;
 extern int handle_image(lua_State* L, char** argv, int n);
 extern void developer_mode(lua_State* L);
 extern void permissions_mode(lua_State* L);