diff options
author | Lauri Aarnio <Lauri.Aarnio@iki.fi> | 2008-12-08 16:58:31 +0200 |
---|---|---|
committer | Lauri Leukkunen <lle@rahina.org> | 2008-12-11 23:47:00 +0200 |
commit | 576ed39bde4ec3034e22aa08b61e7084a87553a5 (patch) | |
tree | ff86f2d15fe5bbedbf20f83cee442f48d77fb700 /luaif | |
parent | 52f61f715c3f53e0eb52e13400c1b979b8f26ab4 (diff) |
Fixed /proc/self/exe (and /proc/<MY_PID>/exe)
- Implemented a special mapping function for /proc, to be
able to map the symlink at /proc/self/exe.
- This can be described as a countermeasure to side-effects of
mapping exec parameters: /proc/self/exe (as well as
/proc/<MY_PID>/exe, which is the same thing) need special care
if the binary was started by anything else than direct exec.
Examples:
a) if CPU transparency is used, the real /proc/self/exe points
to e.g. Qemu. Now SB2 can make it look like the link points
to the binary which is running under qemu.
b) if "ld.so-start" was used, the real /proc/self/exe points to
ld.so and not to the binary itself. Again, SB2 maps that
to a symlink which points to the correct binary.
Other related things:
- all mapping modes use this feature now
- Lua <=> C interface version had to be incremented
- Lua mapping code <=> mapping rules version had to be incremented
Diffstat (limited to 'luaif')
-rw-r--r-- | luaif/luaif.c | 29 | ||||
-rw-r--r-- | luaif/paths.c | 79 |
2 files changed, 87 insertions, 21 deletions
diff --git a/luaif/luaif.c b/luaif/luaif.c index 1f7ab38..ba07663 100644 --- a/luaif/luaif.c +++ b/luaif/luaif.c @@ -690,6 +690,34 @@ static int lua_sb_test_path_match(lua_State *l) return 1; } +/* "sb.procfs_mapping_request", to be called from lua code */ +static int lua_sb_procfs_mapping_request(lua_State *l) +{ + int n; + char *path; + char *resolved_path; + + n = lua_gettop(l); + if (n != 1) { + lua_pushstring(l, NULL); + return 1; + } + + path = strdup(lua_tostring(l, 1)); + + resolved_path = procfs_mapping_request(path); + + if (resolved_path) { + /* mapped to somewhere else */ + lua_pushstring(l, resolved_path); + free(resolved_path); + } else { + /* no need to map this path */ + lua_pushnil(l); + } + free(path); + return 1; +} /* mappings from c to lua */ static const luaL_reg reg[] = @@ -711,6 +739,7 @@ static const luaL_reg reg[] = {"get_session_perm", lua_sb_get_session_perm}, {"isprefix", lua_sb_isprefix}, {"test_path_match", lua_sb_test_path_match}, + {"procfs_mapping_request", lua_sb_procfs_mapping_request}, {NULL, NULL} }; diff --git a/luaif/paths.c b/luaif/paths.c index 5e36632..3fd069d 100644 --- a/luaif/paths.c +++ b/luaif/paths.c @@ -497,10 +497,12 @@ static int call_lua_function_sbox_get_mapping_requirements( const char *binary_name, const char *func_name, const char *full_path_for_rule_selection, - int *min_path_lenp) + int *min_path_lenp, + int *call_translate_for_all_p) { int rule_found; int min_path_len; + int call_translate_for_all; SB_LOG(SB_LOGLEVEL_NOISE, "calling sbox_get_mapping_requirements for %s(%s)", @@ -514,21 +516,26 @@ static int call_lua_function_sbox_get_mapping_requirements( lua_pushstring(luaif->lua, binary_name); lua_pushstring(luaif->lua, func_name); lua_pushstring(luaif->lua, full_path_for_rule_selection); - /* 3 arguments, returns (rule, rule_found_flag, min_path_len) */ - lua_call(luaif->lua, 3, 3); + /* 3 arguments, returns 4: (rule, rule_found_flag, + * min_path_len, call_translate_for_all) */ + lua_call(luaif->lua, 3, 4); - rule_found = lua_toboolean(luaif->lua, -2); - min_path_len = lua_tointeger(luaif->lua, -1); + rule_found = lua_toboolean(luaif->lua, -3); + min_path_len = lua_tointeger(luaif->lua, -2); + call_translate_for_all = lua_toboolean(luaif->lua, -1); if (min_path_lenp) *min_path_lenp = min_path_len; + if (call_translate_for_all_p) + *call_translate_for_all_p = call_translate_for_all; - /* remove "flag" and "min_path_len"; leave "rule" to the stack */ - lua_pop(luaif->lua, 2); + /* remove last 3 values; leave "rule" to the stack */ + lua_pop(luaif->lua, 3); - SB_LOG(SB_LOGLEVEL_DEBUG, "sbox_get_mapping_requirements -> %d,%d", - rule_found, min_path_len); + SB_LOG(SB_LOGLEVEL_DEBUG, "sbox_get_mapping_requirements -> %d,%d,%d", + rule_found, min_path_len, call_translate_for_all); SB_LOG(SB_LOGLEVEL_NOISE, - "call_lua_function_sbox_get_mapping_requirements: at exit, gettop=%d", + "call_lua_function_sbox_get_mapping_requirements:" + " at exit, gettop=%d", lua_gettop(luaif->lua)); return(rule_found); } @@ -609,6 +616,7 @@ static char *sb_path_resolution( struct path_entry_list prefix_path_list; int ro_tmp; char *path_copy; + int call_translate_for_all = 0; if (nest_count > 16) { SB_LOG(SB_LOGLEVEL_ERROR, @@ -646,7 +654,7 @@ static char *sb_path_resolution( if (call_lua_function_sbox_get_mapping_requirements( luaif, binary_name, func_name, abs_path, - &min_path_len_to_check)) { + &min_path_len_to_check, &call_translate_for_all)) { /* has requirements: * skip over path components that we are not supposed to check, * because otherwise rule recognition & execution could fail. @@ -839,18 +847,47 @@ static char *sb_path_resolution( } work = work->pe_next; if (work) { - char *next_dir = NULL; + if (call_translate_for_all) { + /* call_translate_for_all is set when + * path resolution must call + * sbox_translate_path() for each component; + * this happens when a "custom_map_funct" has + * been set. "custom_map_funct" may use any + * kind of strategy to decide when mapping + * needs to be done, for example, the /proc + * mapping function looks at the suffix, and + * not at the prefix... + */ + if (prefix_mapping_result) { + free(prefix_mapping_result); + } + prefix_mapping_result = + call_lua_function_sbox_translate_path( + SB_LOGLEVEL_NOISE, + luaif, binary_name, + "PATH_RESOLUTION/2", + work->pe_full_path, &ro_tmp); + drop_policy_from_lua_stack(luaif); + } else { + /* "standard mapping", based on prefix or + * exact match. Ok to skip sbox_translate_path() + * because here it would just add the component + * to end of the path; instead we'll do that + * here. This is a performance optimization. + */ + char *next_dir = NULL; - if (asprintf(&next_dir, "%s/%s", - prefix_mapping_result, - work->pe_last_component_name) < 0) { - SB_LOG(SB_LOGLEVEL_ERROR, - "asprintf failed"); - } - if (prefix_mapping_result) { - free(prefix_mapping_result); + if (asprintf(&next_dir, "%s/%s", + prefix_mapping_result, + work->pe_last_component_name) < 0) { + SB_LOG(SB_LOGLEVEL_ERROR, + "asprintf failed"); + } + if (prefix_mapping_result) { + free(prefix_mapping_result); + } + prefix_mapping_result = next_dir; } - prefix_mapping_result = next_dir; } else { free(prefix_mapping_result); } |