Example #1
0
int lua_sandbox_init(lua_sandbox* lsb, const char* data_file)
{
    if (lsb == NULL || lsb->m_lua != NULL) {
        return 0;
    }
    if (lsb->m_lua_file == NULL) {
        snprintf(lsb->m_error_message, ERROR_SIZE, "no Lua script provided");
        sandbox_terminate(lsb);
        return 1;
    }
    lsb->m_lua = lua_newstate(memory_manager, lsb);
    if (lsb->m_lua == NULL) {
        snprintf(lsb->m_error_message, ERROR_SIZE, "out of memory");
        sandbox_terminate(lsb);
        return 2;
    }

    load_library(lsb->m_lua, "", luaopen_base, disable_base_functions);
    load_library(lsb->m_lua, LUA_MATHLIBNAME, luaopen_math, disable_none);
    load_library(lsb->m_lua, LUA_OSLIBNAME, luaopen_os, disable_os_functions);
    load_library(lsb->m_lua, LUA_STRLIBNAME, luaopen_string, disable_none);
    load_library(lsb->m_lua, LUA_TABLIBNAME, luaopen_table, disable_none);
    luaopen_circular_buffer(lsb->m_lua);

    lua_pushlightuserdata(lsb->m_lua, (void*)lsb);
    lua_pushcclosure(lsb->m_lua, &read_message, 1);
    lua_setglobal(lsb->m_lua, "read_message");

    lua_pushlightuserdata(lsb->m_lua, (void*)lsb);
    lua_pushcclosure(lsb->m_lua, &output, 1);
    lua_setglobal(lsb->m_lua, "output");

    lua_pushlightuserdata(lsb->m_lua, (void*)lsb);
    lua_pushcclosure(lsb->m_lua, &inject_message, 1);
    lua_setglobal(lsb->m_lua, "inject_message");
    lua_sethook(lsb->m_lua, instruction_manager, LUA_MASKCOUNT,
                lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_LIMIT]);

    if (luaL_dofile(lsb->m_lua, lsb->m_lua_file) != 0) {
        snprintf(lsb->m_error_message, ERROR_SIZE, "%s",
                 lua_tostring(lsb->m_lua, -1));
        sandbox_terminate(lsb);
        return 3;
    } else {
        lua_gc(lsb->m_lua, LUA_GCCOLLECT, 0);
        lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_CURRENT] =
          instruction_usage(lsb);
        if (lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_CURRENT]
            > lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_MAXIMUM]) {
            lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_MAXIMUM] =
              lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_CURRENT];
        }
        lsb->m_status = STATUS_RUNNING;
        if (data_file != NULL && strlen(data_file) > 0) {
            return restore_global_data(lsb, data_file);
        }
    }
    return 0;
}
Example #2
0
lsb_err_value lsb_init(lsb_lua_sandbox *lsb, const char *state_file)
{
  if (!lsb) {
    return LSB_ERR_UTIL_NULL;
  }

  if (lsb->state != LSB_UNKNOWN) {
    lsb_terminate(lsb, LSB_ERR_INIT);
    return LSB_ERR_INIT;
  }

  if (state_file && strlen(state_file) > 0) {
    lsb->state_file = malloc(strlen(state_file) + 1);
    if (!lsb->state_file) {
      lsb_terminate(lsb, LSB_ERR_UTIL_OOM);
      return LSB_ERR_UTIL_OOM;
    }
    strcpy(lsb->state_file, state_file);
  }

#ifndef LUA_JIT
  size_t mem_limit = lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT];
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = 0;
#endif

  preload_modules(lsb->lua);
  // load package module
  lua_pushcfunction(lsb->lua, luaopen_package);
  lua_pushstring(lsb->lua, LUA_LOADLIBNAME);
  lua_call(lsb->lua, 1, 1);
  lua_newtable(lsb->lua);
  lua_setmetatable(lsb->lua, -2);
  lua_pop(lsb->lua, 1);

  // load base module
  lua_getglobal(lsb->lua, "require");
  if (!lua_iscfunction(lsb->lua, -1)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "lsb_init() 'require' not found");
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  }
  lua_pushstring(lsb->lua, LUA_BASELIBNAME);
  if (lua_pcall(lsb->lua, 1, 0, 0)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "lsb_init %s", lua_tostring(lsb->lua, -1));
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  }

  if (lsb->usage[LSB_UT_INSTRUCTION][LSB_US_LIMIT] != 0) {
    lua_sethook(lsb->lua, instruction_manager, LUA_MASKCOUNT,
                (int)lsb->usage[LSB_UT_INSTRUCTION][LSB_US_LIMIT]);
  } else {
    lua_sethook(lsb->lua, NULL, 0, 0);
  }
#ifdef LUA_JIT
  // todo limit
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT,
         (int)lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]);
#else
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = mem_limit;
#endif
  lua_CFunction pf = lua_atpanic(lsb->lua, unprotected_panic);
  int jump = setjmp(g_jbuf);
  if (jump || luaL_dofile(lsb->lua, lsb->lua_file) != 0) {
    int len = snprintf(lsb->error_message, LSB_ERROR_SIZE, "%s",
                       lua_tostring(lsb->lua, -1));
    if (len >= LSB_ERROR_SIZE || len < 0) {
      lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  } else {
    lua_gc(lsb->lua, LUA_GCCOLLECT, 0);
    lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT] = instruction_usage(lsb);
    if (lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT]
        > lsb->usage[LSB_UT_INSTRUCTION][LSB_US_MAXIMUM]) {
      lsb->usage[LSB_UT_INSTRUCTION][LSB_US_MAXIMUM] =
          lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT];
    }
    lsb->state = LSB_RUNNING;
    if (lsb->state_file) {
      lsb_err_value ret = restore_global_data(lsb);
      if (ret) return ret;
    }
  }
  lua_atpanic(lsb->lua, pf);
  return NULL;
}