Explicitly sandbox Lua instances (3/4)
This allows UI scripts (saved in preferences) to access os.* functions (non-sandboxed), while preventing other scripts to do so. Lua scripts that can run os commands can execute arbitrary code on the system. While this is a nice feature, it can be equally dangerous.
This commit is contained in:
parent
6b3f25eb2a
commit
c1be897eed
@ -2350,12 +2350,11 @@ ARDOUR_UI::route_setup_info (const std::string& script_path)
|
||||
return rv;
|
||||
}
|
||||
|
||||
LuaState lua;
|
||||
LuaState lua (true, true);
|
||||
lua.Print.connect (&_lua_print);
|
||||
lua.sandbox (true);
|
||||
|
||||
lua_State* L = lua.getState();
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, true);
|
||||
LuaBindings::set_session (L, _session);
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
lua_setglobal (L, "Editor");
|
||||
@ -2403,12 +2402,11 @@ ARDOUR_UI::meta_route_setup (const std::string& script_path)
|
||||
return;
|
||||
}
|
||||
|
||||
LuaState lua;
|
||||
LuaState lua (true, true);
|
||||
lua.Print.connect (&_lua_print);
|
||||
lua.sandbox (true);
|
||||
|
||||
lua_State* L = lua.getState();
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, true);
|
||||
LuaBindings::set_session (L, _session);
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
lua_setglobal (L, "Editor");
|
||||
@ -2449,12 +2447,13 @@ ARDOUR_UI::meta_session_setup (const std::string& script_path)
|
||||
return;
|
||||
}
|
||||
|
||||
LuaState lua;
|
||||
bool sandbox = UIConfiguration::instance().get_sandbox_all_lua_scripts ();
|
||||
|
||||
LuaState lua (true, sandbox);
|
||||
lua.Print.connect (&_lua_print);
|
||||
lua.sandbox (false);
|
||||
|
||||
lua_State* L = lua.getState();
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, sandbox);
|
||||
LuaBindings::set_session (L, _session);
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
lua_setglobal (L, "Editor");
|
||||
|
@ -941,11 +941,16 @@ Editor::trigger_script_by_name (const std::string script_name, const std::string
|
||||
return;
|
||||
}
|
||||
|
||||
LuaState lua;
|
||||
#ifdef MIXBUS
|
||||
bool sandbox = false; // mixer state save/reset/restore needs os.*
|
||||
#else
|
||||
bool sandbox = UIConfiguration::instance().get_sandbox_all_lua_scripts ();
|
||||
#endif
|
||||
|
||||
LuaState lua (true, sandbox);
|
||||
lua.Print.connect (&_lua_print);
|
||||
lua.sandbox (false);
|
||||
lua_State* L = lua.getState();
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, sandbox);
|
||||
LuaBindings::set_session (L, _session);
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
lua_setglobal (L, "Editor");
|
||||
|
@ -33,7 +33,7 @@ int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef LUABINDINGDOC
|
||||
luabridge::setPrintBindings (true);
|
||||
LuaState lua;
|
||||
LuaState lua (false, false);
|
||||
lua_State* L = lua.getState ();
|
||||
#ifdef LUADOCOUT
|
||||
printf ("-- %s\n", ARDOUR::revision);
|
||||
@ -42,7 +42,7 @@ int main (int argc, char **argv)
|
||||
printf ("[\n");
|
||||
printf ("{\"version\" : \"%s\"},\n\n", ARDOUR::revision);
|
||||
#endif
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, false);
|
||||
LuaInstance::register_hooks (L);
|
||||
ARDOUR::LuaBindings::dsp (L);
|
||||
#ifdef LUADOCOUT
|
||||
|
@ -778,7 +778,7 @@ LuaInstance::bind_dialog (lua_State* L)
|
||||
}
|
||||
|
||||
void
|
||||
LuaInstance::register_classes (lua_State* L)
|
||||
LuaInstance::register_classes (lua_State* L, bool sandbox)
|
||||
{
|
||||
LuaBindings::stddef (L);
|
||||
LuaBindings::common (L);
|
||||
@ -1100,15 +1100,7 @@ LuaInstance::register_classes (lua_State* L)
|
||||
|
||||
.addFunction ("config", &_ui_config)
|
||||
|
||||
.endNamespace () // end ArdourUI
|
||||
|
||||
.beginNamespace ("os")
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
.addFunction ("execute", &lua_exec)
|
||||
#endif
|
||||
.addCFunction ("forkexec", &lua_forkexec)
|
||||
.endNamespace ();
|
||||
|
||||
.endNamespace (); // end ArdourUI
|
||||
// Editing Symbols
|
||||
|
||||
#undef ZOOMFOCUS
|
||||
@ -1135,6 +1127,16 @@ LuaInstance::register_classes (lua_State* L)
|
||||
.beginNamespace ("Editing")
|
||||
# include "editing_syms.h"
|
||||
.endNamespace ();
|
||||
|
||||
if (!sandbox) {
|
||||
luabridge::getGlobalNamespace (L)
|
||||
.beginNamespace ("os")
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
.addFunction ("execute", &lua_exec)
|
||||
#endif
|
||||
.addCFunction ("forkexec", &lua_forkexec)
|
||||
.endNamespace ();
|
||||
}
|
||||
}
|
||||
|
||||
#undef xstr
|
||||
@ -1174,6 +1176,7 @@ LuaInstance::destroy_instance ()
|
||||
}
|
||||
|
||||
LuaInstance::LuaInstance ()
|
||||
: lua (true, UIConfiguration::instance().get_sandbox_all_lua_scripts ())
|
||||
{
|
||||
lua.Print.connect (&_lua_print);
|
||||
init ();
|
||||
@ -1196,7 +1199,6 @@ LuaInstance::~LuaInstance ()
|
||||
void
|
||||
LuaInstance::init ()
|
||||
{
|
||||
lua.sandbox (false);
|
||||
lua.do_command (
|
||||
"function ScriptManager ()"
|
||||
" local self = { scripts = {}, instances = {}, icons = {} }"
|
||||
@ -1343,7 +1345,7 @@ LuaInstance::init ()
|
||||
abort(); /*NOTREACHED*/
|
||||
}
|
||||
|
||||
register_classes (L);
|
||||
LuaInstance::register_classes (L, UIConfiguration::instance().get_sandbox_all_lua_scripts ());
|
||||
register_hooks (L);
|
||||
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
@ -1527,8 +1529,8 @@ LuaInstance::pre_seed_script (std::string const& name, int& id)
|
||||
if (spi) {
|
||||
try {
|
||||
std::string script = Glib::file_get_contents (spi->path);
|
||||
LuaState ls;
|
||||
register_classes (ls.getState ());
|
||||
LuaState ls (true, true);
|
||||
register_classes (ls.getState (), true);
|
||||
LuaScriptParamList lsp = LuaScriptParams::script_params (ls, spi->path, "action_params");
|
||||
LuaScriptParamPtr lspp (new LuaScriptParam("x-script-origin", "", spi->path, false, true));
|
||||
lsp.push_back (lspp);
|
||||
@ -1595,8 +1597,8 @@ LuaInstance::interactive_add (Gtk::Window& parent, LuaScriptInfo::ScriptType typ
|
||||
return false;
|
||||
}
|
||||
|
||||
LuaState ls;
|
||||
register_classes (ls.getState ());
|
||||
LuaState ls (true, true);
|
||||
register_classes (ls.getState (), true);
|
||||
LuaScriptParamList lsp = LuaScriptParams::script_params (ls, spi->path, param_function);
|
||||
|
||||
/* allow cancel */
|
||||
@ -1865,9 +1867,8 @@ LuaInstance::register_lua_slot (const std::string& name, const std::string& scri
|
||||
/* parse script, get ActionHook(s) from script */
|
||||
ActionHook ah;
|
||||
try {
|
||||
LuaState l;
|
||||
LuaState l (true, true);
|
||||
l.Print.connect (&_lua_print);
|
||||
l.sandbox (true);
|
||||
lua_State* L = l.getState();
|
||||
register_hooks (L);
|
||||
l.do_command ("function ardour () end");
|
||||
@ -1972,6 +1973,7 @@ LuaCallback::LuaCallback (Session *s,
|
||||
const ActionHook& ah,
|
||||
const ARDOUR::LuaScriptParamList& args)
|
||||
: SessionHandlePtr (s)
|
||||
, lua (true, UIConfiguration::instance().get_sandbox_all_lua_scripts ())
|
||||
, _id ("0")
|
||||
, _name (name)
|
||||
, _signals (ah)
|
||||
@ -2005,6 +2007,7 @@ LuaCallback::LuaCallback (Session *s,
|
||||
|
||||
LuaCallback::LuaCallback (Session *s, XMLNode & node)
|
||||
: SessionHandlePtr (s)
|
||||
, lua (true, UIConfiguration::instance().get_sandbox_all_lua_scripts ())
|
||||
{
|
||||
XMLNode* child = NULL;
|
||||
if (node.name() != X_("LuaCallback")
|
||||
@ -2088,7 +2091,6 @@ void
|
||||
LuaCallback::init (void)
|
||||
{
|
||||
lua.Print.connect (&_lua_print);
|
||||
lua.sandbox (false);
|
||||
|
||||
lua.do_command (
|
||||
"function ScriptManager ()"
|
||||
@ -2209,7 +2211,7 @@ LuaCallback::init (void)
|
||||
abort(); /*NOTREACHED*/
|
||||
}
|
||||
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, UIConfiguration::instance().get_sandbox_all_lua_scripts ());
|
||||
LuaInstance::register_hooks (L);
|
||||
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
static void destroy_instance();
|
||||
~LuaInstance();
|
||||
|
||||
static void register_classes (lua_State* L);
|
||||
static void register_classes (lua_State* L, bool sandbox);
|
||||
static void register_hooks (lua_State* L);
|
||||
static void bind_cairo (lua_State* L);
|
||||
static void bind_dialog (lua_State* L);
|
||||
|
@ -197,12 +197,11 @@ void LuaWindow::reinit_lua ()
|
||||
{
|
||||
ENSURE_GUI_THREAD (*this, &LuaWindow::session_going_away);
|
||||
delete lua;
|
||||
lua = new LuaState();
|
||||
lua = new LuaState (true, UIConfiguration::instance().get_sandbox_all_lua_scripts ());
|
||||
lua->Print.connect (sigc::mem_fun (*this, &LuaWindow::append_text));
|
||||
lua->sandbox (false);
|
||||
|
||||
lua_State* L = lua->getState();
|
||||
LuaInstance::register_classes (L);
|
||||
LuaInstance::register_classes (L, UIConfiguration::instance().get_sandbox_all_lua_scripts ());
|
||||
luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
|
||||
lua_setglobal (L, "Editor");
|
||||
}
|
||||
|
@ -1869,6 +1869,7 @@ ProcessorEntry::PluginInlineDisplay::display_frame (cairo_t* cr, double w, doubl
|
||||
ProcessorEntry::LuaPluginDisplay::LuaPluginDisplay (ProcessorEntry& e, std::shared_ptr<ARDOUR::LuaProc> p, uint32_t max_height)
|
||||
: PluginInlineDisplay (e, p, max_height)
|
||||
, _luaproc (p)
|
||||
, lua_gui (true, true)
|
||||
, _lua_render_inline (0)
|
||||
{
|
||||
p->setup_lua_inline_gui (&lua_gui);
|
||||
|
@ -189,8 +189,7 @@ SessionDialog::meta_master_bus_profile (std::string script_path)
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
LuaState lua;
|
||||
lua.sandbox (true);
|
||||
LuaState lua (true, true);
|
||||
lua_State* L = lua.getState();
|
||||
|
||||
lua.do_command (
|
||||
|
@ -155,6 +155,7 @@ UI_CONFIG_VARIABLE (bool, ask_cut_copy_section_tempo_map, "ask-cut-copy-section-
|
||||
UI_CONFIG_VARIABLE (std::string, freesound_dir, "freesound-dir", "")
|
||||
UI_CONFIG_VARIABLE (int, max_note_height, "max-note-height", 20)
|
||||
UI_CONFIG_VARIABLE (bool, prefer_tap_tempo, "prefer-tap-tempo", false)
|
||||
UI_CONFIG_VARIABLE (bool, sandbox_all_lua_scripts, "sandbox-all-lua-scripts", false)
|
||||
|
||||
/* these are visibility-type selections in the New Track dialog that we should make persistent for the user's choices */
|
||||
UI_CONFIG_VARIABLE (bool, show_on_cue_page, "show-on-cue-page", true)
|
||||
|
Loading…
Reference in New Issue
Block a user