summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauri Leukkunen <lle@rahina.org>2007-04-12 23:47:52 +0300
committerLauri Leukkunen <lle@rahina.org>2007-04-12 23:47:52 +0300
commitd3c1482adcb3a3dd3cba84b2a2fee425fc18213d (patch)
tree942d802a2f1eddb885a8f34a4bfd7e79bc1acbb8
parent9c0fc6d3a7712e1414e9664964edd9f40450e2b4 (diff)
Add multiple mapping modes support
Mapping modes can be selected by exporting SBOX2_MAPMODE environment variable. Currently there are two, default and emulate. Signed-off-by: Lauri Leukkunen <lle@rahina.org>
-rw-r--r--Makefile5
-rw-r--r--mapping/emumode.c16
-rw-r--r--mapping/mapping.c101
-rw-r--r--redir_scripts/main.lua114
-rw-r--r--redir_scripts/preload/default/00_default.lua (renamed from redir_scripts/preload/00_default.lua)0
-rw-r--r--redir_scripts/preload/default/10_basic_chains.lua (renamed from redir_scripts/preload/10_basic_chains.lua)0
-rw-r--r--redir_scripts/preload/default/XX_catchall.lua (renamed from redir_scripts/preload/XX_catchall.lua)2
-rw-r--r--redir_scripts/preload/emulate/00_default.lua20
-rwxr-xr-xutils/sb23
9 files changed, 143 insertions, 118 deletions
diff --git a/Makefile b/Makefile
index ca3439f..df7b21c 100644
--- a/Makefile
+++ b/Makefile
@@ -28,13 +28,16 @@ install: $(targets)
install -d -m 755 $(prefix)/lib
install -d -m 755 $(prefix)/share/scratchbox2/redir_scripts
install -d -m 755 $(prefix)/share/scratchbox2/redir_scripts/preload
+ install -d -m 755 $(prefix)/share/scratchbox2/redir_scripts/preload/default
+ install -d -m 755 $(prefix)/share/scratchbox2/redir_scripts/preload/emulate
install -c -m 755 preload/libsb2.so $(prefix)/lib/libsb2.so
install -c -m 755 utils/sb2 $(prefix)/bin/sb2
install -c -m 755 utils/sb2-build-libtool.sh $(prefix)/bin/sb2-build-libtool
install -c -m 755 utils/sb_gcc_wrapper $(prefix)/bin/sb_gcc_wrapper
install -c -m 755 scripts/sb2rc $(prefix)/share/scratchbox2/sb2rc
install -c -m 644 redir_scripts/main.lua $(prefix)/share/scratchbox2/redir_scripts/main.lua
- install -c -m 644 redir_scripts/preload/*.lua $(prefix)/share/scratchbox2/redir_scripts/preload/
+ install -c -m 644 redir_scripts/preload/default/*.lua $(prefix)/share/scratchbox2/redir_scripts/preload/default/
+ install -c -m 644 redir_scripts/preload/emulate/*.lua $(prefix)/share/scratchbox2/redir_scripts/preload/emulate/
install -c -m 644 etc/sb2.config.sample $(prefix)/share/scratchbox2/sb2.config.sample
@for f in $(gcc_bins_expanded); do \
ln -sf sb_gcc_wrapper $$f; \
diff --git a/mapping/emumode.c b/mapping/emumode.c
deleted file mode 100644
index 6e9bd37..0000000
--- a/mapping/emumode.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (C) 2007 Lauri Leukkunen <lle@rahina.org>
- *
- * Licensed under LGPL 2.1, see toplevel LICENSE file for details.
- *
- * emumode.c implements target emulation mapping profile.
- * It maps everything except /tmp, /dev, /proc and /sys to
- * $SBOX_TARGET_ROOT. It doesn't use the cache so there's
- * no conflict between emumode and the default mapping mode.
- */
-
-#include <mapping.h>
-
-char *emumode_map(const char *path)
-{
-}
diff --git a/mapping/mapping.c b/mapping/mapping.c
index 6a04c1c..b2bc421 100644
--- a/mapping/mapping.c
+++ b/mapping/mapping.c
@@ -109,7 +109,8 @@ char *decolonize_path(const char *path)
return NULL;
}
unsigned int l = (strlen(cwd) + 1 + strlen(path) + 1);
- cpath = malloc((strlen(cwd) + 1 + strlen(path) + 1) * sizeof(char));
+ cpath = malloc((strlen(cwd) + 1
+ + strlen(path) + 1) * sizeof(char));
memset(cpath, '\0', l);
strcpy(cpath, cwd);
strcat(cpath, "/");
@@ -134,7 +135,8 @@ char *decolonize_path(const char *path)
}
*index = '\0';
if (index == (start)) {
- goto proceed; /* skip over empty strings resulting from // */
+ goto proceed; /* skip over empty strings
+ resulting from // */
}
if (strcmp(start, "..") == 0) {
@@ -178,18 +180,25 @@ proceed:
#ifndef DISABLE_CACHE
-static char *create_sb2cache_path(const char *binary_name, const char *func_name, const char *path)
+static char *create_sb2cache_path(const char *mapping_mode,
+ const char *binary_name,
+ const char *func_name,
+ const char *path)
{
char *target_dir = getenv("SBOX_MAPPING_CACHE");
char *cache_path;
unsigned int length;
- length = strlen(target_dir) + strlen(path) + 1 + strlen(binary_name) + 1 + strlen(func_name) + 4 + 1;
+ length = strlen(mapping_mode) + 1 + strlen(target_dir) + strlen(path)
+ + 1 + strlen(binary_name) + 1 + strlen(func_name) + 4 + 1;
+
cache_path = malloc(length * sizeof(char));
memset(cache_path, '\0', length);
strcpy(cache_path, target_dir);
strcat(cache_path, path);
strcat(cache_path, ".");
+ strcat(cache_path, mapping_mode);
+ strcat(cache_path, ".");
strcat(cache_path, binary_name);
strcat(cache_path, ".");
strcat(cache_path, func_name);
@@ -198,16 +207,20 @@ static char *create_sb2cache_path(const char *binary_name, const char *func_name
}
/*
- * return NULL if not found from cache, or if the cache is outdated compared to sb2_timestamp
+ * Return NULL if not found from cache, or if the cache is outdated
+ * compared to sb2_timestamp.
*/
-static char *read_sb2cache(const char *binary_name, const char *func_name, const char *path)
+static char *read_sb2cache(const char *mapping_mode,
+ const char *binary_name,
+ const char *func_name,
+ const char *path)
{
char *link_path = NULL;
struct stat64 s;
if (getenv("SBOX_DISABLE_MAPPING_CACHE")) return NULL;
- char *cache_path = create_sb2cache_path(binary_name, func_name, path);
+ char *cache_path = create_sb2cache_path(mapping_mode, binary_name, func_name, path);
if (lstat64(cache_path, &s) < 0 ||
(s.st_mtime < get_sb2_timestamp())) {
@@ -261,9 +274,13 @@ exit:
}
/*
- * if the cache dir doesn't exist, this will create it
+ * If the cache dir doesn't exist, this will create it.
*/
-static int insert_sb2cache(const char *binary_name, const char *func_name, const char *path, const char *map_to)
+static int insert_sb2cache(const char *mapping_mode,
+ const char *binary_name,
+ const char *func_name,
+ const char *path,
+ const char *map_to)
{
char *cache_path;
char *dcopy;
@@ -287,7 +304,8 @@ static int insert_sb2cache(const char *binary_name, const char *func_name, const
}
}
- cache_path = create_sb2cache_path(binary_name, func_name, path);
+ cache_path = create_sb2cache_path(mapping_mode, binary_name,
+ func_name, path);
dcopy = strdup(cache_path);
@@ -417,11 +435,9 @@ static int sb_realpath(lua_State *l)
path = strdup(lua_tostring(l, 1));
- //printf("sb_realpath: [%s]\n", path);
-
/* Here we rely on glibc specific feature of passing NULL as the second
- * parameter to realpath, thus forcing it to allocate a sufficient buffer.
- * This might not work at all on other systems.
+ * parameter to realpath, thus forcing it to allocate a sufficient
+ * buffer. This might not work at all on other systems.
*/
resolved_path = __sb2_realpath(path, NULL);
@@ -430,8 +446,6 @@ static int sb_realpath(lua_State *l)
return 1;
}
- //printf("sb_realpath: resolved_path = [%s]\n", resolved_path);
-
lua_pushstring(l, resolved_path);
return 1;
}
@@ -461,7 +475,6 @@ static int sb_followsymlink(lua_State *l)
path = strdup(lua_tostring(l, 1));
- //printf("C thinks path is: %s\n", path);
#ifdef __x86_64__
if (syscall(__NR_lstat, path, &s) < 0) {
#else
@@ -474,10 +487,9 @@ static int sb_followsymlink(lua_State *l)
lua_pushstring(l, path);
goto getout;
}
- //printf("about to test for symlink: %i\n", s.st_mode);
+
if (S_ISLNK(s.st_mode)) {
/* we have a symlink, read it and return */
- //printf("WE HAVE A SYMLINK!!!\n");
syscall(__NR_readlink, path, link_path, PATH_MAX);
lua_pushstring(l, link_path);
@@ -485,10 +497,9 @@ static int sb_followsymlink(lua_State *l)
//printf("not a symlink! %s\n", path);
/* not a symlink, return path */
lua_pushstring(l, path);
- //printf("after pushing\n");
}
+
getout:
- //printf("about to free!\n");
free(path);
return 1;
}
@@ -497,7 +508,6 @@ getout:
* This function should ONLY look at things from rsdir
* any other path leads to loops
*/
-
static int sb_getdirlisting(lua_State *l)
{
DIR *d;
@@ -552,46 +562,42 @@ char *scratchbox_path(const char *func_name, const char *path)
if (tmp) {
strcpy(binary_name, tmp);
} else {
- strcpy(binary_name, "DUMMY");
+ strcpy(binary_name, "UNKNOWN");
}
return scratchbox_path2(binary_name, func_name, path);
}
-char *scratchbox_path2(const char *binary_name, const char *func_name, const char *path)
+char *scratchbox_path2(const char *binary_name,
+ const char *func_name,
+ const char *path)
{
char work_dir[PATH_MAX + 1];
- char *tmp = NULL, *decolon_path = NULL;
+ char *tmp = NULL, *decolon_path = NULL, *mapping_mode = NULL;
char pidlink[17]; /* /proc/2^8/exe */
-
+
+ if (!(mapping_mode = getenv("SBOX2_MAPMODE"))) {
+ mapping_mode = "default";
+ }
+
if (!path) {
WRITE_LOG("ERROR: scratchbox_path2: path == NULL: [%s][%s]\n", binary_name, func_name);
return NULL;
}
- //WRITE_LOG("in scratchbox_path2: %s %s (%s)\n", binary_name, func_name, path);
+
if (mapping_disabled || getenv("SBOX_DISABLE_MAPPING")) {
return strdup(path);
}
disable_mapping();
decolon_path = decolonize_path(path);
- //WRITE_LOG("scratchbox_path2: decolon_path: (%s)\n", decolon_path);
-#if 0
- if (strstr(decolon_path, getenv("SBOX_TARGET_ROOT"))) {
- /* short circuit a direct reference to a file inside the sbox
- * target dir */
- //DBGOUT("about to short circuit: %s\n", func_name);
- free(decolon_path);
- enable_mapping();
- return strdup(path);
- }
-#endif
-
/* first try from the cache */
#ifndef DISABLE_CACHE
tmp = NULL;
- if (rsdir && main_lua) tmp = read_sb2cache(binary_name, func_name, decolon_path);
+ if (rsdir && main_lua) tmp = read_sb2cache(mapping_mode,
+ binary_name,
+ func_name, decolon_path);
if (tmp) {
if (strcmp(tmp, decolon_path) == 0) {
@@ -625,15 +631,11 @@ char *scratchbox_path2(const char *binary_name, const char *func_name, const cha
memset(work_dir, '\0', PATH_MAX+1);
snprintf(pidlink,16,"/proc/%i/exe",sb_getpid());
-// if (syscall(__NR_readlink, pidlink, binary_name, PATH_MAX) < 0) {
-// perror("__NR_readlink() error, check that /proc is mounted!");
-// }
syscall(__NR_getcwd, work_dir, PATH_MAX);
/* redir_scripts RECURSIVE CALL BREAK */
if (strncmp(decolon_path, rsdir, strlen(rsdir)) == 0) {
- //pthread_mutex_unlock(&lua_lock);
- //DBGOUT("cutting recursive call\n");
+ pthread_mutex_unlock(&lua_lock);
enable_mapping();
return (char *)decolon_path;
}
@@ -660,23 +662,26 @@ char *scratchbox_path2(const char *binary_name, const char *func_name, const cha
}
lua_getfield(l, LUA_GLOBALSINDEX, "sbox_translate_path");
+ lua_pushstring(l, mapping_mode);
lua_pushstring(l, binary_name);
lua_pushstring(l, func_name);
lua_pushstring(l, work_dir);
lua_pushstring(l, decolon_path);
- lua_call(l, 4, 1); /* four arguments, one result */
+ lua_call(l, 5, 1); /* five arguments, one result */
+
tmp = (char *)lua_tostring(l, -1);
if (tmp) {
tmp = strdup(tmp);
}
+
lua_pop(l, 1);
pthread_mutex_unlock(&lua_lock);
#ifndef DISABLE_CACHE
- insert_sb2cache(binary_name, func_name, decolon_path, tmp);
+ insert_sb2cache(mapping_mode, binary_name, func_name, decolon_path, tmp);
#endif
- //DBGOUT("returning path: [%s]\n", tmp);
+
if (strcmp(tmp, decolon_path) == 0) {
free(decolon_path);
free(tmp);
diff --git a/redir_scripts/main.lua b/redir_scripts/main.lua
index eedeadd..6eaf66e 100644
--- a/redir_scripts/main.lua
+++ b/redir_scripts/main.lua
@@ -2,8 +2,6 @@
-- Copyright (C) 2006, 2007 Lauri Leukkunen
-- Licensed under MIT license.
---print "hello!\n"
-
tools_root = os.getenv("SBOX_TOOLS_ROOT")
if (not tools_root) then
tools_root = "/scratchbox/sarge"
@@ -30,54 +28,68 @@ if (rsdir == nil) then
rsdir = "/scratchbox/redir_scripts"
end
-chains = {}
+
+function read_mode_part(mode, part)
+ filename = rsdir .. "/preload/" .. mode .. "/" .. part
+ f, err = loadfile(filename)
+ if (f == nil) then
+ error("\nError while loading " .. filename .. ": \n" .. err .. "\n")
+ else
+ f() -- execute the loaded chunk
+ -- export_chains variable contains now the chains
+ -- from the chunk
+ for i = 1,table.maxn(export_chains) do
+ -- fill in the default values
+ if (not export_chains[i].binary) then
+ export_chains[i].binary = ".*"
+ end
+ if (not export_chains[i].rules) then
+ export_chains[i].rules = {}
+ end
+ -- loop through the rules
+ for r = 1, table.maxn(export_chains[i].rules) do
+ if (not export_chains[i].rules[r].func_name) then
+ export_chains[i].rules[r].func_name = ".*"
+ end
+ if (not export_chains[i].rules[r].path) then
+ -- this is an error, report and exit
+ os.exit(1)
+ end
+ export_chains[i].rules[r].lua_script = filename
+ if (export_chains[i].binary) then
+ export_chains[i].rules[r].binary_name = export_chains[i].binary
+ else
+ export_chains[i].rules[r].binary_name = "nil"
+ end
+ end
+ export_chains[i].lua_script = filename
+ table.insert(modes[mode].chains, export_chains[i])
+ end
+ end
+end
+
+-- modes represent the different mapping modes supported.
+-- Each mode contains its own set of chains.
+-- The mode is passed from the libsb2.so to here in the first
+-- argument to sbox_translate_path()
+modes = {}
-- sb.sb_getdirlisting is provided by lua_bindings.c
-- it returns a table listing all files in a directory
-t = sb.sb_getdirlisting(rsdir .. "/preload")
-
-if (t ~= nil) then
+mm = sb.sb_getdirlisting(rsdir .. "/preload")
+table.sort(mm);
+for m = 1, table.maxn(mm) do
+ local t = sb.sb_getdirlisting(rsdir .. "/preload/" .. mm[m])
local i = 0
local r = 0
- table.sort(t)
- -- load the individual parts ($SBOX_REDIR_SCRIPTS/preload/*.lua)
- for n = 1,table.maxn(t) do
- if (string.match(t[n], "%a*%.lua$")) then
- filename = rsdir .. "/preload/" .. t[n]
- f, err = loadfile(filename)
- if (f == nil) then
- error("\nError while loading " .. filename .. ": \n" .. err .. "\n")
- else
- f() -- execute the loaded chunk
- -- export_chains variable contains now the chains
- -- from the chunk
- for i = 1,table.maxn(export_chains) do
- -- fill in the default values
- if (not export_chains[i].binary) then
- export_chains[i].binary = ".*"
- end
- if (not export_chains[i].rules) then
- export_chains[i].rules = {}
- end
- -- loop through the rules
- for r = 1, table.maxn(export_chains[i].rules) do
- if (not export_chains[i].rules[r].func_name) then
- export_chains[i].rules[r].func_name = ".*"
- end
- if (not export_chains[i].rules[r].path) then
- -- this is an error, report and exit
- os.exit(1)
- end
- export_chains[i].rules[r].lua_script = filename
- if (export_chains[i].binary) then
- export_chains[i].rules[r].binary_name = export_chains[i].binary
- else
- export_chains[i].rules[r].binary_name = "nil"
- end
- end
- export_chains[i].lua_script = filename
- table.insert(chains, export_chains[i])
- end
+ if (mm[m] ~= "." and mm[m] ~= "..") then
+ table.sort(t)
+ modes[mm[m]] = {}
+ modes[mm[m]].chains = {}
+ -- load the individual parts ($SBOX_REDIR_SCRIPTS/preload/[modename]/*.lua)
+ for n = 1,table.maxn(t) do
+ if (string.match(t[n], "%a*%.lua$")) then
+ read_mode_part(mm[m], t[n])
end
end
end
@@ -215,17 +227,15 @@ end
-- sbox_translate_path is the function called from libsb2.so
-- preload library and the FUSE system for each path that needs
-- translating
-
-function sbox_translate_path(binary_name, func_name, work_dir, path)
+function sbox_translate_path(mapping_mode, binary_name, func_name, work_dir, path)
--sb_debug(string.format("[%s]:", binary_name))
--sb_debug(string.format("debug: [%s][%s][%s][%s]", binary_name, func_name, work_dir, path))
-
-- loop through the chains, first match is used
- for n=1,table.maxn(chains) do
- if (not chains[n].noentry
- and string.match(binary_name, chains[n].binary)) then
- return map_using_chain(chains[n], binary_name, func_name, work_dir, path)
+ for n=1,table.maxn(modes[mapping_mode].chains) do
+ if (not modes[mapping_mode].chains[n].noentry
+ and string.match(binary_name, modes[mapping_mode].chains[n].binary)) then
+ return map_using_chain(modes[mapping_mode].chains[n], binary_name, func_name, work_dir, path)
end
end
diff --git a/redir_scripts/preload/00_default.lua b/redir_scripts/preload/default/00_default.lua
index 570b85b..570b85b 100644
--- a/redir_scripts/preload/00_default.lua
+++ b/redir_scripts/preload/default/00_default.lua
diff --git a/redir_scripts/preload/10_basic_chains.lua b/redir_scripts/preload/default/10_basic_chains.lua
index 5de2f4a..5de2f4a 100644
--- a/redir_scripts/preload/10_basic_chains.lua
+++ b/redir_scripts/preload/default/10_basic_chains.lua
diff --git a/redir_scripts/preload/XX_catchall.lua b/redir_scripts/preload/default/XX_catchall.lua
index f4ba104..206317f 100644
--- a/redir_scripts/preload/XX_catchall.lua
+++ b/redir_scripts/preload/default/XX_catchall.lua
@@ -1,4 +1,4 @@
--- Copyright (C) 2007 Lauri Leukkunen
+-- Copyright (C) 2007 Lauri Leukkunen <lle@rahina.org>
-- Licensed under MIT license.
diff --git a/redir_scripts/preload/emulate/00_default.lua b/redir_scripts/preload/emulate/00_default.lua
new file mode 100644
index 0000000..5ae2aa1
--- /dev/null
+++ b/redir_scripts/preload/emulate/00_default.lua
@@ -0,0 +1,20 @@
+-- Copyright (C) 2007 Lauri Leukkunen <lle@rahina.org>
+-- Licensed under MIT license.
+
+
+mapall_chain = {
+ next_chain = nil,
+ binary = ".*",
+ rules = {
+ {path = ".*qemu.*", map_to = nil},
+ {path = "^/dev", map_to = nil},
+ {path = "^/proc", map_to = nil},
+ {path = "^/tmp", map_to = nil},
+ {path = "^/sys", map_to = nil},
+ {path = ".*", map_to = "="}
+ }
+}
+
+export_chains = {
+ mapall_chain
+}
diff --git a/utils/sb2 b/utils/sb2
index 856cfcd..4299853 100755
--- a/utils/sb2
+++ b/utils/sb2
@@ -70,6 +70,9 @@ if [ "$sb_map_verbose" == "--verbose" ]; then
sb_bash_args=$(echo $* | sed 's/^--verbose//')
fi
+# set the initial binary name for the mapping engine
+export __SB2_BINARYNAME="bash"
+
if [ -z "$sb_bash_args" ]; then
exec /bin/bash --noprofile --norc
else