diff options
author | Lauri Aarnio <Lauri.Aarnio@iki.fi> | 2008-10-23 17:27:55 +0300 |
---|---|---|
committer | Lauri Leukkunen <lle@rahina.org> | 2008-10-23 19:18:01 +0300 |
commit | 0a44f98a97a22eb57ac34dea67623a2188038eda (patch) | |
tree | 23530e1eb51f5dab742443018eb14220c5b259d5 | |
parent | b779e037736239d3b8005506b898456c66c11a2a (diff) |
Added path reversing logic; getcwd() etc now return backward-mapped results - i.e. getcwd(), realpath(), get_current_dir_name_gate() and getwd() now return the place where SB2 pretends to be, not the real path anymore - reverse mapping rules are created automatically when the session is created. However, there are still some situations where reverse mapping is disabled (see lua_scripts/create_reverse_rules.lua for details) - This also fixes a nasty bug with "mkdir -p" (which created directories to wrong locations in certain situations. "mkdir" witout "-p" was OK) - sb2-show: added new command "realcwd" - "devel" mapping mode: some paths were classified as virtual (virtual_path is a new attribute for rules: It disables reversing of that rule) - "simple" mapping mode: ~/.scratchbox2, .../share/scratchbox2 and /usr/bin/sb2-show were added to mapping rules - luaif.c: sb.decolonize_path() was disabled (It isn't anymore used from our Lua scripts, but I didn't
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | docs/sb2-show.1 | 3 | ||||
-rw-r--r-- | include/mapping.h | 3 | ||||
-rw-r--r-- | include/sb2.h | 3 | ||||
-rw-r--r-- | lua_scripts/create_reverse_rules.lua | 255 | ||||
-rw-r--r-- | lua_scripts/mapping.lua | 65 | ||||
-rw-r--r-- | lua_scripts/pathmaps/devel/00_default.lua | 9 | ||||
-rw-r--r-- | lua_scripts/pathmaps/simple/00_default.lua | 9 | ||||
-rw-r--r-- | luaif/luaif.c | 10 | ||||
-rw-r--r-- | luaif/paths.c | 95 | ||||
-rw-r--r-- | preload/interface.master | 6 | ||||
-rw-r--r-- | preload/libsb2.c | 77 | ||||
-rwxr-xr-x | utils/sb2 | 8 | ||||
-rw-r--r-- | utils/sb2-monitor.c | 21 | ||||
-rw-r--r-- | utils/sb2-show.c | 12 |
15 files changed, 539 insertions, 38 deletions
@@ -114,6 +114,7 @@ install-noarch: regular install -c -m 644 $(SRCDIR)/lua_scripts/mapping.lua $(prefix)/share/scratchbox2/lua_scripts/mapping.lua install -c -m 644 $(SRCDIR)/lua_scripts/argvenvp.lua $(prefix)/share/scratchbox2/lua_scripts/argvenvp.lua install -c -m 644 $(SRCDIR)/lua_scripts/argvenvp_gcc.lua $(prefix)/share/scratchbox2/lua_scripts/argvenvp_gcc.lua + install -c -m 644 $(SRCDIR)/lua_scripts/create_reverse_rules.lua $(prefix)/share/scratchbox2/lua_scripts/create_reverse_rules.lua install -c -m 644 $(SRCDIR)/lua_scripts/pathmaps/emulate/*.lua $(prefix)/share/scratchbox2/lua_scripts/pathmaps/emulate/ install -c -m 644 $(SRCDIR)/lua_scripts/pathmaps/simple/*.lua $(prefix)/share/scratchbox2/lua_scripts/pathmaps/simple/ diff --git a/docs/sb2-show.1 b/docs/sb2-show.1 index cddc5ce..c14b42f 100644 --- a/docs/sb2-show.1 +++ b/docs/sb2-show.1 @@ -45,6 +45,9 @@ Useful for debugging and tuning lua scripts of sb2. path [path1] [path2] [pathN] Show mappings of pathnames .TP +realcwd +Show real current working directory +.TP exec file [argv0] [argv1] [argvN] Show execve() modifications done by sb2 .TP diff --git a/include/mapping.h b/include/mapping.h index 5274c29..a9f9af4 100644 --- a/include/mapping.h +++ b/include/mapping.h @@ -29,4 +29,7 @@ extern int sb_execve_postprocess(char *exec_type, extern char *sb_query_exec_policy(const char *field_name, const char *binary_name, const char *real_binary_name); +extern char *scratchbox_reverse_path( + const char *func_name, const char *full_path); + #endif diff --git a/include/sb2.h b/include/sb2.h index ce5ddd3..503803b 100644 --- a/include/sb2.h +++ b/include/sb2.h @@ -41,7 +41,10 @@ struct lua_instance { #define SB2_LUA_C_INTERFACE_VERSION "35,lta-2008-10-01" struct lua_instance *get_lua(void); + +#if 0 char *sb_decolonize_path(const char *path); +#endif int sb_next_execve(const char *filename, char *const argv [], char *const envp[]); diff --git a/lua_scripts/create_reverse_rules.lua b/lua_scripts/create_reverse_rules.lua new file mode 100644 index 0000000..ad9f758 --- /dev/null +++ b/lua_scripts/create_reverse_rules.lua @@ -0,0 +1,255 @@ +-- Copyright (c) 2008 Nokia Corporation. +-- Author: Lauri T. Aarnio +-- +-- Licensed under MIT license + +-- This script is executed once after a new SB2 session has been created, +-- to create reversing rules for path mapping (see utils/sb2). +-- This is still simple, and may not work in all cases: This script +-- will shut down if problems are detected (then path reversing won't be +-- available and SB2 works just as it did before this feature was implemented) +-- +-- FIXME: +-- 1. Rules with conditional actions are not reversed correctly. Basically, +-- this script just gives up and marks the destinations with "use_orig_path". +-- This should be fixed, even if it is not a problem with our current +-- "official" mapping modes. +-- +-- 2. Reverse rules won't be created if the forward rules use "func_name" +-- conditions. It might be possible to fix that, but "func_names" certainly +-- complicate sorting of the generated reversing rules. +-- +-- 3. Rule chains with "next_chain" set to something else than 'nil' +-- are not currently supported. + +allow_reversing = true -- default = create reverse rules. + +-- Order of reverse rules is not necessarily the same as order of forward rules +function test_rev_rule_position(output_rules, d_path) + local n + for n=1,table.maxn(output_rules) do + local rule = output_rules[n] + if (rule.prefix and (rule.prefix ~= "") and + (isprefix(rule.prefix, d_path))) then + return n + end + -- "path" rules: (exact match) + if (rule.path == d_path) then + return n + end + end + return nil +end + +function reverse_one_rule(output_rules, rule, n) + local new_rule = {} + new_rule.comments = {} + + if rule.name then + new_rule.name = string.format( + "Rev: %s (%d)", rule.name, n) + else + new_rule.name = string.format( + "Rev: Rule %d", n) + end + + local forward_path + if (rule.prefix) then + forward_path = rule.prefix + elseif (rule.path) then + forward_path = rule.path + else + forward_path = nil + new_rule.error = string.format( + "--ERROR: Rule '%s' does not contain 'prefix' or 'path'", + new_rule.name) + end + + if (rule.func_name ~= nil) then + allow_reversing = false + end + + local d_path + if (rule.use_orig_path) then + new_rule.use_orig_path = true + d_path = forward_path + elseif (rule.actions) then + -- FIXME: To be implemented. See the "TODO" list at top. + new_rule.use_orig_path = true + d_path = forward_path + elseif (rule.map_to) then + d_path = rule.map_to .. forward_path + new_rule.replace_by = forward_path + elseif (rule.replace_by) then + d_path = rule.replace_by + new_rule.replace_by = forward_path + else + new_rule.error = string.format( + "--ERROR: Rule '%s' does not contain any actions", + new_rule.name) + end + + local idx + if (rule.prefix) then + new_rule.prefix = d_path + new_rule.orig_prefix = rule.prefix + idx = test_rev_rule_position(output_rules, d_path..":") + elseif (rule.path) then + new_rule.path = d_path + new_rule.orig_path = rule.path + idx = test_rev_rule_position(output_rules, d_path) + end + + if (idx ~= nil) then + -- a conflict, must reorganize + table.insert(new_rule.comments, string.format( + "--NOTE: '%s' conflicts with '%s', reorganized", + new_rule.name, output_rules[idx].name)) + + local x_path = nil + if (output_rules[idx].prefix) then + x_path = output_rules[idx].prefix + elseif (output_rules[idx].path) then + x_path = output_rules[idx].path + end + + table.insert(output_rules, idx, new_rule) + + if x_path then + local idx2 + idx2 = test_rev_rule_position(output_rules, x_path) + + if idx2 ~= idx+1 then + table.insert(new_rule.comments, string.format( + "--NOTE: '%s' DOUBLE CONFLICT with '%s'", + new_rule.name, output_rules[idx].name)) + end + end + + else + -- no conflicts + table.insert(output_rules, new_rule) + end +end + +function reverse_rules(input_rules) + local output_rules = {} + local n + for n=1,table.maxn(input_rules) do + local rule = input_rules[n] + + if rule.virtual_path then + -- don't reverse virtual paths + print("-- virtual_path set, not reversing", n) + else + reverse_one_rule(output_rules, rule, n) + end + + end + return(output_rules) +end + +function print_rules(rules) + local n + for n=1,table.maxn(rules) do + local rule = rules[n] + + print(string.format("\t{name=\"%s\",", rule.name)) + + local k + for k=1,table.maxn(rule.comments) do + print(rule.comments[k]) + end + + if (rule.orig_prefix) then + print("\t -- orig_prefix", rule.orig_prefix) + end + if (rule.orig_path) then + print("\t -- orig_path", rule.orig_path) + end + + if (rule.prefix) then + print("\t prefix=\""..rule.prefix.."\",") + end + if (rule.path) then + print("\t path=\""..rule.path.."\",") + end + + if (rule.use_orig_path) then + print("\t use_orig_path=true,") + end + -- FIXME: To be implemented. See the "TODO" list at top. + -- elseif (rule.actions) then + -- print("\t -- FIXME: handle 'actions'") + -- print(string.format( + -- "\t %s=\"%s\",\n\t use_orig_path=true},", + -- sel, fwd_target)) + if (rule.map_to) then + print("\t map_to=\""..rule.map_to.."\",") + end + if (rule.replace_by) then + print("\t replace_by=\""..rule.replace_by.."\",") + end + if (rule.error) then + print("\t -- ",rule.error) + allow_reversing = false + end + print("\t},") + end +end + +function process_chains(chains_table) + local n + + for n=1,table.maxn(chains_table) do + if chains_table[n].noentry then + print("-- ========== ",n) + print("-- noentry") + else + print(string.format("-- ======= Chain %d =======",n)) + print(string.format("reverse_chain_%d = {",n)) + + if chains_table[n].next_chain then + -- FIXME: Handle next_chain!!! + print(" -- NOTE: next_chain is not nil,") + print(" -- can't create reversing rules") + allow_reversing = false + else + print(" next_chain=nil,") + end + + if chains_table[n].binary then + print(string.format(" binary=\"%s\",", + chains_table[n].binary,"\n")) + else + print(" binary=nil,") + end + + local rev_rules = reverse_rules(chains_table[n].rules) + if (allow_reversing) then + print(" rules={") + print_rules(rev_rules) + print(" }") + end + print("}") + end + end + + if (allow_reversing) then + print("reverse_chains = {") + for n=1,table.maxn(chains_table) do + if chains_table[n].noentry then + print(string.format(" -- %d = noentry",n)) + else + print(string.format(" reverse_chain_%d,",n)) + end + end + print("}") + else + print("-- Failed to create reverse rules.") + print("reverse_chains = nil") + end +end + +process_chains(active_mode_mapping_rule_chains) + diff --git a/lua_scripts/mapping.lua b/lua_scripts/mapping.lua index f42aee9..1e4adde 100644 --- a/lua_scripts/mapping.lua +++ b/lua_scripts/mapping.lua @@ -133,6 +133,21 @@ active_mode_exec_policy_chains = {} load_and_check_rules() +-- load reverse mapping rules, if those have been created +-- (the file does not exist during the very first round here) +reverse_chains = nil +if (sb.path_exists(session_dir .. "/rev_rules.lua")) then + sb.log("debug", "Loading reverse rules") + do_file(session_dir .. "/rev_rules.lua") +end +if (debug_messages_enabled) then + if reverse_chains ~= nil then + sb.log("debug", "Loaded reverse rules") + else + sb.log("debug", "No reverse rules") + end +end + function sbox_execute_replace_rule(path, replacement, rule) local ret = nil @@ -283,11 +298,20 @@ function find_rule(chain, func, full_path) or string.match(func, wrk.rules[i].func_name))) then -- "prefix" rules: -- compare prefix (only if a non-zero prefix) + local rulename + if (debug_messages_enabled) then + rulename = wrk.rules[i].name + if rulename == nil then + rulename = string.format("#%d",i) + end + end if (wrk.rules[i].prefix and (wrk.rules[i].prefix ~= "") and (isprefix(wrk.rules[i].prefix, full_path))) then if (debug_messages_enabled) then - sb.log("noise", string.format("selected prefix rule %d (%s)", i, wrk.rules[i].prefix)) + sb.log("noise", string.format( + "selected prefix rule '%s' (%s)", + rulename, wrk.rules[i].prefix)) end min_path_len = string.len(wrk.rules[i].prefix) return wrk.rules[i], min_path_len @@ -295,7 +319,9 @@ function find_rule(chain, func, full_path) -- "path" rules: (exact match) if (wrk.rules[i].path == full_path) then if (debug_messages_enabled) then - sb.log("noise", string.format("selected path rule %d (%s)", i, wrk.rules[i].path)) + sb.log("noise", string.format( + "selected path rule '%s' (%s)", + rulename, wrk.rules[i].path)) end min_path_len = string.len(wrk.rules[i].path) return wrk.rules[i], min_path_len @@ -427,3 +453,38 @@ function sb_find_exec_policy(binaryname, mapped_file) return 0, nil end +-- sbox_reverse_path is called from libsb2.so +-- returns "orig_path" +function sbox_reverse_path(binary_name, func_name, full_path) + -- loop through the chains, first match is used + local min_path_len = 0 + local rule = nil + local chain = nil + + if (reverse_chains ~= nil) then + chain = find_chain(reverse_chains, binary_name) + end + if (chain == nil) then + -- reverse mapping is an optional feature, + -- so it isn't really an error if the rule + -- can't be found. + sb.log("info", string.format("Unable to find REVERSE chain for: %s(%s)", + func_name, full_path)) + + return nil + end + + rule, min_path_len = find_rule(chain, func_name, full_path) + if (not rule) then + -- not even a default rule found + sb.log("info", string.format("Unable to find REVERSE rule for: %s(%s)", func_name, full_path)) + return nil + end + + local rule2, exec_policy2, orig_path, ro2 + rule2, exec_policy2, orig_path, ro2 = sbox_translate_path(rule, + binary_name, func_name, full_path) + + return orig_path +end + diff --git a/lua_scripts/pathmaps/devel/00_default.lua b/lua_scripts/pathmaps/devel/00_default.lua index b38a451..a0febd5 100644 --- a/lua_scripts/pathmaps/devel/00_default.lua +++ b/lua_scripts/pathmaps/devel/00_default.lua @@ -337,28 +337,29 @@ simple_chain = { -- 98. Scratchbox 1 emulation rules -- (some packages have hard-coded paths to the SB1 enviroment; -- replace those by the correct locations in our environment) + -- (these are marked "virtual"; these won't be reversed) -- "libtool" for arm {prefix = "/scratchbox/compilers/cs2005q3.2-glibc2.5-arm/arch_tools/share/libtool", replace_by = sb2_share_dir .. "/libtool", log_level = "warning", - readonly = true}, + readonly = true, virtual_path = true}, -- "libtool" for i386 {prefix = "/scratchbox/compilers/cs2005q3.2-glibc-i386/arch_tools/share", replace_by = tools .. "/usr/share", log_level = "warning", - readonly = true}, + readonly = true, virtual_path = true}, {prefix = "/scratchbox/tools/bin", replace_by = tools .. "/usr/bin", log_level = "warning", - readonly = true}, + readonly = true, virtual_path = true}, {prefix = "/scratchbox/tools/autotools/automake-1.7/share/automake-1.7", replace_by = tools .. "/usr/share/automake-1.7", log_level = "warning", - readonly = true}, + readonly = true, virtual_path = true}, -- otherwise, don't map /scratchbox, some people still -- keep their projects there. diff --git a/lua_scripts/pathmaps/simple/00_default.lua b/lua_scripts/pathmaps/simple/00_default.lua index 44311c0..d1534ff 100644 --- a/lua_scripts/pathmaps/simple/00_default.lua +++ b/lua_scripts/pathmaps/simple/00_default.lua @@ -30,6 +30,15 @@ simple_chain = { replace_by = sbox_dir.."/share/scratchbox2/scripts", readonly = true}, + {prefix = sbox_user_home_dir .. "/.scratchbox2", + use_orig_path = true}, + + {prefix = sbox_dir .. "/share/scratchbox2", + use_orig_path = true}, + + {path = "/usr/bin/sb2-show", + use_orig_path = true, readonly = true}, + -- ----------------------------------------------- -- 99. Other rules. {prefix = "/lib", map_to = target_root}, diff --git a/luaif/luaif.c b/luaif/luaif.c index 4d83e33..5dc8372 100644 --- a/luaif/luaif.c +++ b/luaif/luaif.c @@ -159,12 +159,16 @@ static struct lua_instance *my_lua_instance = NULL; static void load_and_execute_lua_file(struct lua_instance *luaif, const char *filename) { + const char *errmsg; + switch(luaL_loadfile(luaif->lua, filename)) { case LUA_ERRFILE: fprintf(stderr, "Error loading %s\n", filename); exit(1); case LUA_ERRSYNTAX: - fprintf(stderr, "Syntax error in %s\n", filename); + errmsg = lua_tostring(luaif->lua, -1); + fprintf(stderr, "Syntax error in %s (%s)\n", filename, + (errmsg?errmsg:"")); exit(1); case LUA_ERRMEM: fprintf(stderr, "Memory allocation error while " @@ -335,6 +339,7 @@ void sb2__load_and_execute_lua_file__(const char *filename) load_and_execute_lua_file(luaif, filename); } +#if 0 /* DISABLED 2008-10-23/LTA: sb_decolonize_path() is not currently available*/ /* "sb.decolonize_path", to be called from lua code */ static int lua_sb_decolonize_path(lua_State *l) { @@ -356,6 +361,7 @@ static int lua_sb_decolonize_path(lua_State *l) free(path); return 1; } +#endif /* "sb.readlink", to be called from lua code */ static int lua_sb_readlink(lua_State *l) @@ -548,7 +554,9 @@ static const luaL_reg reg[] = {"getdirlisting", lua_sb_getdirlisting}, #endif {"readlink", lua_sb_readlink}, +#if 0 {"decolonize_path", lua_sb_decolonize_path}, +#endif {"log", lua_sb_log}, {"setenv", lua_sb_setenv}, {"path_exists", lua_sb_path_exists}, diff --git a/luaif/paths.c b/luaif/paths.c index a3dff17..db14001 100644 --- a/luaif/paths.c +++ b/luaif/paths.c @@ -273,7 +273,28 @@ static void remove_dots_and_dotdots_from_path_entries( } } -static char *absolute_path(const char *path) +static char *sb_reversing_getcwd(const char *fn_name, char *buf, size_t bufsize) +{ + char *rev_path = NULL; + + if (!getcwd_nomap_nolog(buf, bufsize)) { + return(NULL); + } + + rev_path = scratchbox_reverse_path(fn_name, buf); + + if (rev_path) { + SB_LOG(SB_LOGLEVEL_DEBUG, "REV: '%s' => '%s'", buf, rev_path); + snprintf(buf, bufsize, "%s", rev_path); + } else { + SB_LOG(SB_LOGLEVEL_DEBUG, "REV failed."); + } + free(rev_path); + + return(buf); +} + +static char *absolute_path(const char *fn_name, const char *path) { char *cpath = NULL; @@ -286,7 +307,7 @@ static char *absolute_path(const char *path) char cwd[PATH_MAX + 1]; memset(cwd, '\0', sizeof(cwd)); - if (!getcwd_nomap_nolog(cwd, sizeof(cwd))) { + if (!sb_reversing_getcwd(fn_name, cwd, sizeof(cwd))) { /* getcwd() returns NULL if the path is really long. * In this case this really won't be able to do all * path mapping steps, but sb_decolonize_path() @@ -307,7 +328,7 @@ static char *absolute_path(const char *path) /* returns an allocated buffer containing absolute, * decolonized version of "path" */ -char *sb_decolonize_path(const char *path) +static char *sb_decolonize_path(const char *fn_name, const char *path) { char *cpath; struct path_entry_list list; @@ -322,7 +343,7 @@ char *sb_decolonize_path(const char *path) list.pl_first = NULL; - cpath = absolute_path(path); + cpath = absolute_path(fn_name, path); if (!cpath) { SB_LOG(SB_LOGLEVEL_NOTICE, "sb_decolonize_path forced to use relative path '%s'", @@ -342,7 +363,7 @@ char *sb_decolonize_path(const char *path) /* dirname() is not thread safe (may return pointer to static buffer), * so we'll have our own version, which always returns absolute dirnames: */ -static char *sb_abs_dirname(const char *path) +static char *sb_abs_dirname(const char *fn_name, const char *path) { char *cpath; struct path_entry_list list; @@ -353,7 +374,7 @@ static char *sb_abs_dirname(const char *path) list.pl_first = NULL; - cpath = absolute_path(path); + cpath = absolute_path(fn_name, path); if (!cpath) return(NULL); split_path_to_path_entries(cpath, &list); @@ -424,7 +445,7 @@ static char *call_lua_function_sbox_translate_path( */ char *cleaned_path; - cleaned_path = sb_decolonize_path(traslate_result); + cleaned_path = sb_decolonize_path(func_name, traslate_result); if (*cleaned_path != '/') { /* oops, got a relative path. CWD is too long. */ SB_LOG(SB_LOGLEVEL_DEBUG, @@ -513,6 +534,40 @@ static int call_lua_function_sbox_get_mapping_requirements( return(rule_found); } +static char *call_lua_function_sbox_reverse_path( + struct lua_instance *luaif, + const char *binary_name, + const char *func_name, + const char *full_path) +{ + char *orig_path = NULL; + + SB_LOG(SB_LOGLEVEL_NOISE, "calling sbox_reverse_path for %s(%s)", + func_name, full_path); + + lua_getfield(luaif->lua, LUA_GLOBALSINDEX, "sbox_reverse_path"); + lua_pushstring(luaif->lua, binary_name); + lua_pushstring(luaif->lua, func_name); + lua_pushstring(luaif->lua, full_path); + /* 3 arguments, returns orig_path */ + lua_call(luaif->lua, 3, 1); + + orig_path = (char *)lua_tostring(luaif->lua, -1); + if (orig_path) { + orig_path = strdup(orig_path); + } + lua_pop(luaif->lua, 1); /* remove return value */ + + if (orig_path) { + SB_LOG(SB_LOGLEVEL_DEBUG, "orig_path='%s'", orig_path); + } else { + SB_LOG(SB_LOGLEVEL_INFO, + "No result from sbox_reverse_path for: %s '%s'", + func_name, full_path); + } + return(orig_path); +} + /* ========== Path resolution: ========== */ /* clean up path resolution environment from lua stack */ @@ -706,8 +761,8 @@ static char *sb_path_resolution( char *dirnam; int last_in_dirnam_is_slash; - dirnam = sb_abs_dirname(work->pe_full_path); - if (!dirname) { + dirnam = sb_abs_dirname(func_name, work->pe_full_path); + if (!dirnam) { /* this should not happen. * work->pe_full_path is supposed to * be absolute path. @@ -874,7 +929,7 @@ static char *scratchbox_path_internal( char *decolon_path = NULL; char *full_path_for_rule_selection = NULL; - full_path_for_rule_selection = sb_decolonize_path(path); + full_path_for_rule_selection = sb_decolonize_path(func_name, path); if (*full_path_for_rule_selection != '/') { SB_LOG(SB_LOGLEVEL_DEBUG, @@ -946,6 +1001,7 @@ static char *scratchbox_path_internal( (*mapping_result == '/')) { char cwd[PATH_MAX + 1]; + /* here we want the real CWD, not a reversed one: */ if (getcwd_nomap_nolog(cwd, sizeof(cwd))) { int cwd_len = strlen(cwd); int result_len = strlen(mapping_result); @@ -1032,3 +1088,22 @@ char *scratchbox_path_for_exec( path, ro_flagp, dont_resolve_final_symlink, 1)); } +char *scratchbox_reverse_path( + const char *func_name, + const char *full_path) +{ + char binary_name[PATH_MAX+1]; + char *bin_name; + struct lua_instance *luaif; + + memset(binary_name, '\0', PATH_MAX+1); + if (!(bin_name = getenv("__SB2_BINARYNAME"))) { + bin_name = "UNKNOWN"; + } + strcpy(binary_name, bin_name); + + luaif = get_lua(); + return (call_lua_function_sbox_reverse_path( + luaif, binary_name, func_name, full_path)); +} + diff --git a/preload/interface.master b/preload/interface.master index d3ace83..1521ba8 100644 --- a/preload/interface.master +++ b/preload/interface.master @@ -27,6 +27,8 @@ EXPORT: void _fini(void) EXPORT: char *sb2show__map_path2__(const char *binary_name, \ const char *mapping_mode, const char *fn_name, const char *pathname, \ int *readonly) +EXPORT: char * sb2show__get_real_cwd__(const char *binary_name, \ + const char *fn_name) EXPORT: int sb2show__execve_mods__( \ char *file, \ char *const *orig_argv, char *const *orig_envp, \ @@ -57,6 +59,9 @@ GATE: char * getcwd (char *buf, size_t size) : returns_string create_nomap_nolog GATE: char * get_current_dir_name (void) : returns_string GATE: char * getwd (char *buf) : returns_string +GATE: char *realpath(const char *name, char *resolved) : \ + map(name) returns_string + GATE: int uname(struct utsname *buf) #ifdef HAVE_FTS_H @@ -317,7 +322,6 @@ WRAP: READLINK_TYPE readlink(const char *path, char *buf, size_t bufsize) : \ WRAP: READLINK_TYPE readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize) : \ dont_resolve_final_symlink map_at(dirfd,pathname) -WRAP: char *realpath(const char *name, char *resolved) : map(name) returns_string WRAP: int remove(const char *pathname) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) #ifdef HAVE_REMOVEXATTR diff --git a/preload/libsb2.c b/preload/libsb2.c index ee34ef2..80190e9 100644 --- a/preload/libsb2.c +++ b/preload/libsb2.c @@ -459,11 +459,13 @@ char * get_current_dir_name_gate( return NULL; } if (*cwd != '\0') { - sbox_path = scratchbox_path(realfnname, cwd, NULL/*RO-flag*/, - 0/*dont_resolve_final_symlink*/); + sbox_path = scratchbox_reverse_path(realfnname, cwd); + } + if (sbox_path) { + free(cwd); + return sbox_path; } - free(cwd); - return sbox_path; + return(cwd); /* failed to reverse it */ } @@ -481,19 +483,31 @@ char *getcwd_gate ( return NULL; } if (*cwd != '\0') { - sbox_path = scratchbox_path(realfnname, cwd, NULL/*RO-flag*/, - 0/*dont_resolve_final_symlink*/); + sbox_path = scratchbox_reverse_path(realfnname, cwd); } if (sbox_path) { +SB_LOG(SB_LOGLEVEL_DEBUG, "GETCWD: '%s'", sbox_path); if(buf) { + if (strlen(sbox_path) >= size) { + /* path does not fit to the buffer */ + free(sbox_path); + errno = ERANGE; + return(NULL); + } strncpy(buf, sbox_path, size); free(sbox_path); } else { - /* buf==NULL: real getcwd() used malloc() to allocate cwd */ + /* buf==NULL: real getcwd() used malloc() to + * allocate cwd (some implementations) [or the + * behavior may be unspecified (posix definition)] + * Assume memory was allocated, because the real + * getcwd() already returned a pointer to us... + */ free(cwd); cwd = sbox_path; } } +SB_LOG(SB_LOGLEVEL_DEBUG, "GETCWD: returns '%s'", cwd); return cwd; } @@ -510,11 +524,14 @@ char * getwd_gate( return NULL; } if (*cwd != '\0') { - sbox_path = scratchbox_path(realfnname, cwd, NULL/*RO-flag*/, - 0/*dont_resolve_final_symlink*/); + sbox_path = scratchbox_reverse_path(realfnname, cwd); } if (sbox_path) { if(buf) { + if (strlen(sbox_path) >= PATH_MAX) { + free(sbox_path); + return(NULL); + } strcpy(buf, sbox_path); free(sbox_path); } else { @@ -526,6 +543,38 @@ char * getwd_gate( return cwd; } +char *realpath_gate( + char *(*real_realpath_ptr)(const char *name, char *resolved), + const char *realfnname, + const char *name, /* name, already mapped */ + char *resolved) +{ + SBOX_MAP_PROLOGUE(); + char *rp; + + if ((rp = (*real_realpath_ptr)(name,resolved)) == NULL) { + return NULL; + } + if (*rp != '\0') { + sbox_path = scratchbox_reverse_path(realfnname, rp); + if (sbox_path) { + if (resolved) { + strncpy(resolved, sbox_path, PATH_MAX); + rp = resolved; + free(sbox_path); + } else { + /* resolved was null - assume that glibc + * allocated memory */ + free(rp); + rp = sbox_path; + } + } /* else not reversed, just return rp */ + } +SB_LOG(SB_LOGLEVEL_DEBUG, "REALPATH: returns '%s'", rp); + return(rp); +} + + /* "SB2_WRAP_GLOB" needs to be defined on systems where the C library * is not based on glibc (or not compatible with glob() from glibc 2.7) */ @@ -817,6 +866,16 @@ char *sb2show__map_path2__(const char *binary_name, const char *mapping_mode, return(mapped__pathname); } +char *sb2show__get_real_cwd__(const char *binary_name, const char *fn_name) +{ + char path[PATH_MAX]; + + if (getcwd_nomap_nolog(path, sizeof(path))) { + return(strdup(path)); + } + return(NULL); +} + /* ---- support functions for the generated interface: */ /* returns true, if the "mode" parameter of fopen() (+friends) @@ -662,6 +662,14 @@ export DEB_HOST_GNU_SYSTEM export LD_LIBRARY_PATH # ------------ +# Now everything is ready, programs can be executed in SB2'ed environment. +# Create reverse mapping rules before starting the actual command (or shell) +sb2-monitor -L $SBOX_LIBSB2 -- $SBOX_DIR/bin/sb2-show \ + execluafile $SBOX_SESSION_DIR/lua_scripts/create_reverse_rules.lua \ + >$SBOX_SESSION_DIR/rev_rules.lua + +# ------------ + if [ $# -gt 0 -o "$STDIN" = true ] ; then binary="$1" diff --git a/utils/sb2-monitor.c b/utils/sb2-monitor.c index e194fe7..1ba7a2b 100644 --- a/utils/sb2-monitor.c +++ b/utils/sb2-monitor.c @@ -58,8 +58,7 @@ static void usage_exit(const char *errmsg, int exitstatus) "\n%s: Usage:\n" "\t%s [options_for_%s] -- command [parameters]\n" "\nOptions:\n" - "\t-x program\tExecute 'program' after 'command' terminates " - "(mandatory)\n" + "\t-x program\tExecute 'program' after 'command' terminates\n" "\t-d\tEnable debug messages\n" "\nExample:\n" "\t%s -x /bin/echo -- signaltester -n 5\n", @@ -247,9 +246,6 @@ int main(int argc, char *argv[]) if (optind >= argc) usage_exit("Wrong number of parameters", 1); - if (!command_to_exec_at_end) - usage_exit("-x option is mantadory", 1); - original_process_group = getpgrp(); DEBUG_MSG("PGID=%d\n", (int)getpgrp()); @@ -414,12 +410,15 @@ int main(int argc, char *argv[]) } DEBUG_MSG("%s %s\n", exit_reason, exit_status); - /* time to exec the external script */ - execlp(command_to_exec_at_end, command_to_exec_at_end, - exit_reason, exit_status, NULL); + if (command_to_exec_at_end) { + /* time to exec the external script */ + execlp(command_to_exec_at_end, command_to_exec_at_end, + exit_reason, exit_status, NULL); - /* OOPS, exec failed */ - DEBUG_MSG("Failed to execute %s\n", command_to_exec_at_end); - return(1); + /* OOPS, exec failed */ + DEBUG_MSG("Failed to execute %s\n", command_to_exec_at_end); + return(1); + } + return(0); } diff --git a/utils/sb2-show.c b/utils/sb2-show.c index 75314e3..626717c 100644 --- a/utils/sb2-show.c +++ b/utils/sb2-show.c @@ -43,6 +43,8 @@ static void usage_exit(const char *progname, const char *errmsg, int exitstatus) "\nCommands:\n" "\tpath [path1] [path2].." "\tShow mappings of pathnames\n" + "\trealcwd" + "\tShow real current working directory\n" "\texec file argv0 [argv1] [argv2].." "\tShow execve() modifications\n" "\tlog-error 'message'" @@ -277,6 +279,14 @@ static void command_show_path(const char *binary_name, } } +static void command_show_realcwd(const char *binary_name, const char *fn_name) +{ + char *real_cwd_path = NULL; + + real_cwd_path = sb2show__get_real_cwd__(binary_name, fn_name); + printf("%s\n", real_cwd_path ? real_cwd_path : "<null>"); +} + /* read paths from stdin, report paths that are not mapped to specified * directory. * returns 0 if all OK, 1 if one or more paths were not mapped. @@ -451,6 +461,8 @@ int main(int argc, char *argv[]) if (!strcmp(argv[optind], "path")) { command_show_path(binary_name, function_name, argv + optind + 1); + } else if (!strcmp(argv[optind], "realcwd")) { + command_show_realcwd(binary_name, function_name); } else if (!strcmp(argv[optind], "exec")) { command_show_exec(binary_name, function_name, progname, argc - (optind+1), argv + optind + 1, |