summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauri Aarnio <Lauri.Aarnio@iki.fi>2008-10-23 17:27:55 +0300
committerLauri Leukkunen <lle@rahina.org>2008-10-23 19:18:01 +0300
commit0a44f98a97a22eb57ac34dea67623a2188038eda (patch)
tree23530e1eb51f5dab742443018eb14220c5b259d5
parentb779e037736239d3b8005506b898456c66c11a2a (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--Makefile1
-rw-r--r--docs/sb2-show.13
-rw-r--r--include/mapping.h3
-rw-r--r--include/sb2.h3
-rw-r--r--lua_scripts/create_reverse_rules.lua255
-rw-r--r--lua_scripts/mapping.lua65
-rw-r--r--lua_scripts/pathmaps/devel/00_default.lua9
-rw-r--r--lua_scripts/pathmaps/simple/00_default.lua9
-rw-r--r--luaif/luaif.c10
-rw-r--r--luaif/paths.c95
-rw-r--r--preload/interface.master6
-rw-r--r--preload/libsb2.c77
-rwxr-xr-xutils/sb28
-rw-r--r--utils/sb2-monitor.c21
-rw-r--r--utils/sb2-show.c12
15 files changed, 539 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 60eb23b..8ca15dc 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/utils/sb2 b/utils/sb2
index ed64882..1c39940 100755
--- a/utils/sb2
+++ b/utils/sb2
@@ -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,