Esempio n. 1
0
/* Find the rule and mapping requirements.
 * returns object offset if rule was found, zero if not found.
*/
ruletree_object_offset_t ruletree_get_mapping_requirements(
	ruletree_object_offset_t	rule_list_offs,
        const path_mapping_context_t *ctx,
        const struct path_entry_list *abs_virtual_source_path_list,
        int *min_path_lenp,
        int *call_translate_for_all_p,
	uint32_t fn_class)
{
	char    			*abs_virtual_source_path_string;
	ruletree_fsrule_t		*rule = NULL;
	ruletree_object_offset_t	rule_offs = 0;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "ruletree_get_mapping_requirements");
	abs_virtual_source_path_string = path_list_to_string(abs_virtual_source_path_list);

	if (rule_list_offs) {
		rule_offs = ruletree_find_rule(ctx,
			rule_list_offs, abs_virtual_source_path_string,
			strlen(abs_virtual_source_path_string),
			min_path_lenp, fn_class, &rule);
	} else {
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"%s: no rule list (,path=%s)",
			__func__, abs_virtual_source_path_string);
		rule_offs = 0;
		if (min_path_lenp) *min_path_lenp = 0;
	}

	if (call_translate_for_all_p) {
		if (rule) {
			switch (rule->rtree_fsr_action_type) {
			case LB_RULETREE_FSRULE_ACTION_CONDITIONAL_ACTIONS:
			case LB_RULETREE_FSRULE_ACTION_PROCFS:
				*call_translate_for_all_p = 1;
				break;
			default:
				*call_translate_for_all_p = 0;
				break;
			}
		} else {
			*call_translate_for_all_p = 0;
		}
	}

	free(abs_virtual_source_path_string);

	STOP_AND_REPORT_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "");
	return (rule_offs); 
}
Esempio n. 2
0
/* map using a non-standard ruleset. Not used currently,
 * but will be useful for e.g. mapping script interpreters
 * when everything is ready for "full mapping" which
 * includes full path resolution.
*/
void custom_map_path(
	const char *binary_name,
	const char *func_name,
	const char *virtual_path,
	int dont_resolve_final_symlink,
	uint32_t fn_class,
	mapping_results_t *res,
	ruletree_object_offset_t rule_list_offset)
{
	struct sb2context *sb2ctx = NULL;

	SB_LOG(SB_LOGLEVEL_DEBUG, "%s: Map %s", __func__, virtual_path);

	if (!virtual_path) {
		res->mres_result_buf = res->mres_result_path = NULL;
		res->mres_readonly = 1;
	} else {
		PROCESSCLOCK(clk1)

		sb2ctx = check_mapping_method(1);

		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, __func__);

		sbox_map_path_internal__c_engine(sb2ctx, binary_name,
			func_name, virtual_path,
			dont_resolve_final_symlink, 0, fn_class, res, rule_list_offset);

		if (res->mres_fallback_to_lua_mapping_engine &&
		    (res->mres_fallback_to_lua_mapping_engine[0] == '#')) {
			SB_LOG(SB_LOGLEVEL_ERROR,
				"C path mapping engine failed (%s), can't fallback to Lua (%s) - %s",
				res->mres_fallback_to_lua_mapping_engine, virtual_path, __func__);
		}
	}
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, virtual_path);
}
Esempio n. 3
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;
}
Esempio n. 4
0
int do_exec(int *result_errno_ptr,
	const char *exec_fn_name, const char *orig_file,
	char *const *orig_argv, char *const *orig_envp)
{
	char *new_file = NULL;
	char **new_argv = NULL;
	char **new_envp = NULL;
	int  result;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "do_exec");
	if (getenv("SBOX_DISABLE_MAPPING")) {
		/* just run it, don't worry, be happy! */
	} else {
		int	r;
		char	**my_envp_copy = NULL; /* used only for debug log */
		char	*tmp, *binaryname;
		enum binary_type type;

		tmp = strdup(orig_file);
		binaryname = strdup(basename(tmp)); /* basename may modify *tmp */
		free(tmp);

		if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
			char *buf = strvec_to_string(orig_argv);

			SB_LOG(SB_LOGLEVEL_DEBUG,
				"EXEC/Orig.args: %s : %s", orig_file, buf);
			free(buf);
		
			/* create a copy of intended environment for logging,
			 * before preprocessing */
			my_envp_copy = prepare_envp_for_do_exec(orig_file,
				binaryname, orig_envp);
		}
		
		new_envp = prepare_envp_for_do_exec(orig_file, binaryname, orig_envp);

		r = prepare_exec(exec_fn_name, NULL/*exec_policy_name: not yet known*/,
			orig_file, 0, orig_argv, orig_envp,
			&type, &new_file, &new_argv, &new_envp);

		if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
			/* find out and log if preprocessing did something */
			compare_and_log_strvec_changes("argv", orig_argv, new_argv);
			compare_and_log_strvec_changes("envp", my_envp_copy, new_envp);
		}

		if (r < 0) {
			SB_LOG(SB_LOGLEVEL_DEBUG,
				"EXEC denied by prepare_exec(), %s", orig_file);
			*result_errno_ptr = errno;
			STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Exec denied");
			return(r); /* exec denied */
		}

		if (check_envp_has_ld_preload_and_ld_library_path(
			new_envp ? new_envp : orig_envp) == 0) {

			SB_LOG(SB_LOGLEVEL_ERROR,
				"exec(%s) failed, internal configuration error: "
				"LD_LIBRARY_PATH and/or LD_PRELOAD were not set "
				"by exec mapping logic", orig_file);
			*result_errno_ptr = EINVAL;
			STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Config error");
			return(-1);
		}
	}

	errno = *result_errno_ptr; /* restore to orig.value */
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, orig_file);
	result = sb_next_execve(
		(new_file ? new_file : orig_file),
		(new_argv ? new_argv : orig_argv),
		(new_envp ? new_envp : orig_envp));
	*result_errno_ptr = errno;
	SB_LOG(SB_LOGLEVEL_DEBUG,
		"EXEC failed (%s), errno=%d", orig_file, *result_errno_ptr);
	return(result);
}
Esempio n. 5
0
static int prepare_exec(const char *exec_fn_name,
	const char *exec_policy_name,
	const char *orig_file,
	int file_has_been_mapped,
	char *const *orig_argv,
	char *const *orig_envp,
	enum binary_type *typep,
	char **new_file,  /* return value */
	char ***new_argv,
	char ***new_envp) /* *new_envp must be filled by the caller */
{
	char **my_envp = *new_envp; /* FIXME */
	const char **my_new_envp = NULL;
	const char **my_new_argv = NULL;
	char **my_argv = NULL, *my_file = NULL;
	char *binaryname, *tmp, *mapped_file;
	int err = 0;
	enum binary_type type;
	int postprocess_result = 0;
	int ret = 0; /* 0: ok to exec, ret<0: exec fails */
	int file_mode;
	uid_t file_uid;
	gid_t file_gid;
	PROCESSCLOCK(clk1)
	PROCESSCLOCK(clk4)

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "prepare_exec");
	(void)exec_fn_name; /* not yet used */
	(void)orig_envp; /* not used */

	SB_LOG(SB_LOGLEVEL_DEBUG,
		"prepare_exec(): orig_file='%s'",
		orig_file);
	SB_LOG(SB_LOGLEVEL_NOISE,
		"%s: exec_policy_name='%s'", __func__, exec_policy_name);

	tmp = strdup(orig_file);
	binaryname = strdup(basename(tmp)); /* basename may modify *tmp */
	free(tmp);
	
	my_file = strdup(orig_file);

	my_argv = duplicate_argv(orig_argv);

	if (!file_has_been_mapped) {
		PROCESSCLOCK(clk2)

		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk2, "execve_preprocess");
		if ((err = apply_exec_preprocessing_rules(&my_file, &my_argv, &my_envp)) != 0) {
			SB_LOG(SB_LOGLEVEL_ERROR, "argvenvp processing error %i", err);
		}
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk2, my_file);
	}

	/* test if mapping is enabled during the exec()..
	 * (host-* tools disable it)
	*/
	if (file_has_been_mapped) {
		/* (e.g. we came back from run_hashbang()) */
		SB_LOG(SB_LOGLEVEL_DEBUG,
			"prepare_exec(): no double mapping, my_file = %s", my_file);
		mapped_file = strdup(my_file);
	} else if (strvec_contains_prefix(my_envp, "SBOX_DISABLE_MAPPING=1", NULL)) {
		SB_LOG(SB_LOGLEVEL_DEBUG,
			"do_exec(): mapping disabled, my_file = %s", my_file);
		mapped_file = strdup(my_file);

		/* we won't call sbox_map_path_for_exec() because mapping
		 * is disabled.  */
	} else {
		/* now we have to do path mapping for my_file to find exactly
		 * what is the path we're supposed to deal with
		 */
		mapping_results_t	mapping_result;
		PROCESSCLOCK(clk3)

		clear_mapping_results_struct(&mapping_result);
		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk3, "map_path_for_exec");
		sbox_map_path_for_exec("do_exec", my_file, &mapping_result);
		mapped_file = (mapping_result.mres_result_buf ?
			strdup(mapping_result.mres_result_buf) : NULL);
		exec_policy_name = (mapping_result.mres_exec_policy_name ?
			strdup(mapping_result.mres_exec_policy_name) : NULL);
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk3, mapped_file);
			
		free_mapping_results(&mapping_result);

		SB_LOG(SB_LOGLEVEL_DEBUG,
			"do_exec(): my_file = %s, mapped_file = %s",
			my_file, mapped_file);
	}

	/*
	 * prepare_envp_for_do_exec() left us placeholder in envp array
	 * that we will fill now with fully mangled binary name.
	 */
	change_environment_variable(my_envp,
		"__SB2_REAL_BINARYNAME=", mapped_file);

	/* inspect the completely mangled filename */
	type = inspect_binary(mapped_file, 1/*check_x_permission*/,
		&file_mode, &file_uid, &file_gid);
	if (typep) *typep = type;

	if (!exec_policy_name) {
		if ((type != BIN_INVALID) && (type != BIN_NONE)) {
			exec_policy_name = find_exec_policy_name(mapped_file, my_file);
			if (!exec_policy_name) {
				errno = ENOEXEC;
				ret = -1;
				SB_LOG(SB_LOGLEVEL_ERROR,
					"No exec policy (%s,%s) => ENOEXEC",
					my_file, mapped_file);
				goto out;
			}
		}
	}
	SB_LOG(SB_LOGLEVEL_DEBUG, "%s: exec_policy_name=%s", __func__, exec_policy_name);

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk4, "exec/typeswitch");
	switch (type) {
		case BIN_HASHBANG:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/hashbang %s", mapped_file);
			/* prepare_hashbang() will call prepare_exec()
			 * recursively */
			ret = prepare_hashbang(&mapped_file, my_file,
					&my_argv, &my_envp, exec_policy_name);
			break;

		case BIN_HOST_DYNAMIC:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/host-dynamic %s",
					mapped_file);

