コード例 #1
0
static char* test_serialize_binary()
{
  size_t size = 512;
  lsb_output_buffer b;
  lsb_err_value ret = lsb_init_output_buffer(&b, size);
  mu_assert(ret == NULL, "received: %s", lsb_err_string(ret));
  lsb_serialize_binary(&b, "a\r\n\\\"", 5);
  mu_assert(b.pos == 9, "received %d", (int)b.pos);
  mu_assert(memcmp(b.buf, "a\\r\\n\\\\\\\"", 5) == 0, "received %.*s", 9,
            b.buf);
  lsb_free_output_buffer(&b);
  return NULL;
}
コード例 #2
0
ファイル: luasandbox.c プロジェクト: AlexTsr/lua_sandbox
lsb_lua_sandbox* lsb_create(void *parent,
                            const char *lua_file,
                            const char *cfg,
                            lsb_logger logger)
{
  if (!lua_file) {
    if (logger) logger(__FUNCTION__, 3, "lua_file must be specified");
    return NULL;
  }

  if (!set_tz()) {
    if (logger) logger(__FUNCTION__, 3, "fail to set the TZ to UTC");
    return NULL;
  }

  set_random_seed();

  lsb_lua_sandbox *lsb = malloc(sizeof*lsb);
  if (!lsb) {
    if (logger) logger(__FUNCTION__, 3, "memory allocation failed");
    return NULL;
  }
  memset(lsb->usage, 0, sizeof(lsb->usage));

#ifdef LUA_JIT
  lsb->lua = luaL_newstate();
#else
  lsb->lua = lua_newstate(memory_manager, lsb);
#endif

  if (!lsb->lua) {
    if (logger) logger(__FUNCTION__, 3, "lua state creation failed");
    free(lsb);
    return NULL;
  }

  // add the config to the lsb_config registry table
  lua_State *lua_cfg = load_sandbox_config(cfg, logger);
  if (!lua_cfg) {
    lua_close(lsb->lua);
    free(lsb);
    return NULL;
  }
  lua_pushnil(lua_cfg);
  lua_pushvalue(lua_cfg, LUA_GLOBALSINDEX);
  copy_table(lsb->lua, lua_cfg, logger);
  lua_pop(lua_cfg, 2);
  lua_close(lua_cfg);
  size_t ml = get_usage_config(lsb->lua, -1, "memory_limit");
  size_t il = get_usage_config(lsb->lua, -1, "instruction_limit");
  size_t ol = get_usage_config(lsb->lua, -1, "output_limit");
  lua_setfield(lsb->lua, LUA_REGISTRYINDEX, LSB_CONFIG_TABLE);
  lua_pushcclosure(lsb->lua, &read_config, 0);
  lua_setglobal(lsb->lua, "read_config");

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

  lsb->parent = parent;
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = ml;
  lsb->usage[LSB_UT_INSTRUCTION][LSB_US_LIMIT] = il;
  lsb->usage[LSB_UT_OUTPUT][LSB_US_LIMIT] = ol;
  lsb->state = LSB_UNKNOWN;
  lsb->error_message[0] = 0;
  lsb->lua_file = malloc(strlen(lua_file) + 1);
  lsb->state_file = NULL;

  if (!lsb->lua_file || lsb_init_output_buffer(&lsb->output, ol)) {
    if (logger) logger(__FUNCTION__, 3, "memory allocation failed failed");
    lsb_free_output_buffer(&lsb->output);
    free(lsb->lua_file);
    lua_close(lsb->lua);
    lsb->lua = NULL;
    free(lsb);
    return NULL;
  }
  strcpy(lsb->lua_file, lua_file);
  return lsb;
}
コード例 #3
0
lsb_err_value preserve_global_data(lsb_lua_sandbox *lsb)
{

  if (!lsb->lua || !lsb->state_file) {
    return NULL;
  }
  lua_sethook(lsb->lua, NULL, 0, 0);

  // make sure the string library is loaded before we start
  lua_getglobal(lsb->lua, LUA_STRLIBNAME);
  if (!lua_istable(lsb->lua, -1)) {
    lua_getglobal(lsb->lua, "require");
    if (!lua_iscfunction(lsb->lua, -1)) {
      snprintf(lsb->error_message, LSB_ERROR_SIZE,
               "preserve_global_data 'require' function not found");
      return LSB_ERR_LUA;
    }
    lua_pushstring(lsb->lua, LUA_STRLIBNAME);
    if (lua_pcall(lsb->lua, 1, 1, 0)) {
      int len = snprintf(lsb->error_message, LSB_ERROR_SIZE,
                         "preserve_global_data failed loading 'string'");
      if (len >= LSB_ERROR_SIZE || len < 0) {
        lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
      }
      return LSB_ERR_LUA;
    }
  }
  lua_pop(lsb->lua, 1);

  lua_pushvalue(lsb->lua, LUA_GLOBALSINDEX);

  FILE *fh = fopen(lsb->state_file, "wb" CLOSE_ON_EXEC);
  if (fh == NULL) {
    int len = snprintf(lsb->error_message, LSB_ERROR_SIZE,
                       "preserve_global_data could not open: %s",
                       lsb->state_file);
    if (len >= LSB_ERROR_SIZE || len < 0) {
      lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
    }
    return LSB_ERR_LUA;;
  }

  lsb_err_value ret = NULL;
  serialization_data data;
  data.fh = fh;

// Clear the sandbox limits during preservation.
#ifdef LUA_JIT
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT, 0);
#else
//  size_t limit = lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT];
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = 0;
#endif
//  size_t cur_output_size = lsb->output.size;
//  size_t max_output_size = lsb->output.maxsize;
  lsb->output.maxsize = 0;
