/* 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); }
/* 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); }
/* 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; }
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); }
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); }
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); }
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 */ }
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); } }