summaryrefslogtreecommitdiff
path: root/luaif
diff options
context:
space:
mode:
authorLauri Aarnio <Lauri.Aarnio@iki.fi>2008-12-08 16:58:31 +0200
committerLauri Leukkunen <lle@rahina.org>2008-12-11 23:47:00 +0200
commit576ed39bde4ec3034e22aa08b61e7084a87553a5 (patch)
treeff86f2d15fe5bbedbf20f83cee442f48d77fb700 /luaif
parent52f61f715c3f53e0eb52e13400c1b979b8f26ab4 (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.c29
-rw-r--r--luaif/paths.c79
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);
}