// end clear

  data.tables.size = 64;
  data.tables.pos = 0;
  data.tables.array = malloc(data.tables.size * sizeof(table_ref));
  if (data.tables.array == NULL || lsb_init_output_buffer(&data.keys, 0)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "preserve_global_data out of memory");
    ret = LSB_ERR_UTIL_OOM;
  } else {
    fprintf(data.fh, "if %s and %s ~= %d then return end\n",
            preservation_version,
            preservation_version,
            get_preservation_version(lsb->lua));
    ret = lsb_outputs(&data.keys, "_G", 2);
    if (!ret) {
      data.keys.pos += 1; // preserve the NUL in this use case
      data.globals = lua_topointer(lsb->lua, -1);
      lua_checkstack(lsb->lua, 2);
      lua_pushnil(lsb->lua);
      while (!ret && lua_next(lsb->lua, -2) != 0) {
        ret = serialize_kvp(lsb, &data, 0);
        lua_pop(lsb->lua, 1);
      }
    }
    lua_pop(lsb->lua, lua_gettop(lsb->lua));
    // Wipe the entire Lua stack.  Since incremental cleanup on failure
    // was added the stack should only contain table _G.
  }
  free(data.tables.array);
  lsb_free_output_buffer(&data.keys);
  fclose(fh);
  if (ret) remove(lsb->state_file);