#if 0
			postprocess_result = sb_execve_postprocess("native",
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				&my_argv, &my_envp);
#else
			postprocess_result = exec_postprocess_native_executable(
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				(const char **)my_argv, &my_new_argv, (const char **)*new_envp, &my_new_envp);
			my_envp = (char**)my_new_envp; /* FIXME */
			my_argv = (char**)my_new_argv; /* FIXME */
#endif

			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					1/*host_compatible_binary*/);
			}
			break;

		case BIN_HOST_STATIC:
#if 0
			postprocess_result = sb_execve_postprocess("static",
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				&my_argv, &my_envp);
#else
			{
				const char			*namev_in_ruletree[4];
				const char			*cputransp_cmd = NULL;
				ruletree_object_offset_t	cmd_offs;

				namev_in_ruletree[0] = "cputransparency";
				namev_in_ruletree[1] = "native";
				namev_in_ruletree[2] = "cmd";
				namev_in_ruletree[3] = NULL;
				cmd_offs = ruletree_catalog_vget(namev_in_ruletree);
				if (cmd_offs) {
					cputransp_cmd = offset_to_ruletree_string_ptr(cmd_offs, NULL);
				}
				if (cputransp_cmd && (cputransp_cmd[0] != '\0')) {
					postprocess_result = exec_postprocess_cpu_transparency_executable(
						exec_policy_name,
						&mapped_file, &my_file, binaryname,
						(const char **)my_argv, &my_new_argv,
						(const char **)*new_envp, &my_new_envp,
						"native");
					my_envp = (char**)my_new_envp; /* FIXME */
					my_argv = (char**)my_new_argv; /* FIXME */
				} else {
					const char *allow_static_bin = NULL;

					/* don't print warning, if this static binary
					 * has been allowed (see the wrapper for
					 * ldconfig - we don't want to see warnings
					 * every time when someone executes that)
					*/
					allow_static_bin = getenv("SBOX_ALLOW_STATIC_BINARY");
					if (allow_static_bin &&
					    !strcmp(allow_static_bin, mapped_file)) {
						/* no warnning, just debug */
						SB_LOG(SB_LOGLEVEL_DEBUG,
							"statically linked "
							"native binary %s (allowed)",
							mapped_file);
					} else {
						SB_LOG(SB_LOGLEVEL_WARNING,
							"Executing statically "
							"linked native binary %s",
							mapped_file);
					}
					/* Add LD_LIBRARY_PATH and LD_PRELOAD.
					 * the static binary itself does not need
					 * these, but if it executes another 
					 * program, then there is at least some
					 * hope of getting back to SB2. It won't
					 * be able to start anything that runs
					 * under CPU transparency, but host-compatible
					 * binaries may be able to get back..
					*/
					postprocess_result = exec_postprocess_host_static_executable(
						exec_policy_name,
						&mapped_file, &my_file, binaryname,
						(const char **)my_argv, &my_new_argv,
						(const char **)*new_envp, &my_new_envp);
					my_envp = (char**)my_new_envp; /* FIXME */
					my_argv = (char**)my_new_argv; /* FIXME */
				}
			}
