Пример #1
0
static void dump_exec_selection_rules(ruletree_object_offset_t offs, int indent)
{
	ruletree_exec_policy_selection_rule_t	*rule = offset_to_ruletree_object_ptr(
		offs, SB2_RULETREE_OBJECT_TYPE_EXEC_SEL_RULE);

	if (rule_dumped[offs]) {
		print_indent(indent + 1);
		printf("[ => @ %u]\n", offs);
		return;
	}
	rule_dumped[offs] = 1;

	print_indent(indent);
	printf("{ Exec policy selection rule[%u]:\n", (unsigned)offs);
	print_indent(indent+1);
	printf("type = 0x%X\n", rule->rtree_xps_type);
	if (rule->rtree_xps_selector_offs) {
		print_indent(indent+1);
		printf("selector = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_xps_selector_offs, NULL));
	}
	if (rule->rtree_xps_exec_policy_name_offs) {
		print_indent(indent+1);
		printf("exec_policy_name = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_xps_exec_policy_name_offs, NULL));
	}
	print_indent(indent+1);
	printf("flags = 0x%X\n", rule->rtree_xps_flags);
	print_indent(indent);
	printf("}\n");
}
Пример #2
0
static int if_exists_in(ruletree_fsrule_t *action,
                        const char *abs_clean_virtual_path)
{
	const char *map_to_target;
	char *test_path = NULL;

	map_to_target = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);

	if (!strcmp(map_to_target, "/")) {
		test_path = strdup(abs_clean_virtual_path);
	} else {
		if (asprintf(&test_path, "%s%s", map_to_target, abs_clean_virtual_path) < 0) {
			LB_LOG(LB_LOGLEVEL_ERROR, "asprintf failed");
			return(0);
		}
	}
	if (lb_path_exists(test_path)) {
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"if_exists_in: True '%s' -> proceed to then_actions", test_path);
                free(test_path);
                return (1);
	}
	LB_LOG(LB_LOGLEVEL_DEBUG,
		"if_exists_in: False '%s'", test_path);
	free(test_path);
	return(0);
}
Пример #3
0
static int if_exists_then_replace_by(
	ruletree_fsrule_t *action, ruletree_fsrule_t *rule_selector,
	const char *abs_clean_virtual_path, char **resultp)
{
	char *test_path;
	const char *replacement = NULL;

	*resultp = NULL;
	replacement = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);

	test_path = ruletree_execute_replace_rule(abs_clean_virtual_path,
			replacement, rule_selector);
	if (!test_path) return(0);

	if (lb_path_exists(test_path)) {
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"if_exists_then_replace_by: True '%s'", test_path);
		*resultp = test_path;
		return(1);
	}
	LB_LOG(LB_LOGLEVEL_DEBUG,
		"if_exists_then_replace_by: False '%s'", test_path);
	free(test_path);
	return(0);
}
static int if_exists_then_map_to(ruletree_fsrule_t *action,
	const char *abs_clean_virtual_path, char **resultp)
{
	const char *map_to_target;
	char *test_path = NULL;

	*resultp = NULL;
	map_to_target = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);

	if (!strcmp(map_to_target, "/")) {
		test_path = strdup(abs_clean_virtual_path);
	} else {
		if (asprintf(&test_path, "%s%s", map_to_target, abs_clean_virtual_path) < 0) {
			SB_LOG(SB_LOGLEVEL_ERROR, "asprintf failed");
			return(0);
		}
	}
	if (sb_path_exists(test_path)) {
		SB_LOG(SB_LOGLEVEL_DEBUG,
			"if_exists_then_map_to: True '%s'", test_path);
		*resultp = test_path;
		return(1);
	}
	SB_LOG(SB_LOGLEVEL_DEBUG,
		"if_exists_then_map_to: False '%s'", test_path);
	free(test_path);
	return(0);
}
Пример #5
0
static void dump_exec_pp_rules(ruletree_object_offset_t offs, int indent)
{
	ruletree_exec_preprocessing_rule_t	*rule = offset_to_exec_preprocessing_rule_ptr(offs);

	if (rule_dumped[offs]) {
		print_indent(indent + 1);
		printf("[ => @ %u]\n", offs);
		return;
	}
	rule_dumped[offs] = 1;

	print_indent(indent);
	printf("{ Exec preprocessing rule[%u]:\n", (unsigned)offs);

	if (rule->rtree_xpr_binary_name_offs) {
		print_indent(indent+1);
		printf("binary_name = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_xpr_binary_name_offs, NULL));
	}

#define EXECPP_PRINT_LIST(name, field) \
	if (rule->field) { \
		print_indent(indent+1); \
		printf(name " = {\n"); \
		dump_objectlist(rule->field, indent + 2); \
		print_indent(indent+1); \
		printf("}\n"); \
	}

	EXECPP_PRINT_LIST("path_prefixes", rtree_xpr_path_prefixes_table_offs)
	EXECPP_PRINT_LIST("add_head", rtree_xpr_add_head_table_offs)
	EXECPP_PRINT_LIST("add_options", rtree_xpr_add_options_table_offs)
	EXECPP_PRINT_LIST("add_tail", rtree_xpr_add_tail_table_offs)
	EXECPP_PRINT_LIST("remove", rtree_xpr_remove_table_offs)

	if (rule->rtree_xpr_new_filename_offs) {
		print_indent(indent+1);
		printf("new_filename = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_xpr_new_filename_offs, NULL));
	}
	if (rule->rtree_xpr_disable_mapping) {
		print_indent(indent+1);
		printf("disable_mapping = true\n");
	}
	print_indent(indent);
	printf("}\n");
}
Пример #6
0
static void dump_objectlist(ruletree_object_offset_t list_offs, int indent)
{
	uint32_t	list_size = ruletree_objectlist_get_list_size(list_offs);
	uint32_t	i;
	const char	*cp;

	print_indent(indent);
	printf("{ list[%u], size=%u:\n", (unsigned)list_offs, list_size);

	for (i = 0; i < list_size; i++) {
		ruletree_object_offset_t	item_offs;

		item_offs = ruletree_objectlist_get_item(list_offs, i);

		print_indent(indent);
		printf("#%d:\n", i);

		if (item_offs) {
			ruletree_object_hdr_t *hdr = offset_to_ruletree_object_ptr(
				item_offs, 0/*any type is ok*/);
			if (hdr) {
				switch (hdr->rtree_obj_type) {
				case SB2_RULETREE_OBJECT_TYPE_OBJECTLIST:
					print_indent(indent+1);
					printf("List:\n");
					dump_objectlist(item_offs, indent+2);
					break;
				case SB2_RULETREE_OBJECT_TYPE_FSRULE:
					print_indent(indent+1);
					printf("FS rule:\n");
					dump_rules(item_offs, indent+2);
					break;
				case SB2_RULETREE_OBJECT_TYPE_EXEC_PP_RULE:
					dump_exec_pp_rules(item_offs, indent+1);
					break;
				case SB2_RULETREE_OBJECT_TYPE_EXEC_SEL_RULE:
					dump_exec_selection_rules(item_offs, indent+1);
					break;
				case SB2_RULETREE_OBJECT_TYPE_NET_RULE:
					dump_net_rules(item_offs, indent+1);
					break;
				case SB2_RULETREE_OBJECT_TYPE_STRING:
					print_indent(indent+1);
					printf("STRING ");
					cp = offset_to_ruletree_string_ptr(item_offs, NULL);
					if (cp) printf("'%s'\n", cp);
					else printf("NULL\n");
					break;
				default:
					print_indent(indent+1);
					printf("Unsupported type\n");
					break;
				}
			}
		}
	}
	print_indent(indent);
	printf("}\n");
}
Пример #7
0
/* returns an allocated buffer */
static char *ruletree_execute_replace_rule(
	const char *full_path,
	const char *replacement,
	ruletree_fsrule_t *rule)
{
	char		*new_path = NULL;
	uint32_t	selector_len;
	const char	*selector = offset_to_ruletree_string_ptr(rule->rtree_fsr_selector_offs, &selector_len);

	LB_LOG(LB_LOGLEVEL_DEBUG, "ruletree_execute_replace_rule: orig='%s',replacement='%s',selector='%s'",
		full_path, replacement,selector);

	switch (rule->rtree_fsr_selector_type) {
	case LB_RULETREE_FSRULE_SELECTOR_PREFIX:
	case LB_RULETREE_FSRULE_SELECTOR_DIR:
		if (asprintf(&new_path, "%s%s",
		     replacement, full_path + selector_len) < 0) {
			LB_LOG(LB_LOGLEVEL_ERROR, "asprintf failed");
			return(NULL);
		}
		return(new_path);

	case LB_RULETREE_FSRULE_SELECTOR_PATH:
		/* "path" may be shorter than prefix during path resolution */
		if (!strcmp(full_path, selector)) {
			return(strdup(replacement));
		}
		LB_LOG(LB_LOGLEVEL_DEBUG, "replacement failed");
		return(NULL);

	default:
		LB_LOG(LB_LOGLEVEL_ERROR,
			"ruletree_execute_replace_rule: Unknown selector type %d",
			rule->rtree_fsr_selector_type);
	}

	return(NULL);
}
Пример #8
0
static void print_ruletree_object_type(ruletree_object_offset_t obj_offs)
{
	ruletree_object_hdr_t *hdr;

	hdr = offset_to_ruletree_object_ptr(obj_offs, 0/*any type is ok*/);

	if (hdr) {
		const char *cp;
		uint32_t *uip;

		switch (hdr->rtree_obj_type) {
		case SB2_RULETREE_OBJECT_TYPE_FILEHDR:
			printf("FILEHDR");
			break;
		case SB2_RULETREE_OBJECT_TYPE_CATALOG:
			printf("CATALOG @%u", obj_offs);
			break;
		case SB2_RULETREE_OBJECT_TYPE_FSRULE:
			printf("FSRULE @%u", obj_offs);
			break;
		case SB2_RULETREE_OBJECT_TYPE_STRING:
			printf("STRING\t");
			cp = offset_to_ruletree_string_ptr(obj_offs, NULL);
			if (cp) printf("'%s'", cp);
			else printf("NULL");
			break;
		case SB2_RULETREE_OBJECT_TYPE_OBJECTLIST:
			printf("LIST @%u", obj_offs);
			break;
		case SB2_RULETREE_OBJECT_TYPE_BINTREE:
			printf("BINTREE @%u", obj_offs);
			break;
		case SB2_RULETREE_OBJECT_TYPE_INODESTAT:
			{
				ruletree_inodestat_t *fsp;

				fsp = (ruletree_inodestat_t*)hdr;
				if (fsp) {
					int	a = fsp->rtree_inode_simu.inodesimu_active_fields;

					printf("INODESTAT: dev=%lld ino=%lld act=0x%X",
						(long long)fsp->rtree_inode_simu.inodesimu_dev,
						(long long)fsp->rtree_inode_simu.inodesimu_ino, a);
					if (a & RULETREE_INODESTAT_SIM_UID) 
						printf(" uid=%d",
							(int)fsp->rtree_inode_simu.inodesimu_uid);
					if (a & RULETREE_INODESTAT_SIM_GID) 
						printf(" gid=%d",
							(int)fsp->rtree_inode_simu.inodesimu_gid);
					if (a & RULETREE_INODESTAT_SIM_MODE) 
						printf(" mode=0%o",
							(int)fsp->rtree_inode_simu.inodesimu_mode);
					if (a & RULETREE_INODESTAT_SIM_SUIDSGID) 
						printf(" suid_sgid=0%o",
							(int)fsp->rtree_inode_simu.inodesimu_suidsgid);
					if (a & RULETREE_INODESTAT_SIM_DEVNODE) 
						printf(" device_type=0%o rdev=0x%llX",
							(int)fsp->rtree_inode_simu.inodesimu_devmode,
							(long long)fsp->rtree_inode_simu.inodesimu_rdev);
				} else {
					printf("INODESTAT: <NULL>");
				}
			}
			break;
		case SB2_RULETREE_OBJECT_TYPE_UINT32:
			uip = ruletree_get_pointer_to_uint32(obj_offs);
			if (uip)
				printf("UINT32 %u (0x%X)", *uip, *uip);
			else
				printf("UINT32 <none; got NULL pointer>");
			break;
		case SB2_RULETREE_OBJECT_TYPE_BOOLEAN:
			uip = ruletree_get_pointer_to_boolean(obj_offs);
			if (uip)
				printf("BOOLEAN %s", *uip ? "true" : "false");
			else
				printf("BOOLEAN <none; got NULL pointer>");
			break;
		default:
			printf("<unknown type %d>",
				hdr->rtree_obj_type);
			break;
		}
	} else {
		printf("<invalid value offset>");
	}
}
Пример #9
0
static void dump_net_rules(ruletree_object_offset_t offs, int indent)
{
	ruletree_net_rule_t	*rule = offset_to_ruletree_object_ptr(offs,
		SB2_RULETREE_OBJECT_TYPE_NET_RULE);

	if (rule_dumped[offs]) {
		print_indent(indent + 1);
		printf("[ => @ %u]\n", offs);
		return;
	}
	rule_dumped[offs] = 1;

	print_indent(indent);
	printf("{ net rule[%u]:\n", (unsigned)offs);
	print_indent(indent + 1);
	switch(rule->rtree_net_ruletype) {
	case SB2_RULETREE_NET_RULETYPE_DENY:
		printf("ruletype = deny\n");
		break;
	case SB2_RULETREE_NET_RULETYPE_ALLOW:
		printf("ruletype = allow\n");
		break;
	case SB2_RULETREE_NET_RULETYPE_RULES:
		printf("ruletype = rules\n");
		break;
	default:
		printf("ruletype = %d (UNKNOWN)\n", rule->rtree_net_ruletype);
		break;
	}

	if (rule->rtree_net_func_name) {
		print_indent(indent + 1);
		printf("func_name = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_net_func_name, NULL));
	}
	if (rule->rtree_net_binary_name) {
		print_indent(indent + 1);
		printf("binary_name = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_net_binary_name, NULL));
	}
	if (rule->rtree_net_address) {
		print_indent(indent + 1);
		printf("address = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_net_address, NULL));
	}
	if (rule->rtree_net_port) {
		print_indent(indent + 1);
		printf("port = %d\n", rule->rtree_net_port);
	}
	if (rule->rtree_net_new_address) {
		print_indent(indent + 1);
		printf("new_address = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_net_new_address, NULL));
	}
	if (rule->rtree_net_new_port) {
		print_indent(indent + 1);
		printf("new_port = %d\n", rule->rtree_net_new_port);
	}
	if (rule->rtree_net_log_msg) {
		print_indent(indent + 1);
		if (rule->rtree_net_log_level) {
			printf("log_level = %d, ", rule->rtree_net_log_level);
		}
		printf("log_msg = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_net_log_msg, NULL));
	}
	if (rule->rtree_net_errno) {
		print_indent(indent + 1);
		printf("errno = %d '%s'\n",
			rule->rtree_net_errno, strerror(rule->rtree_net_errno));
	}
	if (rule->rtree_net_rules) {
		dump_objectlist(rule->rtree_net_rules, indent+1);
	}
	print_indent(indent);
	printf("}\n");
}
Пример #10
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);
}
Пример #11
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 */
}
Пример #12
0
static char *ruletree_execute_conditional_actions(
        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,
	ruletree_fsrule_t	*rule_selector)
{
	uint32_t	actions_list_size;
	uint32_t	i;
	ruletree_object_offset_t action_list_offs = rule_selector->rtree_fsr_rule_list_link;

	/* FIXME: these are not yet used. */
	(void)ctx;
	(void)result_log_level;
        (void)exec_policy_name_ptr;

	LB_LOG(LB_LOGLEVEL_NOISE, "ruletree_execute_conditional_actions for (%s)", abs_clean_virtual_path);
	actions_list_size = ruletree_objectlist_get_list_size(action_list_offs);
	if (actions_list_size == 0) {
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"ruletree_execute_conditional_actions: action list not found or empty.");
		*errormsgp = "action list not found or empty.";
		return (NULL);
	}

	for (i = 0; i < actions_list_size; i++) {
		ruletree_fsrule_t	*action_cand_p;
		ruletree_object_offset_t action_offs;

		action_offs = ruletree_objectlist_get_item(action_list_offs, i);
		if (!action_offs) continue;

		/* "rule_selector" is the rule which matched, and
		 * brought us here (so it contains "dir","prefix"
		 * or "path").
		 * Each member in the "actions" array is a 
                 * candidate for the rule which will be applied,
		 * i.e. a suitable member from that array gives
		 * instructions about what to do next */
		action_cand_p = offset_to_ruletree_fsrule_ptr(action_offs);
		if (action_cand_p) {
			char *mapping_result;

			if (action_cand_p->rtree_fsr_condition_type != 0) {
				const char *cond_str;
				const char *evp;

				cond_str = offset_to_ruletree_string_ptr(action_cand_p->rtree_fsr_condition_offs, NULL);
				LB_LOG(LB_LOGLEVEL_NOISE, "Condition test '%s'", cond_str);
				
				switch (action_cand_p->rtree_fsr_condition_type) {
				case LB_RULETREE_FSRULE_CONDITION_IF_ENV_VAR_IS_NOT_EMPTY:
					if (!cond_str) continue;	/* continue if no env.var.name */
					evp = getenv(cond_str);
					if (!evp || !*evp) continue; /* continue if empty */
					LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: env.var was not empty");
					break;	/* else test passed. */
					
				case LB_RULETREE_FSRULE_CONDITION_IF_ENV_VAR_IS_EMPTY:
					if (!cond_str) continue;	/* continue if no env.var.name */
					evp = getenv(cond_str);
					if (evp && *evp) continue; /* continue if not empty */
					LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: env.var was empty");
					break;	/* else test passed. */
				
				case LB_RULETREE_FSRULE_CONDITION_IF_ACTIVE_EXEC_POLICY_IS:
					if (!cond_str ||
					    !ldbox_active_exec_policy_name ||
					    strcmp(cond_str, ldbox_active_exec_policy_name)) {
						/* exec policy name did not match */
						continue;
					}
					LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: exec policy name matched");
					break;

				case LB_RULETREE_FSRULE_CONDITION_IF_REDIRECT_IGNORE_IS_ACTIVE:
					if (!cond_str) continue;	/* continue if no path */
					if (test_if_str_in_colon_separated_list_from_env(
						cond_str, "LDBOX_REDIRECT_IGNORE")) {
						LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: redirect-ignore is active (%s)",
							cond_str);
					} else {
						LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: redirect-ignore is NOT active (%s)",
							cond_str);
						continue;
					}
					break;

				case LB_RULETREE_FSRULE_CONDITION_IF_REDIRECT_FORCE_IS_ACTIVE:
					if (!cond_str) continue;	/* continue if no path */
					if (test_if_str_in_colon_separated_list_from_env(
						cond_str, "LDBOX_REDIRECT_FORCE")) {
						LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: redirect-force is active (%s)",
							cond_str);
					} else {
						LB_LOG(LB_LOGLEVEL_NOISE, "Condition test: redirect-force is NOT active (%s)",
							cond_str);
						continue;
					}
					break;

                                case LB_RULETREE_FSRULE_CONDITION_IF_EXISTS_IN:
                                  if (if_exists_in(action_cand_p, abs_clean_virtual_path)) {
                                    /* found, jump to the new rule tree branch */
                                    ruletree_object_offset_t then_actions_offset = action_cand_p->rtree_fsr_rule_list_link;
                                    if (!then_actions_offset) {
                                      LB_LOG(LB_LOGLEVEL_DEBUG, "if_exists_in: no then_actions found");
                                      /* continue with normal rule tree */
                                      continue;
                                    }
                                    else {
                                      LB_LOG(LB_LOGLEVEL_DEBUG, "if_exists_in: then_actions found (%d)", then_actions_offset);
                                      ruletree_fsrule_t new_rules = *rule_selector;
                                      new_rules.rtree_fsr_rule_list_link = then_actions_offset;
                                      return ruletree_execute_conditional_actions(ctx, result_log_level,
                                                                                  abs_clean_virtual_path, flagsp,
                                                                                  exec_policy_name_ptr, errormsgp,
                                                                                  &new_rules);
                                    }
                                  }
                                  /* not found, continue with normal rule tree */
                                  continue;
                                  break;

				default:
					LB_LOG(LB_LOGLEVEL_ERROR,
						"ruletree_execute_conditional_actions: "
						" unknown condition %d @%d",
						action_cand_p->rtree_fsr_condition_type, action_offs);
					goto unimplemented_action_error;
				}
			}

			switch (action_cand_p->rtree_fsr_action_type) {
			case LB_RULETREE_FSRULE_ACTION_IF_EXISTS_THEN_MAP_TO:
				if (if_exists_then_map_to(action_cand_p,
				     abs_clean_virtual_path, &mapping_result)) {
					return(mapping_result);
				}
				break;

			case LB_RULETREE_FSRULE_ACTION_IF_EXISTS_THEN_REPLACE_BY:
				if (if_exists_then_replace_by(action_cand_p,
				     rule_selector, abs_clean_virtual_path,
				     &mapping_result)) {
					return(mapping_result);
				}
				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:
				return(execute_std_action(rule_selector, action_cand_p,
					abs_clean_virtual_path, flagsp));

			default:
				/* FIXME */
				goto unimplemented_action_error;
			}
		}
	}
	/* end of list is most probably a fatal error in the rule file. */
	LB_LOG(LB_LOGLEVEL_ERROR,
		"ruletree_execute_conditional_actions: End of conditional action list, "
		"probably caused by an error in the rule file.");
	/* FIXME. This should probably return the original path (compare with
	 * Lua code) */
	*errormsgp = "End of conditional action list";
	return (NULL);
			
    unimplemented_action_error:
	LB_LOG(LB_LOGLEVEL_ERROR,
		"Internal error: ruletree_execute_conditional_actions: Encountered "
		"an unknown conditional action.");
	*errormsgp = "unknown conditional action (internal error)";
	return (NULL);
}
Пример #13
0
/* Returns min.path length if a match is found, otherwise returns -1 */
static int ruletree_test_path_match(const char *full_path, size_t full_path_len, ruletree_fsrule_t *rp)
{
	const char	*selector = NULL;
	const char	*match_type = "no match";
	int		result = -1;
	uint32_t	selector_len;

	if (!rp || !full_path) {
		LB_LOG(LB_LOGLEVEL_NOISE, "ruletree_test_path_match fails");
		return(-1);
	}
	LB_LOG(LB_LOGLEVEL_NOISE, "ruletree_test_path_match (%s), type=%d",
		full_path, rp->rtree_fsr_selector_type);

	selector = offset_to_ruletree_string_ptr(rp->rtree_fsr_selector_offs,
		&selector_len);

	switch (rp->rtree_fsr_selector_type) {
	case LB_RULETREE_FSRULE_SELECTOR_PATH:
		if (selector) {
			if ((selector_len == full_path_len) &&
			    !strcmp(full_path, selector)) {
				result = selector_len;
				match_type = "path";
			}
		}
		break;
	case LB_RULETREE_FSRULE_SELECTOR_PREFIX:
		if (selector && (*selector != '\0')) {
			if ((full_path_len >= selector_len) &&
			    (full_path[selector_len-1] == selector[selector_len-1]) &&
			    !strncmp(full_path, selector, selector_len)) {
				result = selector_len;
				match_type = "prefix";
			}
		}
		break;
	case LB_RULETREE_FSRULE_SELECTOR_DIR:
		if (selector && (*selector != '\0')) {
			/* test a directory prefix: the next char after the
			 * prefix must be '\0' or '/', unless we are accessing
			 * the root directory */
			if ((full_path_len >= selector_len) &&
			    ((full_path[selector_len] == '/') ||
			     (full_path[selector_len] == '\0') ||
			     ((selector_len == 1) && (*full_path=='/'))) ) {
				if (!strncmp(full_path, selector, selector_len)) {
					result = selector_len;
					match_type = "dir";
				}
			}
		}
		break;
	default:
		LB_LOG(LB_LOGLEVEL_ERROR,
			"ruletree_test_path_match: "
			"Unsupported selector type (rule='%s')",
			offset_to_ruletree_string_ptr(rp->rtree_fsr_name_offs, NULL));
		return(-1);
	}

	LB_LOG(LB_LOGLEVEL_NOISE,
		"ruletree_test_path_match '%s' (%u), '%s' (%u) => %d (%s)",
		full_path, full_path_len, selector, selector_len, result, match_type);
	return(result);
}
Пример #14
0
/* "standard actions" = use_orig_path, force_orig_path, map_to, replace_by */
static char *execute_std_action(
	ruletree_fsrule_t *rule_selector,
	ruletree_fsrule_t *action,
	const char *abs_clean_virtual_path, int *flagsp)
{
	const char	*cp;
	char	*procfs_result;
	char	*union_dir_result = NULL;
	char	*new_path = NULL;

	switch (action->rtree_fsr_action_type) {
	case LB_RULETREE_FSRULE_ACTION_USE_ORIG_PATH:
		return(strdup(abs_clean_virtual_path));

	case LB_RULETREE_FSRULE_ACTION_FORCE_ORIG_PATH:
		/* flags should already contain LB_MAPPING_RULE_FLAGS_FORCE_ORIG_PATH,
		 * but forcing it here won't hurt anyone. */
		*flagsp |= LB_MAPPING_RULE_FLAGS_FORCE_ORIG_PATH;
		return(strdup(abs_clean_virtual_path));

	case LB_RULETREE_FSRULE_ACTION_FORCE_ORIG_PATH_UNLESS_CHROOT:
		/* flags should already contain it,
		 * but forcing it here won't hurt anyone. */
		*flagsp |= LB_MAPPING_RULE_FLAGS_FORCE_ORIG_PATH_UNLESS_CHROOT;
		return(strdup(abs_clean_virtual_path));

	case LB_RULETREE_FSRULE_ACTION_MAP_TO:
		cp = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);
		return(execute_map_to(abs_clean_virtual_path, "map_to", cp));
		
	case LB_RULETREE_FSRULE_ACTION_REPLACE_BY:
		cp = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: replace by '%s'", cp);
		new_path = ruletree_execute_replace_rule(abs_clean_virtual_path, cp/*replacement*/,
			rule_selector);
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: replaced: '%s'", cp);
		return(new_path);

	case LB_RULETREE_FSRULE_ACTION_SET_PATH:
		cp = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: set path to '%s'", cp);
		new_path = strdup(cp);
		return(new_path);

	case LB_RULETREE_FSRULE_ACTION_MAP_TO_VALUE_OF_ENV_VAR:
		cp = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);
		cp = getenv(cp);
		return(execute_map_to(abs_clean_virtual_path, "map_to_value_of_env_var", cp));

	case LB_RULETREE_FSRULE_ACTION_REPLACE_BY_VALUE_OF_ENV_VAR:
		cp = offset_to_ruletree_string_ptr(action->rtree_fsr_action_offs, NULL);
		cp = getenv(cp);
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: replace by env.var.value '%s'", cp);
		new_path = ruletree_execute_replace_rule(abs_clean_virtual_path, cp/*replacement*/,
			rule_selector);
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: replaced/2: '%s'", cp);
		return(new_path);

	case LB_RULETREE_FSRULE_ACTION_PROCFS:
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: /proc: %s", abs_clean_virtual_path);
		procfs_result = procfs_mapping_request(abs_clean_virtual_path);
		if (procfs_result) {
		        /* mapped to somewhere else */
			return(procfs_result);
		}
                /* no need to map this path */
		return(strdup(abs_clean_virtual_path));

	case LB_RULETREE_FSRULE_ACTION_UNION_DIR:
		LB_LOG(LB_LOGLEVEL_DEBUG,
			"execute_std_action: union_dir: %s", abs_clean_virtual_path);
		{
			ruletree_object_offset_t union_dir_list_offs = rule_selector->rtree_fsr_rule_list_link;
			int	num_real_dir_entries;
			const char	**src_paths = NULL;
			int	i;

			num_real_dir_entries = ruletree_objectlist_get_list_size(union_dir_list_offs);
			if (num_real_dir_entries > 0) {
				src_paths = calloc(num_real_dir_entries, sizeof(char*));
				for (i = 0; i < num_real_dir_entries; i++) {
					ruletree_object_offset_t str_offs;
					str_offs = ruletree_objectlist_get_item(union_dir_list_offs, i);
					src_paths[i] = offset_to_ruletree_string_ptr(str_offs, NULL);
					LB_LOG(LB_LOGLEVEL_DEBUG,
						"execute_std_action: union_dir src_path[%d]: %s", 
						i, src_paths[i]);
				}
				union_dir_result = prep_union_dir(abs_clean_virtual_path,
						src_paths, num_real_dir_entries);
			}
			if (src_paths) free(src_paths);
		}
		LB_LOG(LB_LOGLEVEL_DEBUG, "union_dir result = '%s'", union_dir_result);
		return(union_dir_result);

	default:
		LB_LOG(LB_LOGLEVEL_ERROR,
			"Internal error: execute_std_action: action code is %d",
			action->rtree_fsr_action_type);
	}
	return(NULL);
}
Пример #15
0
static void dump_catalog(ruletree_object_offset_t catalog_offs, const char *catalog_name, int indent)
{
	ruletree_catalog_entry_t	*catalog;
	ruletree_catalog_entry_t	*catp;

	if (!catalog_offs) {
		ruletree_hdr_t	*treehdr = (ruletree_hdr_t*)offset_to_ruletree_object_ptr(0,
					SB2_RULETREE_OBJECT_TYPE_FILEHDR);
		catalog_offs = treehdr->rtree_hdr_root_catalog;
	}

	if (rule_dumped[catalog_offs]) {
		print_indent(indent);
		printf("[ => Catalog @ %u '%s']\n", catalog_offs, catalog_name);
		return;
	}
	rule_dumped[catalog_offs] = 1;

	print_indent(indent);
	printf("Catalog @ %u '%s':\n", catalog_offs, catalog_name);

	catalog = offset_to_ruletree_object_ptr(catalog_offs,
		SB2_RULETREE_OBJECT_TYPE_CATALOG);
	
	if (!catalog) {
		print_indent(indent+1);
		printf("[empty]\n");
		return;
	}

	/* first, print contents of the catalog itself */
	for (catp = catalog; catp;
	     catp = catp->rtree_cat_next_entry_offs ?
		offset_to_ruletree_object_ptr(catp->rtree_cat_next_entry_offs,
			SB2_RULETREE_OBJECT_TYPE_CATALOG) : NULL) {

		const char *name = "??";

		print_indent(indent+1);
		if (catp->rtree_cat_name_offs) {
			name = offset_to_ruletree_string_ptr(catp->rtree_cat_name_offs, NULL);
			if (name) {
				printf("'%s'\t", name);
			} else {
				printf("<invalid name offset>\t");
			}
		} else {
			printf("<no name>\t");
		}

		if (catp->rtree_cat_value_offs) {
			print_ruletree_object_type(catp->rtree_cat_value_offs);
		} else {
			printf("<no value>");
		}
		printf("\n");
	}

	/* next, process again all entries that need recursive processing  */
	for (catp = catalog; catp;
	     catp = catp->rtree_cat_next_entry_offs ?
		offset_to_ruletree_object_ptr(catp->rtree_cat_next_entry_offs,
			SB2_RULETREE_OBJECT_TYPE_CATALOG) : NULL) {

		const char *name = "??";

		if (catp->rtree_cat_name_offs) {
			name = offset_to_ruletree_string_ptr(catp->rtree_cat_name_offs, NULL);
		}

		if (catp->rtree_cat_value_offs) {
			print_ruletree_object_recurse(indent+1,
				name, catp->rtree_cat_value_offs);

		}
	}
	print_indent(indent);
	printf("End of Catalog @ %u '%s'.\n", catalog_offs, catalog_name);
}
Пример #16
0
static void dump_rules(ruletree_object_offset_t offs, int indent)
{
	ruletree_fsrule_t	*rule = offset_to_ruletree_fsrule_ptr(offs);
	const char *rule_list_link_label = "??";

	if (rule_dumped[offs]) {
		print_indent(indent + 1);
		printf("[ => @ %u]\n", offs);
		return;
	}
	rule_dumped[offs] = 1;

	print_indent(indent);
	printf("{ Rule[%u]:\n", (unsigned)offs);

	if (rule->rtree_fsr_name_offs) {
		print_indent(indent+1);
		printf("name = '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_name_offs, NULL));
	}

	if (rule->rtree_fsr_selector_type) {
		print_indent(indent+1);
		printf("IF: ");
		switch (rule->rtree_fsr_selector_type) {
		case SB2_RULETREE_FSRULE_SELECTOR_PREFIX:
			printf("prefix '%s'\n",
				offset_to_ruletree_string_ptr(rule->rtree_fsr_selector_offs, NULL));
			break;
		case SB2_RULETREE_FSRULE_SELECTOR_DIR:
			printf("dir '%s'\n",
				offset_to_ruletree_string_ptr(rule->rtree_fsr_selector_offs, NULL));
			break;
		case SB2_RULETREE_FSRULE_SELECTOR_PATH:
			printf("path '%s'\n",
				offset_to_ruletree_string_ptr(rule->rtree_fsr_selector_offs, NULL));
			break;
		default:
			printf("ERROR: Unknown selector type %d\n",
				rule->rtree_fsr_selector_type);
			break;
		}
	}

	if (rule->rtree_fsr_condition_type) {
		const char *condstr = offset_to_ruletree_string_ptr(rule->rtree_fsr_condition_offs, NULL);

		print_indent(indent+1);
		printf("CONDITIONAL: ");
		switch (rule->rtree_fsr_condition_type) {
		case SB2_RULETREE_FSRULE_CONDITION_IF_ACTIVE_EXEC_POLICY_IS:
			printf("if_active_exec_policy_is '%s'\n", condstr);
			break;
		case SB2_RULETREE_FSRULE_CONDITION_IF_REDIRECT_IGNORE_IS_ACTIVE:
			printf("if_redirect_ignore_is_active '%s'\n", condstr);
			break;
		case SB2_RULETREE_FSRULE_CONDITION_IF_REDIRECT_FORCE_IS_ACTIVE:
			printf("if_redirect_force_is_active '%s'\n", condstr);
			break;
		case SB2_RULETREE_FSRULE_CONDITION_IF_ENV_VAR_IS_NOT_EMPTY:
			printf("if_env_var_is_not_empty '%s'\n", condstr);
			break;
		case SB2_RULETREE_FSRULE_CONDITION_IF_ENV_VAR_IS_EMPTY:
			printf("if_env_var_is_empty '%s'\n", condstr);
			break;
		default:
			printf("ERROR: Unknown condition type %d\n",
				rule->rtree_fsr_condition_type);
			break;
		}
	}

	if (rule->rtree_fsr_func_class) {
		print_indent(indent+1);
		printf("IF_CLASS: 0x%X ( ", rule->rtree_fsr_func_class);
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_OPEN)
		       printf("open ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_STAT)
		       printf("stat ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_EXEC)
		       printf("exec ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_SOCKADDR)
		       printf("sockaddr ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_FTSOPEN)
		       printf("ftsopen ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_GLOB)
		       printf("glob ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_GETCWD)
		       printf("getcwd ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_REALPATH)
		       printf("realpath ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_L10N)
		       printf("l10n ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_MKNOD)
		       printf("mknod ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_RENAME)
		       printf("rename ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_SYMLINK)
		       printf("symlink ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_CREAT)
		       printf("creat ");
		if (rule->rtree_fsr_func_class & SB2_INTERFACE_CLASS_PROC_FS_OP)
		       printf("proc_fs_op ");
		printf(")\n");
	}
	
	if (rule->rtree_fsr_binary_name) {
		const char *bin_name = offset_to_ruletree_string_ptr(rule->rtree_fsr_binary_name, NULL);
		print_indent(indent+1);
		printf("BINARY_NAME: '%s'\n", bin_name);
	}

	if (rule->rtree_fsr_exec_policy_name) {
		const char *ep_name = offset_to_ruletree_string_ptr(rule->rtree_fsr_exec_policy_name, NULL);
		print_indent(indent+1);
		printf("EXEC_POLICY_NAME: '%s'\n", ep_name);
	}

	print_indent(indent+1);
	printf("ACTION: ");
	switch (rule->rtree_fsr_action_type) {
	case SB2_RULETREE_FSRULE_ACTION_FALLBACK_TO_OLD_MAPPING_ENGINE:
		printf("FALLBACK_TO_OLD_MAPPING_ENGINE\n");
		break;	
	case SB2_RULETREE_FSRULE_ACTION_PROCFS:
		printf("sb2_procfs_mapper\n");
		break;	
	case SB2_RULETREE_FSRULE_ACTION_UNION_DIR:
		printf("union_dir => rule->rtree_fsr_rule_list_link\n");
		rule_list_link_label = "union_dir";
		break;	
	case SB2_RULETREE_FSRULE_ACTION_USE_ORIG_PATH:
		printf("use_orig_path\n");
		break;	
	case SB2_RULETREE_FSRULE_ACTION_FORCE_ORIG_PATH:
		printf("force_orig_path\n");
		break;	
	case SB2_RULETREE_FSRULE_ACTION_REPLACE_BY:
		printf("replace_by '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_SET_PATH:
		printf("set_path '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_MAP_TO:
		printf("map_to '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_REPLACE_BY_VALUE_OF_ENV_VAR:
		printf("replace_by_value_of_env_var '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_MAP_TO_VALUE_OF_ENV_VAR:
		printf("map_to_value_of_env_var '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_CONDITIONAL_ACTIONS:
		printf("actions => %d\n",
			rule->rtree_fsr_rule_list_link);
		rule_list_link_label = "actions";
		break;
	case SB2_RULETREE_FSRULE_ACTION_SUBTREE:
		printf("subtree => %d\n",
			rule->rtree_fsr_rule_list_link);
		rule_list_link_label = "rules";
		break;
	case SB2_RULETREE_FSRULE_ACTION_IF_EXISTS_THEN_MAP_TO:
		printf("if_exists_then_map_to '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	case SB2_RULETREE_FSRULE_ACTION_IF_EXISTS_THEN_REPLACE_BY:
		printf("if_exists_then_replace_by '%s'\n",
			offset_to_ruletree_string_ptr(rule->rtree_fsr_action_offs, NULL));
		break;
	default:
		printf("ERROR: Unknown action type %d\n",
			rule->rtree_fsr_action_type);
		break;
	}

	if (rule->rtree_fsr_rule_list_link) {
		print_indent(indent+1);
		printf("%s = {\n", rule_list_link_label);
		dump_objectlist(rule->rtree_fsr_rule_list_link, indent + 2);
		print_indent(indent+1);
		printf("}\n");
	}
	print_indent(indent);
	printf("}\n");
}
Пример #17
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);
}