// Uncomment if we start preserving state when not destroying the sandbox
// Note: serialization uses the output buffer, inprogress output can be
// destroyed if the user was collecting output between calls.
/*
// Restore the sandbox limits after preservation
#ifdef LUA_JIT
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT,
         lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]);
#else
  lua_gc(lsb->lua, LUA_GCCOLLECT, 0);
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = limit;
  lsb->usage[LSB_UT_MEMORY][LSB_US_MAXIMUM] =
    lsb->usage[LSB_UT_MEMORY][LSB_US_CURRENT];
#endif
  lsb->output.maxsize = max_output_size;
  lsb_clear_output_buffer(lsb->output);
  if (lsb->output.size > cur_output_size) {
    void* ptr = realloc(lsb->output.data, cur_output_size);
    if (!ptr) return 1;
    lsb->output.data = ptr;
    lsb->output.size = cur_output_size;
  }
// end restore
*/
  return ret;
}
コード例 #4
0
ファイル: hs_output_plugins.c プロジェクト: dbaba/hindsight
static hs_output_plugin*
create_output_plugin(lsb_message_match_builder *mmb, const hs_config *cfg,
                     hs_sandbox_config *sbc)
{
  char *state_file = NULL;
  char lua_file[HS_MAX_PATH];
  if (!hs_get_fqfn(sbc->dir, sbc->filename, lua_file, sizeof(lua_file))) {
    hs_log(NULL, g_module, 3, "%s failed to construct the lua_file path",
           sbc->cfg_name);
    return NULL;
  }

  hs_output_plugin *p = calloc(1, sizeof(hs_output_plugin));
  if (!p) {
    hs_log(NULL, g_module, 2, "%s hs_output_plugin memory allocation failed",
           sbc->cfg_name);
    return NULL;
  }

  if (pthread_mutex_init(&p->cp_lock, NULL)) {
    free(p);
    hs_log(NULL, g_module, 3, "%s pthread_mutex_init failed", sbc->cfg_name);
    return NULL;
  }

  p->list_index = -1;
  p->sequence_id = 1;
  p->ticker_interval = sbc->ticker_interval;
  int stagger = p->ticker_interval > 60 ? 60 : p->ticker_interval;
  // distribute when the timer_events will fire
  if (stagger) {
    p->ticker_expires = time(NULL) + rand() % stagger;
  }

  if (sbc->async_buffer_size > 0) {
    p->async_len = sbc->async_buffer_size;
    p->async_cp = calloc(p->async_len, sizeof(hs_checkpoint_pair));
    if (!p->async_cp) {
      destroy_output_plugin(p);
      hs_log(NULL, g_module, 2, "%s async buffer memory allocation failed",
             sbc->cfg_name);
      return NULL;
    }
  }

  p->mm = lsb_create_message_matcher(mmb, sbc->message_matcher);
  if (!p->mm) {
    hs_log(NULL, g_module, 3, "%s invalid message_matcher: %s", sbc->cfg_name,
           sbc->message_matcher);
    destroy_output_plugin(p);
    return NULL;
  }

  size_t len = strlen(sbc->cfg_name) + 1;
  p->name = malloc(len);
  if (!p->name) {
    hs_log(NULL, g_module, 2, "%s name memory allocation failed",
           sbc->cfg_name);
    destroy_output_plugin(p);
  }
  memcpy(p->name, sbc->cfg_name, len);

  if (sbc->preserve_data) {
    size_t len = strlen(cfg->output_path) + strlen(sbc->cfg_name) + 7;
    state_file = malloc(len);
    if (!state_file) {
      hs_log(NULL, g_module, 2, "%s state_file memory allocation failed",
             sbc->cfg_name);
      destroy_output_plugin(p);
      return NULL;
    }
    int ret = snprintf(state_file, len, "%s/%s.data", cfg->output_path,
                       sbc->cfg_name);
    if (ret < 0 || ret > (int)len - 1) {
      hs_log(NULL, g_module, 3, "%s failed to construct the state_file path",
             sbc->cfg_name);
      free(state_file);
      destroy_output_plugin(p);
      return NULL;
    }
  }
  lsb_output_buffer ob;
  if (lsb_init_output_buffer(&ob, 8 * 1024)) {
    hs_log(NULL, g_module, 3, "%s configuration memory allocation failed",
           sbc->cfg_name);
    free(state_file);
    destroy_output_plugin(p);
    return NULL;
  }
  if (!hs_get_full_config(&ob, 'o', cfg, sbc)) {
    hs_log(NULL, g_module, 3, "%s hs_get_full_config failed", sbc->cfg_name);
    lsb_free_output_buffer(&ob);
    free(state_file);
    destroy_output_plugin(p);
    return NULL;
  }
  lsb_logger logger = {.context = NULL, .cb = hs_log};
  p->hsb = lsb_heka_create_output(p, lua_file, state_file, ob.buf, &logger,
                                  update_checkpoint_callback);
  lsb_free_output_buffer(&ob);
  free(sbc->cfg_lua);
  sbc->cfg_lua = NULL;
  free(state_file);
  if (!p->hsb) {
    destroy_output_plugin(p);
    hs_log(NULL, g_module, 3, "%s lsb_heka_create_output failed",
           sbc->cfg_name);
    return NULL;
  }

  return p;
}