diff options
author | Lauri Leukkunen <lle@rahina.org> | 2007-04-12 23:47:52 +0300 |
---|---|---|
committer | Lauri Leukkunen <lle@rahina.org> | 2007-04-12 23:47:52 +0300 |
commit | d3c1482adcb3a3dd3cba84b2a2fee425fc18213d (patch) | |
tree | 942d802a2f1eddb885a8f34a4bfd7e79bc1acbb8 | |
parent | 9c0fc6d3a7712e1414e9664964edd9f40450e2b4 (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-- | Makefile | 5 | ||||
-rw-r--r-- | mapping/emumode.c | 16 | ||||
-rw-r--r-- | mapping/mapping.c | 101 | ||||
-rw-r--r-- | redir_scripts/main.lua | 114 | ||||
-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.lua | 20 | ||||
-rwxr-xr-x | utils/sb2 | 3 |
9 files changed, 143 insertions, 118 deletions
@@ -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 +} @@ -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 |