void free_mapping_results(mapping_results_t *res) { if (res->mres_result_buf) free(res->mres_result_buf); if (res->mres_result_path_was_allocated && res->mres_result_path) free(res->mres_result_path); if (res->mres_virtual_cwd) free(res->mres_virtual_cwd); if (res->mres_allocated_exec_policy_name) free(res->mres_allocated_exec_policy_name); /* res->mres_error_text is a constant string, and not freed, ever */ #if 1 /* res->mres_fallback_to_lua_mapping_engine is a constant string, and not freed, ever */ #endif clear_mapping_results_struct(res); }
/* FIXME: why there was #if !defined(HAVE___OPENDIR2) around fts_open() ???? */ FTS * fts_open_gate( int *result_errno_ptr, FTS * (*real_fts_open_ptr)(char * const *path_argv, int options, int (*compar)(const FTSENT **,const FTSENT **)), const char *realfnname, char * const *path_argv, int options, int (*compar)(const FTSENT **,const FTSENT **)) { char *path; char * const *p; char **new_path_argv; char **np; int n; FTS *result; for (n=0, p=path_argv; *p; n++, p++); if ((new_path_argv = calloc(n+1, (sizeof(char *)))) == NULL) { return NULL; } for (n=0, p=path_argv, np=new_path_argv; *p; n++, p++, np++) { mapping_results_t res; clear_mapping_results_struct(&res); path = *p; sbox_map_path(realfnname, path, 0/*flags*/, &res, SB2_INTERFACE_CLASS_FTSOPEN); if (res.mres_result_path) { /* Mapped OK */ *np = strdup(res.mres_result_path); } else { *np = strdup(""); } free_mapping_results(&res); } /* FIXME: this system causes memory leaks */ errno = *result_errno_ptr; /* restore to orig.value */ result = (*real_fts_open_ptr)(new_path_argv, options, compar); *result_errno_ptr = errno; return(result); }
char *bindtextdomain_gate(int *result_errno_ptr, char *(*realfn)(const char *, const char *), const char *realfn_name, const char *domainname, const char *dirname) { mapping_results_t res; const char *mapped_dirname = dirname; char *result = NULL; clear_mapping_results_struct(&res); if (dirname != NULL) { sbox_map_path(realfn_name, dirname, 0, &res); assert(res.mres_result_path != NULL); mapped_dirname = res.mres_result_path; SB_LOG(SB_LOGLEVEL_DEBUG, "binding domain %s to %s", domainname, mapped_dirname); } errno = *result_errno_ptr; /* restore to orig.value */ result = (*realfn)(domainname, mapped_dirname); *result_errno_ptr = errno; free_mapping_results(&res); if (result && (*result != '\0')) { char *sbox_path = NULL; sbox_path = scratchbox_reverse_path(realfn_name, result); if (sbox_path) { /* FIXME: this will leak memory. nobody will free * the buffer at *sbox_path; in fact the manual * page denies that ("..must not be modified * or freed") */ result = sbox_path; } } return (result); }
/* ----- EXPORTED from interface.master: ----- */ char *sb2show__map_path2__(const char *binary_name, const char *mapping_mode, const char *fn_name, const char *pathname, int *readonly) { char *mapped__pathname = NULL; mapping_results_t mapping_result; (void)mapping_mode; /* mapping_mode is not used anymore. */ if (!sb2_global_vars_initialized__) sb2_initialize_global_variables(); clear_mapping_results_struct(&mapping_result); if (pathname != NULL) { sbox_map_path_for_sb2show(binary_name, fn_name, pathname, &mapping_result); if (mapping_result.mres_result_path) mapped__pathname = strdup(mapping_result.mres_result_path); if (readonly) *readonly = mapping_result.mres_readonly; } free_mapping_results(&mapping_result); SB_LOG(SB_LOGLEVEL_DEBUG, "%s '%s'", __func__, pathname); return(mapped__pathname); }
char *bindtextdomain_gate(char *(*realfn)(const char *, const char *), const char *realfn_name, const char *domainname, const char *dirname) { mapping_results_t res; const char *mapped_dirname = dirname; char *result = NULL; clear_mapping_results_struct(&res); if (dirname != NULL) { sbox_map_path(realfn_name, dirname, 0, &res); assert(res.mres_result_path != NULL); mapped_dirname = res.mres_result_path; SB_LOG(SB_LOGLEVEL_DEBUG, "binding domain %s to %s", domainname, mapped_dirname); } result = (*realfn)(domainname, mapped_dirname); free_mapping_results(&res); return (result); }
/* Map script interpreter: * Called with "rule" and "exec_policy" already in lua's stack, * leaves (possibly modified) "rule" and "exec_policy" to lua's stack. */ char *sb_execve_map_script_interpreter( const char *interpreter, const char *interp_arg, const char *mapped_script_filename, const char *orig_script_filename, char ***argv, char ***envp) { struct lua_instance *luaif; char *mapped_interpreter; int new_argc, new_envc; int res; luaif = get_lua(); if (!luaif) return(0); if (!argv || !envp) { SB_LOG(SB_LOGLEVEL_ERROR, "ERROR: sb_execve_map_script_interpreter: " "(argv || envp) == NULL"); release_lua(luaif); return NULL; } SB_LOG(SB_LOGLEVEL_NOISE, "sb_execve_map_script_interpreter: gettop=%d" " interpreter=%s interp_arg=%s " "mapped_script_filename=%s orig_script_filename=%s", lua_gettop(luaif->lua), interpreter, interp_arg, mapped_script_filename, orig_script_filename); lua_getfield(luaif->lua, LUA_GLOBALSINDEX, "sb_execve_map_script_interpreter"); /* stack now contains "rule", "exec_policy" and * "sb_execve_map_script_interpreter". * move "sb_execve_map_script_interpreter" to the bottom : */ lua_insert(luaif->lua, -3); lua_pushstring(luaif->lua, interpreter); if (interp_arg) lua_pushstring(luaif->lua, interp_arg); else lua_pushnil(luaif->lua); lua_pushstring(luaif->lua, mapped_script_filename); lua_pushstring(luaif->lua, orig_script_filename); strvec_to_lua_table(luaif, *argv); strvec_to_lua_table(luaif, *envp); /* args: rule, exec_policy, interpreter, interp_arg, * mapped_script_filename, orig_script_filename, * argv, envp * returns: rule, policy, result, mapped_interpreter, #argv, argv, * #envp, envp * "result" is one of: * 0: argv / envp were modified; mapped_interpreter was set * 1: argv / envp were not modified; mapped_interpreter was set * -1: deny exec. */ if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) { dump_lua_stack("sb_execve_map_script_interpreter M1", luaif->lua); } SB_LOG(SB_LOGLEVEL_NOISE, "sb_execve_map_script_interpreter: call lua, gettop=%d", lua_gettop(luaif->lua)); lua_call(luaif->lua, 8, 8); SB_LOG(SB_LOGLEVEL_NOISE, "sb_execve_map_script_interpreter: return from lua, gettop=%d", lua_gettop(luaif->lua)); if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) { dump_lua_stack("sb_execve_map_script_interpreter M2", luaif->lua); } mapped_interpreter = (char *)lua_tostring(luaif->lua, -5); if (mapped_interpreter) mapped_interpreter = strdup(mapped_interpreter); res = lua_tointeger(luaif->lua, -6); switch (res) { case 0: /* exec arguments were modified, replace contents of * argv and envp vectors */ SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: Updated argv&envp"); strvec_free(*argv); new_argc = lua_tointeger(luaif->lua, -4); lua_string_table_to_strvec(luaif, -3, argv, new_argc); new_envc = lua_tointeger(luaif->lua, -2); strvec_free(*envp); lua_string_table_to_strvec(luaif, -1, envp, new_envc); /* remove return values from the stack, leave rule & policy. */ lua_pop(luaif->lua, 6); break; case 1: SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: argv&envp were not modified"); /* remove return values from the stack, leave rule & policy. */ lua_pop(luaif->lua, 6); break; case 2: SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: use sbox_map_path_for_exec"); /* remove all return values from the stack. */ lua_pop(luaif->lua, 8); if (mapped_interpreter) free(mapped_interpreter); mapped_interpreter = NULL; { mapping_results_t mapping_result; clear_mapping_results_struct(&mapping_result); sbox_map_path_for_exec("script_interp", interpreter, &mapping_result); if (mapping_result.mres_result_buf) { mapped_interpreter = strdup(mapping_result.mres_result_buf); } free_mapping_results(&mapping_result); } SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: " "interpreter=%s mapped_interpreter=%s", interpreter, mapped_interpreter); break; case -1: SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: exec denied"); /* remove return values from the stack, leave rule & policy. */ lua_pop(luaif->lua, 6); if (mapped_interpreter) free(mapped_interpreter); mapped_interpreter = NULL; break; default: SB_LOG(SB_LOGLEVEL_ERROR, "sb_execve_map_script_interpreter: Unsupported result %d", res); /* remove return values from the stack, leave rule & policy. */ lua_pop(luaif->lua, 6); break; } if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) { dump_lua_stack("sb_execve_map_script_interpreter E2", luaif->lua); } SB_LOG(SB_LOGLEVEL_NOISE, "sb_execve_map_script_interpreter: at exit, gettop=%d", lua_gettop(luaif->lua)); release_lua(luaif); return mapped_interpreter; }
static int prepare_hashbang( char **mapped_file, /* In: script, out: mapped script interpreter */ char *orig_file, char ***argvp, char ***envpp, const char *exec_policy_name) { int argc, fd, c, i, j, n; char ch; char *mapped_interpreter = NULL; char **new_argv = NULL; char hashbang[SBOX_MAXPATH]; /* only 60 needed on linux, just be safe */ char interpreter[SBOX_MAXPATH]; char *interp_arg = NULL; char *tmp = NULL, *mapped_binaryname = NULL; int result = 0; if ((fd = open_nomap(*mapped_file, O_RDONLY)) < 0) { /* unexpected error, just run it */ return 0; } if ((c = read(fd, &hashbang[0], SBOX_MAXPATH - 1)) < 2) { /* again unexpected error, close fd and run it */ close_nomap_nolog(fd); return 0; } argc = elem_count(*argvp); /* extra element for hashbang argument */ new_argv = calloc(argc + 3, sizeof(char *)); /* skip any initial whitespace following "#!" */ for (i = 2; (hashbang[i] == ' ' || hashbang[i] == '\t') && i < c; i++) ; for (n = 0, j = i; i < c; i++) { ch = hashbang[i]; if (hashbang[i] == 0 || hashbang[i] == ' ' || hashbang[i] == '\t' || hashbang[i] == '\n') { hashbang[i] = 0; if (i > j) { if (n == 0) { char *ptr = &hashbang[j]; strcpy(interpreter, ptr); new_argv[n++] = strdup(interpreter); } else { /* this was the one and only * allowed argument for the * interpreter */ interp_arg = strdup(&hashbang[j]); new_argv[n++] = interp_arg; break; } } j = i + 1; } if (ch == '\n' || ch == 0) break; } new_argv[n++] = strdup(orig_file); /* the unmapped script path */ for (i = 1; (*argvp)[i] != NULL && i < argc; ) { new_argv[n++] = (*argvp)[i++]; } new_argv[n] = NULL; /* Now we need to update __SB2_ORIG_BINARYNAME to point to * the unmapped script interpreter (exec_map_script_interpreter * may change it again (not currently, but in the future) */ change_environment_variable( *envpp, "__SB2_ORIG_BINARYNAME=", interpreter); /* script interpreter mapping in C */ exec_policy_handle_t eph = find_exec_policy_handle(exec_policy_name); int c_mapping_result_code; const char *c_new_exec_policy_name = NULL; c_mapping_result_code = exec_map_script_interpreter(eph, exec_policy_name, interpreter, interp_arg, *mapped_file, orig_file, new_argv, &c_new_exec_policy_name, &mapped_interpreter); SB_LOG(SB_LOGLEVEL_DEBUG, "back from exec_map_script_interpreter => %d (%s)", c_mapping_result_code, (mapped_interpreter ? mapped_interpreter : "<NULL>")); switch (c_mapping_result_code) { case 0: /* exec arguments were modified, argv has been modified */ SB_LOG(SB_LOGLEVEL_DEBUG, "%s: <0> argv has been updated", __func__); break; case 1: SB_LOG(SB_LOGLEVEL_DEBUG, "%s: <1> argv was not modified", __func__); break; case 2: SB_LOG(SB_LOGLEVEL_DEBUG, "%s: <2> Use ordinary path mapping", __func__); if (mapped_interpreter) free(mapped_interpreter); mapped_interpreter = NULL; { mapping_results_t mapping_result; clear_mapping_results_struct(&mapping_result); sbox_map_path_for_exec("script_interp", interpreter, &mapping_result); if (mapping_result.mres_result_buf) { mapped_interpreter = strdup(mapping_result.mres_result_buf); } if (mapping_result.mres_exec_policy_name) c_new_exec_policy_name = strdup(mapping_result.mres_exec_policy_name); else c_new_exec_policy_name = NULL; free_mapping_results(&mapping_result); } SB_LOG(SB_LOGLEVEL_DEBUG, "%s: " "interpreter=%s mapped_interpreter=%s policy=%s", __func__, interpreter, mapped_interpreter, c_new_exec_policy_name ? c_new_exec_policy_name : "NULL"); break; case -1: SB_LOG(SB_LOGLEVEL_DEBUG, "%s: <-1> exec denied", __func__); if (mapped_interpreter) free(mapped_interpreter); mapped_interpreter = NULL; return(-1); default: SB_LOG(SB_LOGLEVEL_ERROR, "%s: Unsupported result %d", __func__, c_mapping_result_code); return(-1); } exec_policy_name = c_new_exec_policy_name; if (!mapped_interpreter) { SB_LOG(SB_LOGLEVEL_ERROR, "failed to map script interpreter=%s", interpreter); return(-1); } /* * Binaryname (the one expected by the rules) comes still from * the interpreter name so we set it here. Note that it is now * basename of the mapped interpreter (not the original one)! */ tmp = strdup(mapped_interpreter); mapped_binaryname = strdup(basename(tmp)); change_environment_variable(*envpp, "__SB2_BINARYNAME=", mapped_binaryname); free(mapped_binaryname); free(tmp); SB_LOG(SB_LOGLEVEL_DEBUG, "prepare_hashbang(): interpreter=%s," "mapped_interpreter=%s", interpreter, mapped_interpreter); /* feed this through prepare_exec to let it deal with * cpu transparency etc. */ result = prepare_exec("run_hashbang", exec_policy_name, mapped_interpreter, 1/*file_has_been_mapped, and rue&policy exist*/, new_argv, *envpp, (enum binary_type*)NULL, mapped_file, argvp, envpp); SB_LOG(SB_LOGLEVEL_DEBUG, "prepare_hashbang done: mapped_file='%s'", *mapped_file); 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); }
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); } }