Я хочу выполнить недоверяемый .lua файл в его собственной среде путем вызова lua_setfenv () так, чтобы он не мог влиять ни на один мой код.
Документация для той функции, хотя только объясняет, как вызвать функцию, не, как выполнить файл.
В настоящее время для петляния я использую:
int error = luaL_loadfile(mState, path.c_str()) || lua_pcall(mState, 0, 0, 0);
Сделайте я должен назвать "dofile" lua функцией от API C с lua_setfenv
, или есть ли более изящный способ сделать это?
См. Обсуждение песочницы в Lua User's Wiki и более общую тему безопасности сценариев . Есть ряд тонких и не очень тонких проблем с подобными вещами. Это можно сделать, но защита от кода, такого как для i = 1,1e39 do end
, требует большего, чем просто ограничение того, какие функции доступны для песочницы.
Общий метод заключается в создании функциональной среды для песочницы, в которой есть белый список разрешенных функций. В некоторых случаях этот список может даже быть пустым, но предоставление пользователю доступа к парам ()
, например, почти наверняка безвредно. На странице песочницы есть список системных функций с разбивкой по степени их безопасности в качестве удобного справочника для создания такого белого списка.
Затем вы используете lua_setfenv ()
, чтобы применить среду функций к пользовательскому скрипту, который вы загрузили (но еще не выполнили) с помощью lua_loadfile ()
или lua_loadstring ()
в зависимости от ситуации. С присоединенным окружением вы можете выполнить его с помощью lua_pcall ()
и друзей. Перед выполнением некоторые люди фактически сканировали загруженный байт-код на предмет операций, которые они не хотят разрешать. Это можно использовать для полного запрета циклов или записи в глобальные переменные.
Еще одно замечание: функции загрузки обычно загружают либо предварительно скомпилированный байт-код, либо текст Lua.Оказывается, будет намного безопаснее, если вы никогда не разрешите предварительно скомпилированный байт-код, поскольку было выявлено несколько способов заставить виртуальную машину работать неправильно, и все они зависят от ручной обработки недопустимого байт-кода. Поскольку файлы байт-кода начинаются с четко определенной последовательности байтов, которая не является простым текстом ASCII, все, что вам нужно сделать, это прочитать сценарий в строковом буфере, проверить отсутствие маркера и передать его только в lua_loadstring ( )
, если это не байт-код.
В течение многих лет в списке рассылки Lua-L было много дискуссий по этому поводу, так что поиск там также, вероятно, будет полезным.
luaL_loadfile ()
загрузит фрагмент, затем вызовет lua_setfenv ()
для установки таблицы среды, затем вызовет lua_pcall ()
для выполнения фрагмента. См. Недавний ответ судьи Мэйгардена на Вызов функций lua из файлов .lua с использованием дескрипторов?