2
0

s_security.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "cpp_api/s_security.h"
  17. #include "lua_api/l_base.h"
  18. #include "filesys.h"
  19. #include "porting.h"
  20. #include "server.h"
  21. #include "client/client.h"
  22. #include "settings.h"
  23. #include <cerrno>
  24. #include <string>
  25. #include <algorithm>
  26. #include <iostream>
  27. #define SECURE_API(lib, name) \
  28. lua_pushcfunction(L, sl_##lib##_##name); \
  29. lua_setfield(L, -2, #name);
  30. static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int from=-2, int to=-1)
  31. {
  32. if (from < 0) from = lua_gettop(L) + from + 1;
  33. if (to < 0) to = lua_gettop(L) + to + 1;
  34. for (unsigned i = 0; i < (len / sizeof(list[0])); i++) {
  35. lua_getfield(L, from, list[i]);
  36. lua_setfield(L, to, list[i]);
  37. }
  38. }
  39. static void shallow_copy_table(lua_State *L, int from=-2, int to=-1)
  40. {
  41. if (from < 0) from = lua_gettop(L) + from + 1;
  42. if (to < 0) to = lua_gettop(L) + to + 1;
  43. lua_pushnil(L);
  44. while (lua_next(L, from) != 0) {
  45. assert(lua_type(L, -1) != LUA_TTABLE);
  46. // duplicate key and value for lua_rawset
  47. lua_pushvalue(L, -2);
  48. lua_pushvalue(L, -2);
  49. lua_rawset(L, to);
  50. lua_pop(L, 1);
  51. }
  52. }
  53. // Pushes the original version of a library function on the stack, from the old version
  54. static inline void push_original(lua_State *L, const char *lib, const char *func)
  55. {
  56. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
  57. lua_getfield(L, -1, lib);
  58. lua_remove(L, -2); // Remove globals_backup
  59. lua_getfield(L, -1, func);
  60. lua_remove(L, -2); // Remove lib
  61. }
  62. void ScriptApiSecurity::initializeSecurity()
  63. {
  64. static const char *whitelist[] = {
  65. "assert",
  66. "core",
  67. "collectgarbage",
  68. "DIR_DELIM",
  69. "error",
  70. "getfenv",
  71. "getmetatable",
  72. "ipairs",
  73. "next",
  74. "pairs",
  75. "pcall",
  76. "print",
  77. "rawequal",
  78. "rawget",
  79. "rawset",
  80. "select",
  81. "setfenv",
  82. "setmetatable",
  83. "tonumber",
  84. "tostring",
  85. "type",
  86. "unpack",
  87. "_VERSION",
  88. "xpcall",
  89. };
  90. static const char *whitelist_tables[] = {
  91. // These libraries are completely safe BUT we need to duplicate their table
  92. // to ensure the sandbox can't affect the insecure env
  93. "coroutine",
  94. "string",
  95. "table",
  96. "math",
  97. "bit"
  98. };
  99. static const char *io_whitelist[] = {
  100. "close",
  101. "flush",
  102. "read",
  103. "type",
  104. "write",
  105. };
  106. static const char *os_whitelist[] = {
  107. "clock",
  108. "date",
  109. "difftime",
  110. "getenv",
  111. "time",
  112. };
  113. static const char *debug_whitelist[] = {
  114. "gethook",
  115. "traceback",
  116. "getinfo",
  117. "upvalueid",
  118. "sethook",
  119. "debug",
  120. };
  121. static const char *package_whitelist[] = {
  122. "config",
  123. "cpath",
  124. "path",
  125. "searchpath",
  126. };
  127. #if USE_LUAJIT
  128. static const char *jit_whitelist[] = {
  129. "arch",
  130. "flush",
  131. "off",
  132. "on",
  133. "opt",
  134. "os",
  135. "status",
  136. "version",
  137. "version_num",
  138. };
  139. #endif
  140. m_secure = true;
  141. lua_State *L = getStack();
  142. // Backup globals to the registry
  143. lua_getglobal(L, "_G");
  144. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
  145. // Replace the global environment with an empty one
  146. int thread = getThread(L);
  147. createEmptyEnv(L);
  148. setLuaEnv(L, thread);
  149. // Get old globals
  150. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
  151. int old_globals = lua_gettop(L);
  152. // Copy safe base functions
  153. lua_getglobal(L, "_G");
  154. copy_safe(L, whitelist, sizeof(whitelist));
  155. // And replace unsafe ones
  156. SECURE_API(g, dofile);
  157. SECURE_API(g, load);
  158. SECURE_API(g, loadfile);
  159. SECURE_API(g, loadstring);
  160. SECURE_API(g, require);
  161. lua_pop(L, 1);
  162. // Copy safe libraries
  163. for (const char *libname : whitelist_tables) {
  164. lua_getfield(L, old_globals, libname);
  165. lua_newtable(L);
  166. shallow_copy_table(L);
  167. lua_setglobal(L, libname);
  168. lua_pop(L, 1);
  169. }
  170. // Copy safe IO functions
  171. lua_getfield(L, old_globals, "io");
  172. lua_newtable(L);
  173. copy_safe(L, io_whitelist, sizeof(io_whitelist));
  174. // And replace unsafe ones
  175. SECURE_API(io, open);
  176. SECURE_API(io, input);
  177. SECURE_API(io, output);
  178. SECURE_API(io, lines);
  179. lua_setglobal(L, "io");
  180. lua_pop(L, 1); // Pop old IO
  181. // Copy safe OS functions
  182. lua_getfield(L, old_globals, "os");
  183. lua_newtable(L);
  184. copy_safe(L, os_whitelist, sizeof(os_whitelist));
  185. // And replace unsafe ones
  186. SECURE_API(os, remove);
  187. SECURE_API(os, rename);
  188. SECURE_API(os, setlocale);
  189. lua_setglobal(L, "os");
  190. lua_pop(L, 1); // Pop old OS
  191. // Copy safe debug functions
  192. lua_getfield(L, old_globals, "debug");
  193. lua_newtable(L);
  194. copy_safe(L, debug_whitelist, sizeof(debug_whitelist));
  195. lua_setglobal(L, "debug");
  196. lua_pop(L, 1); // Pop old debug
  197. // Copy safe package fields
  198. lua_getfield(L, old_globals, "package");
  199. lua_newtable(L);
  200. copy_safe(L, package_whitelist, sizeof(package_whitelist));
  201. lua_setglobal(L, "package");
  202. lua_pop(L, 1); // Pop old package
  203. #if USE_LUAJIT
  204. // Copy safe jit functions, if they exist
  205. lua_getfield(L, -1, "jit");
  206. if (!lua_isnil(L, -1)) {
  207. lua_newtable(L);
  208. copy_safe(L, jit_whitelist, sizeof(jit_whitelist));
  209. lua_setglobal(L, "jit");
  210. }
  211. lua_pop(L, 1); // Pop old jit
  212. #endif
  213. // Get rid of 'core' in the old globals, we don't want anyone thinking it's
  214. // safe or even usable.
  215. lua_pushnil(L);
  216. lua_setfield(L, old_globals, "core");
  217. lua_pop(L, 1); // Pop globals_backup
  218. /*
  219. * In addition to copying the tables in whitelist_tables, we also need to
  220. * replace the string metatable. Otherwise old_globals.string would
  221. * be accessible via getmetatable("").__index from inside the sandbox.
  222. */
  223. lua_pushliteral(L, "");
  224. lua_newtable(L);
  225. lua_getglobal(L, "string");
  226. lua_setfield(L, -2, "__index");
  227. lua_setmetatable(L, -2);
  228. lua_pop(L, 1); // Pop empty string
  229. }
  230. void ScriptApiSecurity::initializeSecurityClient()
  231. {
  232. static const char *whitelist[] = {
  233. "assert",
  234. "core",
  235. "collectgarbage",
  236. "DIR_DELIM",
  237. "error",
  238. "getfenv",
  239. "ipairs",
  240. "next",
  241. "pairs",
  242. "pcall",
  243. "print",
  244. "rawequal",
  245. "rawget",
  246. "rawset",
  247. "select",
  248. "setfenv",
  249. "getmetatable",
  250. "setmetatable",
  251. "tonumber",
  252. "tostring",
  253. "type",
  254. "unpack",
  255. "_VERSION",
  256. "xpcall",
  257. // Completely safe libraries
  258. "coroutine",
  259. "string",
  260. "table",
  261. "math",
  262. "bit",
  263. };
  264. static const char *os_whitelist[] = {
  265. "clock",
  266. "date",
  267. "difftime",
  268. "time"
  269. };
  270. static const char *debug_whitelist[] = {
  271. "getinfo", // used by builtin and unset before mods load
  272. "traceback"
  273. };
  274. #if USE_LUAJIT
  275. static const char *jit_whitelist[] = {
  276. "arch",
  277. "flush",
  278. "off",
  279. "on",
  280. "opt",
  281. "os",
  282. "status",
  283. "version",
  284. "version_num",
  285. };
  286. #endif
  287. m_secure = true;
  288. lua_State *L = getStack();
  289. int thread = getThread(L);
  290. // create an empty environment
  291. createEmptyEnv(L);
  292. // Copy safe base functions
  293. lua_getglobal(L, "_G");
  294. lua_getfield(L, -2, "_G");
  295. copy_safe(L, whitelist, sizeof(whitelist));
  296. // And replace unsafe ones
  297. SECURE_API(g, dofile);
  298. SECURE_API(g, load);
  299. SECURE_API(g, loadfile);
  300. SECURE_API(g, loadstring);
  301. SECURE_API(g, require);
  302. lua_pop(L, 2);
  303. // Copy safe OS functions
  304. lua_getglobal(L, "os");
  305. lua_newtable(L);
  306. copy_safe(L, os_whitelist, sizeof(os_whitelist));
  307. lua_setfield(L, -3, "os");
  308. lua_pop(L, 1); // Pop old OS
  309. // Copy safe debug functions
  310. lua_getglobal(L, "debug");
  311. lua_newtable(L);
  312. copy_safe(L, debug_whitelist, sizeof(debug_whitelist));
  313. lua_setfield(L, -3, "debug");
  314. lua_pop(L, 1); // Pop old debug
  315. #if USE_LUAJIT
  316. // Copy safe jit functions, if they exist
  317. lua_getglobal(L, "jit");
  318. lua_newtable(L);
  319. copy_safe(L, jit_whitelist, sizeof(jit_whitelist));
  320. lua_setfield(L, -3, "jit");
  321. lua_pop(L, 1); // Pop old jit
  322. #endif
  323. // Set the environment to the one we created earlier
  324. setLuaEnv(L, thread);
  325. }
  326. int ScriptApiSecurity::getThread(lua_State *L)
  327. {
  328. #if LUA_VERSION_NUM <= 501
  329. int is_main = lua_pushthread(L); // Push the main thread
  330. FATAL_ERROR_IF(!is_main, "Security: ScriptApi's Lua state "
  331. "isn't the main Lua thread!");
  332. return lua_gettop(L);
  333. #endif
  334. return 0;
  335. }
  336. void ScriptApiSecurity::createEmptyEnv(lua_State *L)
  337. {
  338. lua_newtable(L); // Create new environment
  339. lua_pushvalue(L, -1);
  340. lua_setfield(L, -2, "_G"); // Create the _G loop
  341. }
  342. void ScriptApiSecurity::setLuaEnv(lua_State *L, int thread)
  343. {
  344. #if LUA_VERSION_NUM >= 502 // Lua >= 5.2
  345. // Set the global environment
  346. lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
  347. #else // Lua <= 5.1
  348. // Set the environment of the main thread
  349. FATAL_ERROR_IF(!lua_setfenv(L, thread), "Security: Unable to set "
  350. "environment of the main Lua thread!");
  351. lua_pop(L, 1); // Pop thread
  352. #endif
  353. }
  354. bool ScriptApiSecurity::isSecure(lua_State *L)
  355. {
  356. #ifndef SERVER
  357. auto script = ModApiBase::getScriptApiBase(L);
  358. // CSM keeps no globals backup but is always secure
  359. if (script->getType() == ScriptingType::Client)
  360. return true;
  361. #endif
  362. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
  363. bool secure = !lua_isnil(L, -1);
  364. lua_pop(L, 1);
  365. return secure;
  366. }
  367. bool ScriptApiSecurity::safeLoadString(lua_State *L, const std::string &code, const char *chunk_name)
  368. {
  369. if (code.size() > 0 && code[0] == LUA_SIGNATURE[0]) {
  370. lua_pushliteral(L, "Bytecode prohibited when mod security is enabled.");
  371. return false;
  372. }
  373. if (luaL_loadbuffer(L, code.data(), code.size(), chunk_name))
  374. return false;
  375. return true;
  376. }
  377. bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char *display_name)
  378. {
  379. FILE *fp;
  380. char *chunk_name;
  381. if (!display_name)
  382. display_name = path;
  383. if (!path) {
  384. fp = stdin;
  385. chunk_name = const_cast<char *>("=stdin");
  386. } else {
  387. fp = fopen(path, "rb");
  388. if (!fp) {
  389. lua_pushfstring(L, "%s: %s", path, strerror(errno));
  390. return false;
  391. }
  392. size_t len = strlen(display_name) + 2;
  393. chunk_name = new char[len];
  394. snprintf(chunk_name, len, "@%s", display_name);
  395. }
  396. size_t start = 0;
  397. int c = std::getc(fp);
  398. if (c == '#') {
  399. // Skip the first line
  400. while ((c = std::getc(fp)) != EOF && c != '\n') {}
  401. if (c == '\n')
  402. std::getc(fp);
  403. start = std::ftell(fp);
  404. }
  405. // Read the file
  406. int ret = std::fseek(fp, 0, SEEK_END);
  407. if (ret) {
  408. lua_pushfstring(L, "%s: %s", path, strerror(errno));
  409. if (path) {
  410. std::fclose(fp);
  411. delete [] chunk_name;
  412. }
  413. return false;
  414. }
  415. size_t size = std::ftell(fp) - start;
  416. std::string code(size, '\0');
  417. ret = std::fseek(fp, start, SEEK_SET);
  418. if (ret) {
  419. lua_pushfstring(L, "%s: %s", path, strerror(errno));
  420. if (path) {
  421. std::fclose(fp);
  422. delete [] chunk_name;
  423. }
  424. return false;
  425. }
  426. size_t num_read = std::fread(&code[0], 1, size, fp);
  427. if (path)
  428. std::fclose(fp);
  429. if (num_read != size) {
  430. lua_pushliteral(L, "Error reading file to load.");
  431. if (path)
  432. delete [] chunk_name;
  433. return false;
  434. }
  435. bool result = safeLoadString(L, code, chunk_name);
  436. if (path)
  437. delete [] chunk_name;
  438. return result;
  439. }
  440. bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
  441. bool write_required, bool *write_allowed)
  442. {
  443. if (write_allowed)
  444. *write_allowed = false;
  445. std::string str; // Transient
  446. std::string abs_path = fs::AbsolutePath(path);
  447. if (!abs_path.empty()) {
  448. // Don't allow accessing the settings file
  449. str = fs::AbsolutePath(g_settings_path);
  450. if (str == abs_path) return false;
  451. }
  452. // If we couldn't find the absolute path (path doesn't exist) then
  453. // try removing the last components until it works (to allow
  454. // non-existent files/folders for mkdir).
  455. std::string cur_path = path;
  456. std::string removed;
  457. while (abs_path.empty() && !cur_path.empty()) {
  458. std::string component;
  459. cur_path = fs::RemoveLastPathComponent(cur_path, &component);
  460. if (component == "..") {
  461. // Parent components can't be allowed or we could allow something like
  462. // /home/user/minetest/worlds/foo/noexist/../../../../../../etc/passwd.
  463. // If we have previous non-relative elements in the path we might be
  464. // able to remove them so that things like worlds/foo/noexist/../auth.txt
  465. // could be allowed, but those paths will be interpreted as nonexistent
  466. // by the operating system anyways.
  467. return false;
  468. }
  469. removed.append(component).append(removed.empty() ? "" : DIR_DELIM + removed);
  470. abs_path = fs::AbsolutePath(cur_path);
  471. }
  472. if (abs_path.empty())
  473. return false;
  474. // Add the removed parts back so that you can't, eg, create a
  475. // directory in worldmods if worldmods doesn't exist.
  476. if (!removed.empty())
  477. abs_path += DIR_DELIM + removed;
  478. // Get gamedef from registry
  479. ScriptApiBase *script = ModApiBase::getScriptApiBase(L);
  480. const IGameDef *gamedef = script->getGameDef();
  481. if (!gamedef)
  482. return false;
  483. // Get mod name
  484. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  485. if (lua_isstring(L, -1)) {
  486. std::string mod_name = readParam<std::string>(L, -1);
  487. // Builtin can access anything
  488. if (mod_name == BUILTIN_MOD_NAME) {
  489. if (write_allowed) *write_allowed = true;
  490. return true;
  491. }
  492. // Allow paths in mod path
  493. // Don't bother if write access isn't important, since it will be handled later
  494. if (write_required || write_allowed != NULL) {
  495. const ModSpec *mod = gamedef->getModSpec(mod_name);
  496. if (mod) {
  497. str = fs::AbsolutePath(mod->path);
  498. if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
  499. if (write_allowed) *write_allowed = true;
  500. return true;
  501. }
  502. }
  503. }
  504. }
  505. lua_pop(L, 1); // Pop mod name
  506. // Allow read-only access to game directory
  507. if (!write_required) {
  508. const SubgameSpec *game_spec = gamedef->getGameSpec();
  509. if (game_spec && !game_spec->path.empty()) {
  510. str = fs::AbsolutePath(game_spec->path);
  511. if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
  512. return true;
  513. }
  514. }
  515. }
  516. // Allow read-only access to all mod directories
  517. if (!write_required) {
  518. const std::vector<ModSpec> &mods = gamedef->getMods();
  519. for (const ModSpec &mod : mods) {
  520. str = fs::AbsolutePath(mod.path);
  521. if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
  522. return true;
  523. }
  524. }
  525. }
  526. str = fs::AbsolutePath(gamedef->getWorldPath());
  527. if (!str.empty()) {
  528. // Don't allow access to other paths in the world mod/game path.
  529. // These have to be blocked so you can't override a trusted mod
  530. // by creating a mod with the same name in a world mod directory.
  531. // We add to the absolute path of the world instead of getting
  532. // the absolute paths directly because that won't work if they
  533. // don't exist.
  534. if (fs::PathStartsWith(abs_path, str + DIR_DELIM + "worldmods") ||
  535. fs::PathStartsWith(abs_path, str + DIR_DELIM + "game")) {
  536. return false;
  537. }
  538. // Allow all other paths in world path
  539. if (fs::PathStartsWith(abs_path, str)) {
  540. if (write_allowed) *write_allowed = true;
  541. return true;
  542. }
  543. }
  544. // Default to disallowing
  545. return false;
  546. }
  547. bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &setting)
  548. {
  549. assert(str_starts_with(setting, "secure."));
  550. // We have to make sure that this function is being called directly by
  551. // a mod, otherwise a malicious mod could override this function and
  552. // steal its return value.
  553. lua_Debug info;
  554. // Make sure there's only one item below this function on the stack...
  555. if (lua_getstack(L, 2, &info))
  556. return false;
  557. FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
  558. FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
  559. // ...and that that item is the main file scope.
  560. if (strcmp(info.what, "main") != 0)
  561. return false;
  562. // Mod must be listed in secure.http_mods or secure.trusted_mods
  563. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  564. if (!lua_isstring(L, -1))
  565. return false;
  566. std::string mod_name = readParam<std::string>(L, -1);
  567. std::string value = g_settings->get(setting);
  568. value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
  569. auto mod_list = str_split(value, ',');
  570. return CONTAINS(mod_list, mod_name);
  571. }
  572. int ScriptApiSecurity::sl_g_dofile(lua_State *L)
  573. {
  574. int nret = sl_g_loadfile(L);
  575. if (nret != 1) {
  576. lua_error(L);
  577. // code after this function isn't executed
  578. }
  579. int top_precall = lua_gettop(L);
  580. lua_call(L, 0, LUA_MULTRET);
  581. // Return number of arguments returned by the function,
  582. // adjusting for the function being poped.
  583. return lua_gettop(L) - (top_precall - 1);
  584. }
  585. int ScriptApiSecurity::sl_g_load(lua_State *L)
  586. {
  587. size_t len;
  588. const char *buf;
  589. std::string code;
  590. const char *chunk_name = "=(load)";
  591. luaL_checktype(L, 1, LUA_TFUNCTION);
  592. if (!lua_isnone(L, 2)) {
  593. luaL_checktype(L, 2, LUA_TSTRING);
  594. chunk_name = lua_tostring(L, 2);
  595. }
  596. while (true) {
  597. lua_pushvalue(L, 1);
  598. lua_call(L, 0, 1);
  599. int t = lua_type(L, -1);
  600. if (t == LUA_TNIL) {
  601. break;
  602. }
  603. if (t != LUA_TSTRING) {
  604. lua_pushnil(L);
  605. lua_pushliteral(L, "Loader didn't return a string");
  606. return 2;
  607. }
  608. buf = lua_tolstring(L, -1, &len);
  609. code += std::string(buf, len);
  610. lua_pop(L, 1); // Pop return value
  611. }
  612. if (!safeLoadString(L, code, chunk_name)) {
  613. lua_pushnil(L);
  614. lua_insert(L, -2);
  615. return 2;
  616. }
  617. return 1;
  618. }
  619. int ScriptApiSecurity::sl_g_loadfile(lua_State *L)
  620. {
  621. #ifndef SERVER
  622. ScriptApiBase *script = ModApiBase::getScriptApiBase(L);
  623. // Client implementation
  624. if (script->getType() == ScriptingType::Client) {
  625. std::string path = readParam<std::string>(L, 1);
  626. const std::string *contents = script->getClient()->getModFile(path);
  627. if (!contents) {
  628. std::string error_msg = "Coudln't find script called: " + path;
  629. lua_pushnil(L);
  630. lua_pushstring(L, error_msg.c_str());
  631. return 2;
  632. }
  633. std::string chunk_name = "@" + path;
  634. if (!safeLoadString(L, *contents, chunk_name.c_str())) {
  635. lua_pushnil(L);
  636. lua_insert(L, -2);
  637. return 2;
  638. }
  639. return 1;
  640. }
  641. #endif
  642. // Server implementation
  643. const char *path = NULL;
  644. if (lua_isstring(L, 1)) {
  645. path = lua_tostring(L, 1);
  646. CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL);
  647. }
  648. if (!safeLoadFile(L, path)) {
  649. lua_pushnil(L);
  650. lua_insert(L, -2);
  651. return 2;
  652. }
  653. return 1;
  654. }
  655. int ScriptApiSecurity::sl_g_loadstring(lua_State *L)
  656. {
  657. const char *chunk_name = "=(load)";
  658. luaL_checktype(L, 1, LUA_TSTRING);
  659. if (!lua_isnone(L, 2)) {
  660. luaL_checktype(L, 2, LUA_TSTRING);
  661. chunk_name = lua_tostring(L, 2);
  662. }
  663. size_t size;
  664. const char *code = lua_tolstring(L, 1, &size);
  665. std::string code_s(code, size);
  666. if (!safeLoadString(L, code_s, chunk_name)) {
  667. lua_pushnil(L);
  668. lua_insert(L, -2);
  669. return 2;
  670. }
  671. return 1;
  672. }
  673. int ScriptApiSecurity::sl_g_require(lua_State *L)
  674. {
  675. lua_pushliteral(L, "require() is disabled when mod security is on.");
  676. return lua_error(L);
  677. }
  678. int ScriptApiSecurity::sl_io_open(lua_State *L)
  679. {
  680. bool with_mode = lua_gettop(L) > 1;
  681. luaL_checktype(L, 1, LUA_TSTRING);
  682. const char *path = lua_tostring(L, 1);
  683. bool write_requested = false;
  684. if (with_mode) {
  685. luaL_checktype(L, 2, LUA_TSTRING);
  686. const char *mode = lua_tostring(L, 2);
  687. write_requested = strchr(mode, 'w') != NULL ||
  688. strchr(mode, '+') != NULL ||
  689. strchr(mode, 'a') != NULL;
  690. }
  691. CHECK_SECURE_PATH_INTERNAL(L, path, write_requested, NULL);
  692. push_original(L, "io", "open");
  693. lua_pushvalue(L, 1);
  694. if (with_mode) {
  695. lua_pushvalue(L, 2);
  696. }
  697. lua_call(L, with_mode ? 2 : 1, 2);
  698. return 2;
  699. }
  700. int ScriptApiSecurity::sl_io_input(lua_State *L)
  701. {
  702. if (lua_isstring(L, 1)) {
  703. const char *path = lua_tostring(L, 1);
  704. CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL);
  705. }
  706. push_original(L, "io", "input");
  707. lua_pushvalue(L, 1);
  708. lua_call(L, 1, 1);
  709. return 1;
  710. }
  711. int ScriptApiSecurity::sl_io_output(lua_State *L)
  712. {
  713. if (lua_isstring(L, 1)) {
  714. const char *path = lua_tostring(L, 1);
  715. CHECK_SECURE_PATH_INTERNAL(L, path, true, NULL);
  716. }
  717. push_original(L, "io", "output");
  718. lua_pushvalue(L, 1);
  719. lua_call(L, 1, 1);
  720. return 1;
  721. }
  722. int ScriptApiSecurity::sl_io_lines(lua_State *L)
  723. {
  724. if (lua_isstring(L, 1)) {
  725. const char *path = lua_tostring(L, 1);
  726. CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL);
  727. }
  728. int top_precall = lua_gettop(L);
  729. push_original(L, "io", "lines");
  730. lua_pushvalue(L, 1);
  731. lua_call(L, 1, LUA_MULTRET);
  732. // Return number of arguments returned by the function,
  733. // adjusting for the function being poped.
  734. return lua_gettop(L) - top_precall;
  735. }
  736. int ScriptApiSecurity::sl_os_rename(lua_State *L)
  737. {
  738. luaL_checktype(L, 1, LUA_TSTRING);
  739. const char *path1 = lua_tostring(L, 1);
  740. CHECK_SECURE_PATH_INTERNAL(L, path1, true, NULL);
  741. luaL_checktype(L, 2, LUA_TSTRING);
  742. const char *path2 = lua_tostring(L, 2);
  743. CHECK_SECURE_PATH_INTERNAL(L, path2, true, NULL);
  744. push_original(L, "os", "rename");
  745. lua_pushvalue(L, 1);
  746. lua_pushvalue(L, 2);
  747. lua_call(L, 2, 2);
  748. return 2;
  749. }
  750. int ScriptApiSecurity::sl_os_remove(lua_State *L)
  751. {
  752. luaL_checktype(L, 1, LUA_TSTRING);
  753. const char *path = lua_tostring(L, 1);
  754. CHECK_SECURE_PATH_INTERNAL(L, path, true, NULL);
  755. push_original(L, "os", "remove");
  756. lua_pushvalue(L, 1);
  757. lua_call(L, 1, 2);
  758. return 2;
  759. }
  760. int ScriptApiSecurity::sl_os_setlocale(lua_State *L)
  761. {
  762. const bool cat = lua_gettop(L) > 1;
  763. // Don't allow changes
  764. if (!lua_isnoneornil(L, 1)) {
  765. lua_pushnil(L);
  766. return 1;
  767. }
  768. push_original(L, "os", "setlocale");
  769. lua_pushnil(L);
  770. if (cat)
  771. lua_pushvalue(L, 2);
  772. lua_call(L, cat ? 2 : 1, 1);
  773. return 1;
  774. }