36 #define SANDBOX_CTX "SANDBOX_CTX"
38 static void HookFunc(
lua_State *L, lua_Debug *ar);
50 static void *LuaAlloc(
void *ud,
void *ptr,
size_t osize,
size_t nsize)
63 ctx->alloc_bytes -= osize;
65 }
else if (ptr == NULL) {
67 if (
ctx->alloc_limit != 0 &&
ctx->alloc_bytes + nsize >
ctx->alloc_limit) {
70 ctx->memory_limit_error =
true;
76 ctx->alloc_bytes += nsize;
77 ctx->alloc_bytes_allocated += nsize;
82 ssize_t diff = nsize - osize;
84 if (
ctx->alloc_limit != 0 &&
ctx->alloc_bytes + diff >
ctx->alloc_limit) {
87 ctx->memory_limit_error =
true;
95 ctx->alloc_bytes += diff;
97 ctx->alloc_bytes_allocated += (size_t)diff;
111 static int LuaBlockedFunction(
lua_State *L)
116 if (lua_getstack(L, 0, &ar) && lua_getinfo(L,
"n", &ar) && ar.name) {
117 luaL_error(L,
"Blocked Lua function called: %s", ar.name);
119 luaL_error(L,
"Blocked Lua function: name not available");
131 static bool IsAllowed(
const char *module,
const char *fname)
133 static const char *base_allowed[] = {
153 static const char *table_allowed[] = {
165 static const char *string_allowed[] = {
186 static const char *math_allowed[] = {
222 static const char *utf8_allowed[] = {
231 const char **allowed = NULL;
233 if (strcmp(module, LUA_GNAME) == 0) {
234 allowed = base_allowed;
235 }
else if (strcmp(module, LUA_TABLIBNAME) == 0) {
236 allowed = table_allowed;
237 }
else if (strcmp(module, LUA_STRLIBNAME) == 0) {
238 allowed = string_allowed;
239 }
else if (strcmp(module, LUA_MATHLIBNAME) == 0) {
240 allowed = math_allowed;
241 }
else if (strcmp(module, LUA_UTF8LIBNAME) == 0) {
242 allowed = utf8_allowed;
249 for (
int i = 0; allowed[i] != NULL; i++) {
250 if (strcmp(allowed[i], fname) == 0) {
262 static const luaL_Reg AllowedLibs[] = {
264 { LUA_GNAME, luaopen_base },
265 { LUA_TABLIBNAME, luaopen_table },
266 { LUA_STRLIBNAME, luaopen_string },
267 { LUA_MATHLIBNAME, luaopen_math },
268 { LUA_UTF8LIBNAME, luaopen_utf8 },
275 const char *module_name = luaL_checkstring(L, 1);
281 return luaL_error(L,
"Module not found: %s", module_name);
297 const uint64_t saved_limit = (sb != NULL) ? sb->
alloc_limit : 0;
302 for (lib = AllowedLibs; lib->func; lib++) {
303 luaL_requiref(L, lib->name, lib->func, 1);
308 lua_getglobal(L, lib->name);
310 while (lua_next(L, -2)) {
311 if (lua_type(L, -1) == LUA_TFUNCTION) {
312 const char *
name = lua_tostring(L, -2);
313 if (!IsAllowed(lib->name,
name)) {
315 lua_pushstring(L,
name);
316 lua_pushcfunction(L, LuaBlockedFunction);
328 lua_pushcfunction(L, SCLuaSbRequire);
329 lua_setglobal(L,
"require");
355 sb->
L = lua_newstate(LuaAlloc, sb);
362 lua_pushlightuserdata(sb->
L, sb);
363 lua_settable(sb->
L, LUA_REGISTRYINDEX);
378 lua_gettable(L, LUA_REGISTRYINDEX);
395 static void HookFunc(
lua_State *L, lua_Debug *ar)
404 luaL_error(L,
"instruction limit exceeded");
410 uint64_t cfg_limit = 0;
418 lua_gc(L, LUA_GCCOLLECT, 0);
438 lua_gc(L, LUA_GCCOLLECT, 0);