Exemple #1
0
int lua_sandbox_timer_event(lua_sandbox* lsb, long long ns)
{
    if (lsb == NULL || lsb->m_lua == NULL) {
        return 1;
    }

    lua_sethook(lsb->m_lua, instruction_manager, LUA_MASKCOUNT,
                lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_LIMIT]);
    lua_getglobal(lsb->m_lua, "timer_event");
    if (!lua_isfunction(lsb->m_lua, -1)) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "timer_event() function was not found");
        sandbox_terminate(lsb);
        return 1;
    }

    lua_pushnumber(lsb->m_lua, ns);
    if (lua_pcall(lsb->m_lua, 1, 0, 0) != 0) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "timer_event() %s",
                 lua_tostring(lsb->m_lua, -1));
        sandbox_terminate(lsb);
        return 1;
    }
    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];
    }
    lua_gc(lsb->m_lua, LUA_GCCOLLECT, 0);
    return 0;
}
Exemple #2
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;
}
Exemple #3
0
int lua_sandbox_process_message(lua_sandbox* lsb)
{
    if (lsb == NULL || lsb->m_lua == NULL) {
        return 1;
    }

    lua_sethook(lsb->m_lua, instruction_manager, LUA_MASKCOUNT,
                lsb->m_usage[USAGE_TYPE_INSTRUCTION][USAGE_STAT_LIMIT]);
    lua_getglobal(lsb->m_lua, "process_message");
    if (!lua_isfunction(lsb->m_lua, -1)) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "process_message() function was not found");
        sandbox_terminate(lsb);
        return 1;
    }

    if (lua_pcall(lsb->m_lua, 0, 1, 0) != 0) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "process_message() %s", lua_tostring(lsb->m_lua, -1));
        sandbox_terminate(lsb);
        return 1;
    }

    if (!lua_isnumber(lsb->m_lua, 1)) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "process_message() must return a single numeric value");
        sandbox_terminate(lsb);
        return 1;
    }

    int status = (int)lua_tointeger(lsb->m_lua, 1);
    lua_pop(lsb->m_lua, 1);
    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];
    }
    return status;
}
Exemple #4
0
char* lua_sandbox_destroy(lua_sandbox* lsb, const char* data_file)
{
    char* err = NULL;
    if (lsb == NULL) return err;

    if (lsb->m_lua != NULL && data_file != NULL && strnlen(data_file, 1) > 0) {
        if (preserve_global_data(lsb, data_file) != 0) {
            size_t len = strnlen(lsb->m_error_message, ERROR_SIZE);
            err = malloc(len + 1);
            if (err != NULL) {
                strcpy(err, lsb->m_error_message);
            }
        }
    }
    sandbox_terminate(lsb);
    free(lsb->m_output.m_data);
    free(lsb->m_lua_file);
    free(lsb);
    return err;
}
int restore_global_data(lua_sandbox* lsb, const char* data_file)
{
    unsigned configured_memory =
      lsb->m_usage[USAGE_TYPE_MEMORY][USAGE_STAT_LIMIT];
    // Increase the sandbox limits during restoration.
    lsb->m_usage[USAGE_TYPE_MEMORY][USAGE_STAT_LIMIT] = MAX_MEMORY * 2;
    // Clear the sandbox instruction limit hook.
    lua_sethook(lsb->m_lua, instruction_manager, 0, 0);

    if (luaL_dofile(lsb->m_lua, data_file) != 0) {
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "restore_global_data %s",
                 lua_tostring(lsb->m_lua, -1));
        sandbox_terminate(lsb);
        return 2;
    } else {
        lua_gc(lsb->m_lua, LUA_GCCOLLECT, 0);
        lsb->m_usage[USAGE_TYPE_MEMORY][USAGE_STAT_LIMIT] = configured_memory;
        lsb->m_usage[USAGE_TYPE_MEMORY][USAGE_STAT_MAXIMUM] =
          lsb->m_usage[USAGE_TYPE_MEMORY][USAGE_STAT_CURRENT];
    }
    return 0;
}