#endif
			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				/* the static binary won't get SUID simulation,
				 * but if it executes something else.. */
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					1/*host_compatible_binary*/);
			}
			break;

		case BIN_TARGET:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/target %s",
					mapped_file);

#if 0
			postprocess_result = sb_execve_postprocess(
				"cpu_transparency",
				exec_policy_name,
				&mapped_file, &my_file,
				binaryname, &my_argv, &my_envp);
#else
			postprocess_result = exec_postprocess_cpu_transparency_executable(
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				(const char **)my_argv, &my_new_argv, (const char **)*new_envp, &my_new_envp,
				"target");
			my_envp = (char**)my_new_envp; /* FIXME */
			my_argv = (char**)my_new_argv; /* FIXME */
#endif

			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					0/*not host_compatible_binary*/);
			}
			break;

		case BIN_INVALID: /* = can't be executed, no X permission */
	 		/* don't even try to exec, errno has been set.*/
			ret = -1;
			break;

		case BIN_NONE:
			/* file does not exist. errno has been set. */
			ret = -1;
			break;

		case BIN_UNKNOWN:
			errno = ENOEXEC;
			ret = -1;
			SB_LOG(SB_LOGLEVEL_DEBUG,
				"Unidentified executable detected (%s) => ENOEXEC",
				mapped_file);
			break;
	}
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk4, my_file);
    out:
	*new_file = mapped_file;
	*new_argv = my_argv;
	*new_envp = my_envp;
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, orig_file);
	return(ret);
}
Esempio n. 6
0
char *ruletree_translate_path(
        const path_mapping_context_t *ctx,
        int result_log_level,
        const char *abs_clean_virtual_path,
        int *flagsp,
        const char **exec_policy_name_ptr,
	const char **errormsgp)
{
	char	*host_path = NULL;
	ruletree_fsrule_t *rule;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "ruletree_translate_path");
	*errormsgp = NULL;

	if (!ctx->pmc_ruletree_offset) {
		/* This might happen during initialization phase,
		 * when rule tree is not yet available */
		LB_LOG(LB_LOGLEVEL_DEBUG, "ruletree_translate_path: No rule tree");
		*errormsgp = "No rule tree";
		return(NULL);
	}
	rule = offset_to_ruletree_fsrule_ptr(ctx->pmc_ruletree_offset);

	LB_LOG(LB_LOGLEVEL_DEBUG, "ruletree_translate_path(%s)",
		abs_clean_virtual_path);

	/* execute rule */
	/* FIXME: should care about the R/O flag... */

	if (flagsp) *flagsp = rule->rtree_fsr_flags;
	if (exec_policy_name_ptr) {
		if (rule->rtree_fsr_exec_policy_name) {
			*exec_policy_name_ptr = offset_to_ruletree_string_ptr(rule->rtree_fsr_exec_policy_name, NULL);
		} else {
			*exec_policy_name_ptr = NULL;
		}
	}

	switch (rule->rtree_fsr_action_type) {
	case LB_RULETREE_FSRULE_ACTION_FALLBACK_TO_OLD_MAPPING_ENGINE:
		LB_LOG(LB_LOGLEVEL_WARNING,
			"ruletree_translate_path: Forced fallback. This should never happen nowadays.");
		host_path = NULL;
		break;

	case LB_RULETREE_FSRULE_ACTION_USE_ORIG_PATH:
	case LB_RULETREE_FSRULE_ACTION_FORCE_ORIG_PATH:
	case LB_RULETREE_FSRULE_ACTION_FORCE_ORIG_PATH_UNLESS_CHROOT:
	case LB_RULETREE_FSRULE_ACTION_MAP_TO:
	case LB_RULETREE_FSRULE_ACTION_REPLACE_BY:
	case LB_RULETREE_FSRULE_ACTION_SET_PATH:
	case LB_RULETREE_FSRULE_ACTION_MAP_TO_VALUE_OF_ENV_VAR:
	case LB_RULETREE_FSRULE_ACTION_REPLACE_BY_VALUE_OF_ENV_VAR:
	case LB_RULETREE_FSRULE_ACTION_PROCFS:
	case LB_RULETREE_FSRULE_ACTION_UNION_DIR:
		host_path = execute_std_action(rule, rule, abs_clean_virtual_path, flagsp);
		break;

	case LB_RULETREE_FSRULE_ACTION_CONDITIONAL_ACTIONS:
		host_path = ruletree_execute_conditional_actions(
			ctx, result_log_level, abs_clean_virtual_path,
			flagsp, exec_policy_name_ptr, errormsgp,
			rule);
		break;
	
	default:
		LB_LOG(LB_LOGLEVEL_ERROR,
			"ruletree_translate_path: Unknown action code %d",
			rule->rtree_fsr_action_type);
		host_path = NULL;
		break;
	}
	if (host_path) {
		if (*host_path != '/') {
			LB_LOG(LB_LOGLEVEL_ERROR,
				"Mapping failed: Result is not absolute ('%s'->'%s')",
				abs_clean_virtual_path, host_path);
			host_path = NULL;
		} else {
			char *new_host_path = clean_and_log_fs_mapping_result(ctx,
				abs_clean_virtual_path, result_log_level, host_path, *flagsp);
			if (new_host_path == NULL) {
				LB_LOG(result_log_level,
					"Mapping failed ('%s')",
					abs_clean_virtual_path);
				*errormsgp = "Mapping failed";
			}
			free(host_path);
			host_path = new_host_path;
		}
	} else {
		LB_LOG(result_log_level,
			"Mapping failed: Fallback to Lua mapping ('%s')",
			abs_clean_virtual_path);
		*errormsgp = "No result from C mapping";
	}
	STOP_AND_REPORT_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, host_path);
	return(host_path);
}
Esempio n. 7
0
static ruletree_object_offset_t ruletree_find_rule(
        const path_mapping_context_t *ctx,
	ruletree_object_offset_t rule_list_offs,
	const char *virtual_path,
	size_t virtual_path_len,
	int *min_path_lenp,
	uint32_t fn_class,
	ruletree_fsrule_t	**rule_p)
{
	uint32_t	rule_list_size;
	uint32_t	i;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "ruletree_find_rule");
	LB_LOG(LB_LOGLEVEL_NOISE, "ruletree_find_rule for (%s)", virtual_path);
	rule_list_size = ruletree_objectlist_get_list_size(rule_list_offs);

	if (min_path_lenp) *min_path_lenp = 0;
	if (rule_p) *rule_p = NULL;

	if (rule_list_size == 0) return(0);

	for (i = 0; i < rule_list_size; i++) {
		ruletree_fsrule_t	*rp;
		ruletree_object_offset_t rule_offs;

		rule_offs = ruletree_objectlist_get_item(rule_list_offs, i);
		if (!rule_offs) continue;

		rp = offset_to_ruletree_fsrule_ptr(rule_offs);
		if (rp) {
			int min_path_len;

			if (rp->rtree_fsr_condition_type != 0) {
				LB_LOG(LB_LOGLEVEL_DEBUG,
					"ruletree_find_rule: can't handle rules with conditions, fail. @%d", rule_offs);
				return(0);
			}

			if (rp->rtree_fsr_selector_type == 0) {
				LB_LOG(LB_LOGLEVEL_NOISE,
					"ruletree_find_rule skipping defunct rule @%d", rule_offs);
				continue;
			}

			min_path_len = ruletree_test_path_match(virtual_path, virtual_path_len, rp);

			if (min_path_len >= 0) {
				LB_LOG(LB_LOGLEVEL_NOISE,
					"ruletree_find_rule found rule @ %d",
					rule_offs);

				if (rp->rtree_fsr_func_class) {
					if ((rp->rtree_fsr_func_class & fn_class) == 0) {
						/* Function class does not match.. */
						continue;
					}
				}

				if (rp->rtree_fsr_binary_name) {
					const char	*bin_name_in_rule =
						offset_to_ruletree_string_ptr(rp->rtree_fsr_binary_name, NULL);
					if (strcmp(ctx->pmc_binary_name, bin_name_in_rule)) {
						/* binary name does not match, not this rule... */
						continue;
					}
				}

				if (min_path_lenp) *min_path_lenp = min_path_len;

				if (rp->rtree_fsr_action_type == LB_RULETREE_FSRULE_ACTION_SUBTREE) {
					/* if rule can be found from the subtree, return it,
                                         * otherwise continue looping here */
					if (rp->rtree_fsr_rule_list_link) {
						ruletree_object_offset_t subtree_offs;

						LB_LOG(LB_LOGLEVEL_NOISE,
							"ruletree_find_rule: continue @ %d",
							rp->rtree_fsr_rule_list_link);
						subtree_offs = ruletree_find_rule(ctx,
							rp->rtree_fsr_rule_list_link,
							virtual_path, virtual_path_len,
							min_path_lenp,
							fn_class, rule_p);
						if (subtree_offs) {
							STOP_AND_REPORT_PROCESSCLOCK(
								LB_LOGLEVEL_INFO, &clk1,
								"found/subtree");
							return(subtree_offs);
						}
					} else {
						LB_LOG(LB_LOGLEVEL_NOISE,
							"ruletree_find_rule: no link");
					}
					continue;
				}
				/* found it! */
				if (rule_p) *rule_p = rp;
				STOP_AND_REPORT_PROCESSCLOCK(
					LB_LOGLEVEL_INFO, &clk1,
					"found");
				return(rule_offs);
			}
		}
	}
	STOP_AND_REPORT_PROCESSCLOCK(LB_LOGLEVEL_INFO, &clk1, "not found");
	return (0); /* failed to find it */
}
Esempio n. 8
0
static void fwd_map_path(
	const char *binary_name,
	const char *func_name,
	const char *virtual_path,
	int dont_resolve_final_symlink,
	int exec_mode,
	uint32_t fn_class,
	mapping_results_t *res)
{
	struct sb2context *sb2ctx = NULL;

	(void)exec_mode; /* not used */

	if (!virtual_path) {
		res->mres_result_buf = res->mres_result_path = NULL;
		res->mres_readonly = 1;
	} else {
#if 0
		mapping_results_t res2;
#endif
		PROCESSCLOCK(clk1)

		sb2ctx = check_mapping_method(1);

		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "fwd_map_path");
		switch (mapping_method) {
#if 0
		case MAPPING_METHOD_C_ENGINE_WITH_FALLBACKS:
			sbox_map_path_internal__c_engine(sb2ctx, binary_name,
				func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res, 0);
			if (res->mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), fallback to Lua (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
				free_mapping_results(res);
				if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
				sbox_map_path_internal__lua_engine(sb2ctx, binary_name,
					func_name, virtual_path,
					dont_resolve_final_symlink, 0, fn_class, res);
			}
			break;
#endif
		case MAPPING_METHOD_C_ENGINE:
			sbox_map_path_internal__c_engine(sb2ctx, binary_name,
				func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res, 0);
			if (res->mres_fallback_to_lua_mapping_engine &&
			    (res->mres_fallback_to_lua_mapping_engine[0] == '#')) {
#if 0
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), fallback to Lua was forced (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
				free_mapping_results(res);
				if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
				sbox_map_path_internal__lua_engine(sb2ctx, binary_name,
					func_name, virtual_path,
					dont_resolve_final_symlink, 0, fn_class, res);
#else
				SB_LOG(SB_LOGLEVEL_ERROR,
					"C path mapping engine tries to force fallback to Lua, won't do that (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
#endif
			} else if (res->mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), NO fallback to Lua (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
			}
			break;
#if 0
		case MAPPING_METHOD_LUA_ENGINE:
			sbox_map_path_internal__lua_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res);
			break;
		case MAPPING_METHOD_BOTH_ENGINES:
			clear_mapping_results_struct(&res2);
			sbox_map_path_internal__lua_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res);
			sbox_map_path_internal__c_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, &res2, 0);
			if (res2.mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_ERROR,
					"C path mapping engine => fallback to Lua (%s), (%s)",
					res2.mres_fallback_to_lua_mapping_engine, virtual_path);
			}
			compare_results_from_c_and_lua_engines(
				"result path",
				__func__, res2.mres_result_path,
				res->mres_result_path);
			compare_results_from_c_and_lua_engines(
				"virtual cwd",
				__func__, res2.mres_virtual_cwd,
				res->mres_virtual_cwd);
			free_mapping_results(&res2);
			break;
#endif
		default:
			SB_LOG(SB_LOGLEVEL_ERROR,
				"%s: Invalid mapping method",
				__func__);
		}
		release_sb2context(sb2ctx);
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, virtual_path);
	}
}