Exemple #1
0
static void fatal(lua_State * L, const char * msg)
{
    dump_lua_stack(L, 0);
    fprintf(stderr, "%s\nSTACK\n%s", msg, lua_tostring(L, -1));
    lua_pop(L, 1);
    fflush(stderr);
    exit(1);
}
Exemple #2
0
/* Map script interpreter:
 * Called with "rule" and "exec_policy" already in lua's stack,
 * leaves (possibly modified) "rule" and "exec_policy" to lua's stack.
*/
char *sb_execve_map_script_interpreter(
    const char *interpreter,
    const char *interp_arg,
    const char *mapped_script_filename,
    const char *orig_script_filename,
    char ***argv,
    char ***envp)
{
    struct lua_instance *luaif;
    char *mapped_interpreter;
    int new_argc, new_envc;
    int res;

    luaif = get_lua();
    if (!luaif) return(0);

    if (!argv || !envp) {
        SB_LOG(SB_LOGLEVEL_ERROR,
               "ERROR: sb_execve_map_script_interpreter: "
               "(argv || envp) == NULL");
        release_lua(luaif);
        return NULL;
    }

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: gettop=%d"
           " interpreter=%s interp_arg=%s "
           "mapped_script_filename=%s orig_script_filename=%s",
           lua_gettop(luaif->lua), interpreter, interp_arg,
           mapped_script_filename, orig_script_filename);

    lua_getfield(luaif->lua, LUA_GLOBALSINDEX,
                 "sb_execve_map_script_interpreter");

    /* stack now contains "rule", "exec_policy" and
     * "sb_execve_map_script_interpreter".
     * move "sb_execve_map_script_interpreter" to the bottom : */
    lua_insert(luaif->lua, -3);

    lua_pushstring(luaif->lua, interpreter);
    if (interp_arg) lua_pushstring(luaif->lua, interp_arg);
    else lua_pushnil(luaif->lua);
    lua_pushstring(luaif->lua, mapped_script_filename);
    lua_pushstring(luaif->lua, orig_script_filename);
    strvec_to_lua_table(luaif, *argv);
    strvec_to_lua_table(luaif, *envp);

    /* args: rule, exec_policy, interpreter, interp_arg,
     *	 mapped_script_filename, orig_script_filename,
     *	 argv, envp
     * returns: rule, policy, result, mapped_interpreter, #argv, argv,
     *	#envp, envp
     * "result" is one of:
     *  0: argv / envp were modified; mapped_interpreter was set
     *  1: argv / envp were not modified; mapped_interpreter was set
     * -1: deny exec.
    */
    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter M1", luaif->lua);
    }
    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: call lua, gettop=%d",
           lua_gettop(luaif->lua));
    lua_call(luaif->lua, 8, 8);
    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: return from lua, gettop=%d",
           lua_gettop(luaif->lua));
    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter M2", luaif->lua);
    }

    mapped_interpreter = (char *)lua_tostring(luaif->lua, -5);
    if (mapped_interpreter) mapped_interpreter = strdup(mapped_interpreter);

    res = lua_tointeger(luaif->lua, -6);
    switch (res) {

    case 0:
        /* exec arguments were modified, replace contents of
         * argv and envp vectors */
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: Updated argv&envp");

        strvec_free(*argv);
        new_argc = lua_tointeger(luaif->lua, -4);
        lua_string_table_to_strvec(luaif, -3, argv, new_argc);

        new_envc = lua_tointeger(luaif->lua, -2);
        strvec_free(*envp);
        lua_string_table_to_strvec(luaif, -1, envp, new_envc);

        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;

    case 1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: argv&envp were not modified");
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;

    case 2:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: use sbox_map_path_for_exec");
        /* remove all return values from the stack. */
        lua_pop(luaif->lua, 8);
        if (mapped_interpreter) free(mapped_interpreter);
        mapped_interpreter = NULL;
        {
            mapping_results_t	mapping_result;

            clear_mapping_results_struct(&mapping_result);
            sbox_map_path_for_exec("script_interp",
                                   interpreter, &mapping_result);
            if (mapping_result.mres_result_buf) {
                mapped_interpreter =
                    strdup(mapping_result.mres_result_buf);
            }
            free_mapping_results(&mapping_result);
        }
        SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: "
               "interpreter=%s mapped_interpreter=%s",
               interpreter, mapped_interpreter);
        break;

    case -1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: exec denied");
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        if (mapped_interpreter) free(mapped_interpreter);
        mapped_interpreter = NULL;
        break;

    default:
        SB_LOG(SB_LOGLEVEL_ERROR,
               "sb_execve_map_script_interpreter: Unsupported result %d", res);
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;
    }


    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter E2", luaif->lua);
    }

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: at exit, gettop=%d",
           lua_gettop(luaif->lua));
    release_lua(luaif);
    return mapped_interpreter;
}
Exemple #3
0
/* Exec Postprocessing:
 * Called with "rule" and "exec_policy" already in lua's stack.
*/
int sb_execve_postprocess(char *exec_type,
                          char **mapped_file,
                          char **filename,
                          const char *binary_name,
                          char ***argv,
                          char ***envp)
{
    struct lua_instance *luaif;
    int res, new_argc;
    int replace_environment = 0;

    luaif = get_lua();
    if (!luaif) return(0);

    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_postprocess entry", luaif->lua);
    }

    if (!argv || !envp) {
        SB_LOG(SB_LOGLEVEL_ERROR,
               "ERROR: sb_argvenvp: (argv || envp) == NULL");
        release_lua(luaif);
        return -1;
    }

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_postprocess: gettop=%d", lua_gettop(luaif->lua));

    lua_getfield(luaif->lua, LUA_GLOBALSINDEX, "sb_execve_postprocess");

    /* stack now contains "rule", "exec_policy" and "sb_execve_postprocess".	 * move "sb_execve_postprocess" to the bottom : */
    lua_insert(luaif->lua, -3);

    lua_pushstring(luaif->lua, exec_type);
    lua_pushstring(luaif->lua, *mapped_file);
    lua_pushstring(luaif->lua, *filename);
    lua_pushstring(luaif->lua, binary_name);
    strvec_to_lua_table(luaif, *argv);
    strvec_to_lua_table(luaif, *envp);

    /* args: rule, exec_policy, exec_type, mapped_file, filename,
     *	 binaryname, argv, envp
     * returns: res, mapped_file, filename, argc, argv, envc, envp */
    lua_call(luaif->lua, 8, 7);

    res = lua_tointeger(luaif->lua, -7);
    switch (res) {

    case 0:
        /* exec arguments were modified, replace contents of
         * argv vector */
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_postprocess: Updated argv&envp");
        free(*mapped_file);
        *mapped_file = strdup(lua_tostring(luaif->lua, -6));

        free(*filename);
        *filename = strdup(lua_tostring(luaif->lua, -5));

        strvec_free(*argv);
        new_argc = lua_tointeger(luaif->lua, -4);
        lua_string_table_to_strvec(luaif, -3, argv, new_argc);

        replace_environment = 1;
        break;

    case 1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_postprocess: argv was not modified");
        /* always update environment when we are going to exec */
        replace_environment = 1;
        break;

    case -1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_postprocess: exec denied");
        break;

    default:
        SB_LOG(SB_LOGLEVEL_ERROR,
               "sb_execve_postprocess: Unsupported result %d", res);
        break;
    }

    if (replace_environment) {
        int new_envc;
        new_envc = lua_tointeger(luaif->lua, -2);
        strvec_free(*envp);
        lua_string_table_to_strvec(luaif, -1, envp, new_envc);
    }

    /* remove sb_execve_postprocess return values from the stack.  */
    lua_pop(luaif->lua, 7);

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_postprocess: at exit, gettop=%d", lua_gettop(luaif->lua));
    release_lua(luaif);
    return res;
}
/*
* Function used as a callback for all Lua functions passed through
* get_as3_value_from_lua_stack()
*/
AS3_Val as3_lua_callback(void * data, AS3_Val args)
{
  /* WARNING: Panic alert! Use L*_FN checkers here! */

  SPAM(("as3_lua_callback(): begin"));

  AS3_Val res;
  LuaFunctionCallbackData * func_data = (LuaFunctionCallbackData *) data;
  int nargs = 0;
  int status = 0;
  int results_base = 0;
  lua_State * L = func_data->L;
  if (L == NULL)
  {
    /* TODO: Should we crash here?
    fatal_error("state expired"); / * Does not return * /
    */
    sztrace("as3_lua_callback: state expired");
    return AS3_Undefined();
  }

  { /* A new scope for LCALL to work (C89 conformance) */
    LCALL(L, stack);

    /* TODO: Cache that with lua_ref, it is faster */
    lua_getfield(L, LUA_REGISTRYINDEX, AS3LUA_CALLBACKS);

    /* TODO: Assert we have a table here */

    lua_rawgeti(L, -1, func_data->ref); /* push stored function */

    if (lua_istable(L, -1) == 0) /* Probably nil */
    {
      lua_pop(L, 1); /* Pop bad callback table */
      LCHECK_FN(L, stack, 0, fatal_error);

      fatal_error("function callback not found"); /* Does not return */
    }

    lua_rawgeti(L, -1, AS3LUA_CBFNINDEX); /* push stored callback function */

 #ifdef DO_SPAM
  {
    SPAM(("as3_lua_callback(): AS3 arguments"));
    AS3_Val a = AS3_CallS("join", args, AS3_Undefined());
    AS3_Trace(a);
    SAFE_RELEASE(a);
  }
#endif /* DO_SPAM */


    /* TODO: Assert we have Lua function (or other callable object) on the top of the stack */

    LCHECK_FN(L, stack, 2 + 1, fatal_error);

    nargs = push_as3_array_to_lua_stack(L, args); /* push arguments */

#ifdef DO_SPAM
    /* TODO: Remove */
    lua_pushcfunction(L, as3_trace);
    dump_lua_stack(L, LBASE(L, stack) + 2 + 1);
    lua_pushliteral(L, "ARGUMENTS");
    lua_pushnumber(L, nargs);
    lua_call(L, 3, 0);
#endif /* DO_SPAM */

    LCHECK_FN(L, stack, 2 + 1 + nargs, fatal_error);

    results_base = LBASE(L, stack) + 2;
    status = do_pcall_with_traceback(L, nargs, LUA_MULTRET);
    if (status != 0)
    {
      const char * msg = NULL;

      LCHECK_FN(L, stack, 2 + 1, fatal_error); /* Tables and error message */
      lua_remove(L, -2); /* Remove AS3LUA_CALLBACKS table */
      lua_remove(L, -2); /* Remove holder table */
      LCHECK_FN(L, stack, 1, fatal_error); /* Only error message */

      /* Error message is on stack */
      /* NOTE: It is not necessary string! If we want to preserve its type, see lua_DoString. */

      if (lua_tostring(L, -1) == NULL)
      {
        lua_pop(L, 1);
        lua_pushliteral(L, "(non-string)");
      }

      LCHECK_FN(L, stack, 1, fatal_error);

      lua_pushliteral(L, "Error in Lua callback:\n");
      lua_insert(L, -2);

      LCHECK_FN(L, stack, 2, fatal_error);

      lua_concat(L, 2);

      LCHECK_FN(L, stack, 1, fatal_error);

      sztrace((char *)lua_tostring(L, -1));

      /* TODO: ?! */
      /* lua_error(L); */

      msg = lua_tostring(L, -1);
      lua_pop(L, 1);

/*
      fatal_error(msg); / * Does not return * /
*/
    }

    /* Process results */

#ifdef DO_SPAM
    /* TODO: Remove */
    /*
    lua_pushcfunction(L, as3_trace);
    lua_pushliteral(L, "STACK");
    dump_lua_stack(L, results_base);
    lua_call(L, 2, 0);
    */
#endif /* DO_SPAM */

    res = create_as3_value_from_lua_stack(L, results_base + 1, LTOP(L, stack), TRUE);

#ifdef DO_SPAM
    SPAM(("as3_lua_callback() result type"));
    AS3_Trace(AS3_Call(getQualifiedClassName_method, NULL, AS3_Array("AS3ValType", res)));
#endif /* DO_SPAM */

    lua_settop(L, LBASE(L, stack)); /* Cleanup results and two holder tables */

    SPAM(("as3_lua_callback(): end"));

    return res;
  }

  /* Unreachable */
}
Exemple #5
0
/* note: this expects that the lua stack already contains the mapping rule,
 * needed by sbox_translate_path (lua code).
 * at exit the rule is still there.
*/
char *call_lua_function_sbox_translate_path(
	const path_mapping_context_t *ctx,
	int result_log_level,
	const char *abs_clean_virtual_path,
	int *flagsp,
	char **exec_policy_name_ptr)
{
	struct sb2context	*sb2ctx = ctx->pmc_sb2ctx;
	int flags;
	char *host_path = NULL;

	SB_LOG(SB_LOGLEVEL_NOISE, "calling sbox_translate_path for %s(%s), fn_class=0x%X",
		ctx->pmc_func_name, abs_clean_virtual_path, ctx->pmc_fn_class);
	if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
	SB_LOG(SB_LOGLEVEL_NOISE,
		"call_lua_function_sbox_translate_path: gettop=%d",
		lua_gettop(sb2ctx->lua));
	if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
		dump_lua_stack("call_lua_function_sbox_translate_path entry",
			sb2ctx->lua);
	}

	lua_getfield(sb2ctx->lua, LUA_GLOBALSINDEX, "sbox_translate_path");
	/* stack now contains the rule object and string "sbox_translate_path",
         * move the string to the bottom: */
	lua_insert(sb2ctx->lua, -2);
	/* add other parameters */
	lua_pushstring(sb2ctx->lua, ctx->pmc_binary_name);
	lua_pushstring(sb2ctx->lua, ctx->pmc_func_name);
	lua_pushstring(sb2ctx->lua, abs_clean_virtual_path);
	lua_pushnumber(sb2ctx->lua, ctx->pmc_fn_class);
	 /* 5 arguments, returns rule,policy,path,flags */
	lua_call(sb2ctx->lua, 5, 4);

	host_path = (char *)lua_tostring(sb2ctx->lua, -2);
	if (host_path && (*host_path != '/')) {
		SB_LOG(SB_LOGLEVEL_ERROR,
			"Mapping failed: Result is not absolute ('%s'->'%s')",
			abs_clean_virtual_path, host_path);
		host_path = NULL;
	} else if (host_path) {
		host_path = strdup(host_path);
	}
	flags = lua_tointeger(sb2ctx->lua, -1);
	check_mapping_flags(flags, "sbox_translate_path");
	if (flagsp) *flagsp = flags;

	if (exec_policy_name_ptr) {
		char *exec_policy_name;

		if (*exec_policy_name_ptr) {
			free(*exec_policy_name_ptr);
			*exec_policy_name_ptr = NULL;
		}
		exec_policy_name = (char *)lua_tostring(sb2ctx->lua, -3);
		if (exec_policy_name) {
			*exec_policy_name_ptr = strdup(exec_policy_name);
		}
	}

	lua_pop(sb2ctx->lua, 3); /* leave the rule to the stack */

	if (host_path) {
		char *new_host_path = clean_and_log_fs_mapping_result(ctx,
			abs_clean_virtual_path, result_log_level, host_path, flags);
		free(host_path);
		host_path = new_host_path;
	}
	if (!host_path) {
		SB_LOG(SB_LOGLEVEL_ERROR,
			"No result from sbox_translate_path for: %s '%s'",
			ctx->pmc_func_name, abs_clean_virtual_path);
	}
	SB_LOG(SB_LOGLEVEL_NOISE,
		"call_lua_function_sbox_translate_path: at exit, gettop=%d",
		lua_gettop(sb2ctx->lua));
	if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
		dump_lua_stack("call_lua_function_sbox_translate_path exit",
			sb2ctx->lua);
	}
	return(host_path);
}
Exemple #6
0
/* Exec Postprocessing:
*/
int lb_execve_postprocess(const char *exec_type,
	const char *exec_policy_name,
	char **mapped_file,
	char **filename,
	const char *binary_name,
	char ***argv,
	char ***envp)
{
	struct lbcontext *lbctx;
	int res, new_argc;
	int replace_environment = 0;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "lb_execve_postprocess");
	lbctx = get_lbcontext_lua();
	if (!lbctx) return(0);

	if(LB_LOG_IS_ACTIVE(LB_LOGLEVEL_NOISE3)) {
		dump_lua_stack("lb_execve_postprocess entry", lbctx->lua);
	}

	if (!argv || !envp) {
		LB_LOG(LB_LOGLEVEL_ERROR,
			"ERROR: lb_argvenvp: (argv || envp) == NULL");
		release_lbcontext(lbctx);
		return -1;
	}

	LB_LOG(LB_LOGLEVEL_NOISE,
		"lb_execve_postprocess: gettop=%d", lua_gettop(lbctx->lua));

	lua_getfield(lbctx->lua, LUA_GLOBALSINDEX, "lb_execve_postprocess");

	lua_pushstring(lbctx->lua, exec_policy_name);
	lua_pushstring(lbctx->lua, exec_type);
	lua_pushstring(lbctx->lua, *mapped_file);
	lua_pushstring(lbctx->lua, *filename);
	lua_pushstring(lbctx->lua, binary_name);
	strvec_to_lua_table(lbctx, *argv);
	strvec_to_lua_table(lbctx, *envp);

	/* args: exec_policy_name, exec_type, mapped_file, filename,
	 *	 binaryname, argv, envp
	 * returns: res, mapped_file, filename, argc, argv, envc, envp */
	lua_call(lbctx->lua, 7, 7);
	
	res = lua_tointeger(lbctx->lua, -7);
	switch (res) {

	case 0:
		/* exec arguments were modified, replace contents of
		 * argv vector */
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"lb_execve_postprocess: Updated argv&envp");
		free(*mapped_file);
		*mapped_file = strdup(lua_tostring(lbctx->lua, -6));

		free(*filename);
		*filename = strdup(lua_tostring(lbctx->lua, -5));

		strvec_free(*argv);
		new_argc = lua_tointeger(lbctx->lua, -4);
		lua_string_table_to_strvec(lbctx->lua, -3, argv, new_argc);

		replace_environment = 1;
		break;

	case 1:
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"lb_execve_postprocess: argv was not modified");
		/* always update environment when we are going to exec */
		replace_environment = 1;
		break;

	case -1:
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"lb_execve_postprocess: exec denied");
		break;

	default:
		LB_LOG(LB_LOGLEVEL_ERROR,
			"lb_execve_postprocess: Unsupported result %d", res);
		break;
	}

	if (replace_environment) {
		int new_envc;
		new_envc = lua_tointeger(lbctx->lua, -2);
		strvec_free(*envp);
		lua_string_table_to_strvec(lbctx->lua, -1, envp, new_envc);
	}

	/* remove lb_execve_postprocess return values from the stack.  */
	lua_pop(lbctx->lua, 7);

	STOP_AND_REPORT_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, mapped_file);

	LB_LOG(LB_LOGLEVEL_NOISE,
		"lb_execve_postprocess: at exit, gettop=%d", lua_gettop(lbctx->lua));
	release_lbcontext(lbctx);
	return res;
}