summaryrefslogtreecommitdiff
path: root/preload
diff options
context:
space:
mode:
authorLauri Aarnio <Lauri.Aarnio@iki.fi>2009-03-04 17:16:33 +0200
committerLauri Leukkunen <lle@rahina.org>2009-03-07 16:05:39 +0200
commit575ea17d95bc50b116b0261ac81c3cbfa5fba371 (patch)
tree15d65beada4764b83a7c3b05573eb0fc2862888a /preload
parent98dfaf9468a1cc02fe7f77f2778e3d738f40d022 (diff)
Fixed mapping of relative paths.
- Relative paths are (again) mapped to relative paths whenever possible. - SB2 used to be able to map to relative paths until the "fdpathdb" was added (fdpathdb must get absolute mapping results). The previous solution for relative results was disabled in mid-january, because it was clear that some refactoring was needed to be able to use both the fdpathdb functionality and relative mapping results. - This commit now introduces a proper fix: Path mapping results are returned in a structure, where an absolute and a relative result can co-exist. - Also, the lower levels of path mapping logic (parts that are implemented in C) were re-organized and cleaned; the code should be easier to follow and more efficient now.
Diffstat (limited to 'preload')
-rw-r--r--preload/fdpathdb.c47
-rwxr-xr-xpreload/gen-interface.pl73
-rw-r--r--preload/libsb2.c83
-rw-r--r--preload/libsb2.h27
-rw-r--r--preload/sb_exec.c14
5 files changed, 123 insertions, 121 deletions
diff --git a/preload/fdpathdb.c b/preload/fdpathdb.c
index f60bf9a..bbbbc18 100644
--- a/preload/fdpathdb.c
+++ b/preload/fdpathdb.c
@@ -168,74 +168,73 @@ static void fdpathdb_register_mapped_path(
fdpathdb_mutex_unlock();
}
+static void fdpathdb_register_mapping_result(const char *realfnname,
+ int ret_fd, mapping_results_t *res, const char *pathname)
+{
+ /* "mres_result_buf" is supposed to be an absolute path,
+ * while "mres_result_path" may be relative or absolute.
+ * (the path DB can not use relative paths)
+ */
+ fdpathdb_register_mapped_path(realfnname, ret_fd,
+ res->mres_result_buf, pathname);
+}
+
/* Wrappers' postprocessors: these register paths to this DB */
extern void __open_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
const char *pathname, int flags, int mode)
{
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
extern void __open64_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
const char *pathname, int flags, int mode)
{
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
extern void open_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
const char *pathname, int flags, int mode)
{
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
extern void open64_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
const char *pathname, int flags, int mode)
{
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
extern void openat_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
int dirfd, const char *pathname, int flags, int mode)
{
(void)dirfd;
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
extern void openat64_postprocess_pathname(
- const char *realfnname, int ret_fd, const char *mapped__pathname,
+ const char *realfnname, int ret_fd, mapping_results_t *res,
int dirfd, const char *pathname, int flags, int mode)
{
(void)dirfd;
- (void)pathname;
(void)flags;
(void)mode;
- fdpathdb_register_mapped_path(realfnname, ret_fd,
- mapped__pathname, pathname);
+ fdpathdb_register_mapping_result(realfnname, ret_fd, res, pathname);
}
void dup_postprocess_(const char *realfnname, int ret, int fd)
diff --git a/preload/gen-interface.pl b/preload/gen-interface.pl
index 0c417d6..58e109f 100755
--- a/preload/gen-interface.pl
+++ b/preload/gen-interface.pl
@@ -35,9 +35,9 @@
#
# Following modifiers are available for "WRAP" and "GATE":
# - "map(varname)" will map function's parameter "varname" using
-# the SBOX_MAP_PATH macro
+# the sbox_map_path() function
# - "map_at(fdname,varname)" will map function's parameter "varname" using
-# the SBOX_MAP_PATH_AT macro
+# the sbox_map_path_at() function
# - "hardcode_param(N,name)" will hardcode name of the Nth parameter
# to "name" (this is typically needed only if the function definition uses
# macros to build the parameter list, instead of specifying names of
@@ -371,20 +371,6 @@ sub minimal_function_declarator_parser {
# End of the minimal C declarator parser.
#============================================
-sub find_type_of_parameter {
- my $fn = shift;
- my $param_name = shift;
- my $r_param_names = $fn->{'parameter_names'};
-
- my $i;
- for ($i = 0; $i < @{$r_param_names}; $i++) {
- if ($r_param_names->[$i] eq $param_name) {
- return($fn->{'parameter_types'}->[$i]);
- }
- }
- return(undef);
-}
-
sub create_code_for_va_list_get_mode {
my $condition = shift;
my $last_named_var = shift;
@@ -418,8 +404,14 @@ sub process_readonly_check_modifier {
my $return_value = shift;
my $error_code = shift;
- my $new_name = "mapped__".$param_to_be_mapped;
- my $ro_flag = $param_to_be_mapped."_is_readonly";
+ my $new_name = "res_mapped__".$param_to_be_mapped.".mres_result_path";
+ my $ro_flag = "res_mapped__".$param_to_be_mapped.".mres_readonly";
+
+ if (!defined($mods->{'mapping_results_by_orig_name'}->{$param_to_be_mapped})) {
+ printf "ERROR: mapping_results_by_orig_name not found for '%s'\n",
+ $param_to_be_mapped;
+ $num_errors++;
+ }
if (defined($extra_check)) {
$extra_check = " && ($extra_check)";
@@ -473,6 +465,7 @@ sub process_wrap_or_gate_modifiers {
'va_list_handler_code' => "",
'va_list_end_code' => "",
'mapped_params_by_orig_name' => {},
+ 'mapping_results_by_orig_name' => {},
'dont_resolve_final_symlink' => 0,
'postprocess_vars' => [],
@@ -503,19 +496,20 @@ sub process_wrap_or_gate_modifiers {
my $param_to_be_mapped = $1;
my $new_name = "mapped__".$param_to_be_mapped;
- my $ro_flag = $param_to_be_mapped."_is_readonly";
my $no_symlink_resolve = $mods->{'dont_resolve_final_symlink'};
- $mods->{'mapped_params_by_orig_name'}->{$param_to_be_mapped} = $new_name;
+ $mods->{'mapped_params_by_orig_name'}->{$param_to_be_mapped} = "res_$new_name.mres_result_path";
+ $mods->{'mapping_results_by_orig_name'}->{$param_to_be_mapped} = "res_$new_name";
$mods->{'path_mapping_vars'} .=
- "\tchar *$new_name = NULL;\n".
- "\tint $ro_flag = 0;\n";
+ "\tmapping_results_t res_$new_name;\n";
$mods->{'path_mapping_code'} .=
- "\tSBOX_MAP_PATH($param_to_be_mapped, ".
- "$new_name, &$ro_flag, ".
- "$no_symlink_resolve);\n";
+ "\tclear_mapping_results_struct(&res_$new_name);\n".
+ "\tsbox_map_path(__func__, ".
+ "$param_to_be_mapped, ".
+ "$no_symlink_resolve, ".
+ "&res_$new_name);\n";
$mods->{'free_path_mapping_vars_code'} .=
- "\tif($new_name) free($new_name);\n";
+ "\tfree_mapping_results(&res_$new_name);\n";
# Make a "..._nomap" version, because the main
# wrapper has mappings.
@@ -543,16 +537,19 @@ sub process_wrap_or_gate_modifiers {
my $ro_flag = $param_to_be_mapped."_is_readonly";
my $no_symlink_resolve = $mods->{'dont_resolve_final_symlink'};
- $mods->{'mapped_params_by_orig_name'}->{$param_to_be_mapped} = $new_name;
+ $mods->{'mapped_params_by_orig_name'}->{$param_to_be_mapped} = "res_$new_name.mres_result_path";
+ $mods->{'mapping_results_by_orig_name'}->{$param_to_be_mapped} = "res_$new_name";
$mods->{'path_mapping_vars'} .=
- "\tchar *$new_name = NULL;\n".
- "\tint $ro_flag = 0;\n";
+ "\tmapping_results_t res_$new_name;\n";
$mods->{'path_mapping_code'} .=
- "\tSBOX_MAP_PATH_AT($fd_param, ".
- "$param_to_be_mapped, $new_name, &$ro_flag, ".
- "$no_symlink_resolve);\n";
+ "\tclear_mapping_results_struct(&res_$new_name);\n".
+ "\tsbox_map_path_at(__func__, ".
+ "$fd_param, ".
+ "$param_to_be_mapped, ".
+ "$no_symlink_resolve, ".
+ "&res_$new_name);\n";
$mods->{'free_path_mapping_vars_code'} .=
- "\tif($new_name) free($new_name);\n";
+ "\tfree_mapping_results(&res_$new_name);\n";
# Make a "..._nomap" version, because the main
# wrapper has mappings.
@@ -689,18 +686,18 @@ sub create_postprocessors {
");\n";
} else {
# has mapped parameter
- my $mapped_param = $mods->{'mapped_params_by_orig_name'}->{$ppvar};
- my $type_of_param = find_type_of_parameter($fn,$ppvar);
+ my $mapping_results = $mods->{'mapping_results_by_orig_name'}->{$ppvar};
+
$postprocessor_calls .= "$pp_fn(__func__, ".
$return_value_param_in_call.
- "$mapped_param, ".
+ "&$mapping_results, ".
# add orig (unmapped) parameters
join(", ", @{$mods->{'parameter_names'}}).
"); ";
$postprocessor_prototypes .= "extern void ".
"$pp_fn(const char *realfnname, ".
$return_value_param_in_prototype.
- "$type_of_param $mapped_param, ".
+ "mapping_results_t *res, ".
# orig (unmapped) parameters
join(", ", @{$mods->{'parameter_types'}}).
");\n";
@@ -848,6 +845,8 @@ my $export_h_buffer =
#include <sys/xattr.h>
#endif
+#include \"mapping.h\"
+
";
# Handle "WRAP" and "GATE" commands.
diff --git a/preload/libsb2.c b/preload/libsb2.c
index 62c6b49..16d47c8 100644
--- a/preload/libsb2.c
+++ b/preload/libsb2.c
@@ -428,7 +428,6 @@ FTS * fts_open_gate(FTS * (*real_fts_open_ptr)(char * const *path_argv,
int options,
int (*compar)(const FTSENT **,const FTSENT **))
{
- SBOX_MAP_PROLOGUE();
char *path;
char * const *p;
char **new_path_argv;
@@ -441,12 +440,23 @@ FTS * fts_open_gate(FTS * (*real_fts_open_ptr)(char * const *path_argv,
}
for (n=0, p=path_argv, np=new_path_argv; *p; n++, p++, np++) {
+ mapping_results_t res;
+
+ clear_mapping_results_struct(&res);
path = *p;
- sbox_path = scratchbox_path(realfnname, path, NULL/*RO-flag*/,
- 0/*dont_resolve_final_symlink*/);
- *np = sbox_path;
+ sbox_map_path(realfnname, path,
+ 0/*dont_resolve_final_symlink*/, &res);
+ if (res.mres_result_path) {
+ /* Mapped OK */
+ *np = strdup(res.mres_result_path);
+ } else {
+ *np = strdup("");
+ }
+ free_mapping_results(&res);
}
+ /* FIXME: this system causes memory leaks */
+
return (*real_fts_open_ptr)(new_path_argv, options, compar);
}
#endif
@@ -455,7 +465,7 @@ char * get_current_dir_name_gate(
char * (*real_get_current_dir_name_ptr)(void),
const char *realfnname)
{
- SBOX_MAP_PROLOGUE();
+ char *sbox_path = NULL;
char *cwd;
if ((cwd = (*real_get_current_dir_name_ptr)()) == NULL) {
@@ -520,7 +530,7 @@ char * getwd_gate(
const char *realfnname,
char *buf)
{
- SBOX_MAP_PROLOGUE();
+ char *sbox_path = NULL;
char *cwd;
if ((cwd = (*real_getwd_ptr)(buf)) == NULL) {
@@ -552,7 +562,7 @@ char *realpath_gate(
const char *name, /* name, already mapped */
char *resolved)
{
- SBOX_MAP_PROLOGUE();
+ char *sbox_path = NULL;
char *rp;
if ((rp = (*real_realpath_ptr)(name,resolved)) == NULL) {
@@ -594,7 +604,7 @@ static char *check_and_prepare_glob_pattern(
* log the mapped pattern (NOTICE level) if it was mapped
*/
if (*pattern == '/') { /* if absolute path in pattern.. */
- mapped__pattern = scratchbox_path(realfnname, pattern,
+ mapped__pattern = sbox_map_path(realfnname, pattern,
NULL/*RO-flag*/, 0/*dont_resolve_final_symlink*/);
if (!strcmp(mapped__pattern, pattern)) {
/* no change */
@@ -761,24 +771,32 @@ static void map_sockaddr_un(
struct sockaddr_un *orig_serv_addr_un,
struct sockaddr_un *mapped_serv_addr_un)
{
- int pathname_is_readonly = 0;
- char *mapped_addr = NULL;
+ mapping_results_t res;
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: checking AF_UNIX addr '%s'",
realfnname, orig_serv_addr_un->sun_path);
- SBOX_MAP_PATH(orig_serv_addr_un->sun_path, mapped_addr,
- &pathname_is_readonly, 0/*dont_resolve_final_symlink*/);
- /* FIXME: implement if(pathname_is_readonly!=0)... */
- *mapped_serv_addr_un = *orig_serv_addr_un;
- if (sizeof(mapped_serv_addr_un->sun_path) <= strlen(mapped_addr)) {
+ clear_mapping_results_struct(&res);
+ /* FIXME: implement if(pathname_is_readonly!=0)... */
+ sbox_map_path(realfnname, orig_serv_addr_un->sun_path,
+ 0/*dont_resolve_final_symlink*/, &res);
+ if (res.mres_result_path == NULL) {
SB_LOG(SB_LOGLEVEL_ERROR,
- "%s: Mapped AF_UNIX address (%s) is too long",
- realfnname, mapped_addr);
+ "%s: Failed to map AF_UNIX address '%s'",
+ realfnname, orig_serv_addr_un->sun_path);
} else {
- strcpy(mapped_serv_addr_un->sun_path, mapped_addr);
+ *mapped_serv_addr_un = *orig_serv_addr_un;
+ if (sizeof(mapped_serv_addr_un->sun_path) <=
+ strlen(res.mres_result_path)) {
+ SB_LOG(SB_LOGLEVEL_ERROR,
+ "%s: Mapped AF_UNIX address (%s) is too long",
+ realfnname, res.mres_result_path);
+ } else {
+ strcpy(mapped_serv_addr_un->sun_path,
+ res.mres_result_path);
+ }
}
- if (mapped_addr) free(mapped_addr);
+ free_mapping_results(&res);
}
int bind_gate(
@@ -856,15 +874,22 @@ char *sb2show__map_path2__(const char *binary_name, const char *mapping_mode,
const char *fn_name, const char *pathname, int *readonly)
{
char *mapped__pathname = NULL;
+ mapping_results_t mapping_result;
(void)mapping_mode; /* mapping_mode is not used anymore. */
if (!sb2_global_vars_initialized__) sb2_initialize_global_variables();
+ clear_mapping_results_struct(&mapping_result);
if (pathname != NULL) {
- mapped__pathname = scratchbox_path3(binary_name, fn_name,
- pathname, readonly, 0/*dont_resolve_final_symlink*/);
+ sbox_map_path_for_sb2show(binary_name, fn_name,
+ pathname, &mapping_result);
+ if (mapping_result.mres_result_path)
+ mapped__pathname =
+ strdup(mapping_result.mres_result_path);
+ if (readonly) *readonly = mapping_result.mres_readonly;
}
+ free_mapping_results(&mapping_result);
SB_LOG(SB_LOGLEVEL_DEBUG, "%s '%s'", __func__, pathname);
return(mapped__pathname);
}
@@ -965,31 +990,31 @@ static void postprocess_tempname_template(const char *realfnname,
}
void mkstemp_postprocess_template(const char *realfnname,
- int ret, char *mapped__template, char *template)
+ int ret, mapping_results_t *res, char *template)
{
(void)ret;
- postprocess_tempname_template(realfnname, mapped__template, template);
+ postprocess_tempname_template(realfnname, res->mres_result_path, template);
}
void mkstemp64_postprocess_template(const char *realfnname,
- int ret, char *mapped__template, char *template)
+ int ret, mapping_results_t *res, char *template)
{
(void)ret;
- postprocess_tempname_template(realfnname, mapped__template, template);
+ postprocess_tempname_template(realfnname, res->mres_result_path, template);
}
void mkdtemp_postprocess_template(const char *realfnname,
- char *ret, char *mapped__template, char *template)
+ char *ret, mapping_results_t *res, char *template)
{
(void)ret;
- postprocess_tempname_template(realfnname, mapped__template, template);
+ postprocess_tempname_template(realfnname, res->mres_result_path, template);
}
void mktemp_postprocess_template(const char *realfnname,
- char *ret, char *mapped__template, char *template)
+ char *ret, mapping_results_t *res, char *template)
{
(void)ret;
- postprocess_tempname_template(realfnname, mapped__template, template);
+ postprocess_tempname_template(realfnname, res->mres_result_path, template);
}
/* the real tmpnam() can not be used at all, because the generated name must
diff --git a/preload/libsb2.h b/preload/libsb2.h
index f4a6fe2..0360f42 100644
--- a/preload/libsb2.h
+++ b/preload/libsb2.h
@@ -95,33 +95,6 @@
* if ( amount /../ > amount /other/ ) ) remove extra /../
*/
-#define SBOX_MAP_PROLOGUE() \
- char *sbox_path = NULL;
-
-#define SBOX_MAP_AT_PROLOGUE() \
- char *sbox_path = NULL;
-
-#define SBOX_MAP_PATH_NARROW(path, sbox_path, readonly_flag_addr) \
-{ \
- if ((path) != NULL && *((char *)(path)) != '\0') { \
- sbox_path = scratchbox_path(__FUNCTION__, path, readonly_flag_addr); \
- } \
-}
-
-#define SBOX_MAP_PATH(path, sbox_path, readonly_flag_addr, no_symlink_resolve) \
-{ \
- if ((path) != NULL) { \
- sbox_path = scratchbox_path(__FUNCTION__, path, readonly_flag_addr, no_symlink_resolve); \
- } \
-}
-
-#define SBOX_MAP_PATH_AT(dirfd, path, sbox_path, readonly_flag_addr, no_symlink_resolve) \
-{ \
- if ((path) != NULL) { \
- sbox_path = scratchbox_path_at(__FUNCTION__, dirfd, path, \
- readonly_flag_addr, no_symlink_resolve); \
- } \
-}
extern void *sbox_find_next_symbol(int log_enabled, const char *functname);
diff --git a/preload/sb_exec.c b/preload/sb_exec.c
index 40ef414..d96e804 100644
--- a/preload/sb_exec.c
+++ b/preload/sb_exec.c
@@ -960,7 +960,7 @@ static int prepare_exec(const char *exec_fn_name,
"do_exec(): mapping disabled, my_file = %s", my_file);
mapped_file = strdup(my_file);
- /* we won't call scratchbox_path_for_exec() because mapping
+ /* we won't call sbox_map_path_for_exec() because mapping
* is disabled; instead we must push a string to Lua's stack
* which explains the situation to the Lua code
*/
@@ -970,14 +970,20 @@ static int prepare_exec(const char *exec_fn_name,
/* now we have to do path mapping for my_file to find exactly
* what is the path we're supposed to deal with
*/
+ mapping_results_t mapping_result;
+
+ clear_mapping_results_struct(&mapping_result);
+ sbox_map_path_for_exec("do_exec", my_file, &mapping_result);
+ if (mapping_result.mres_result_buf) {
+ mapped_file = strdup(mapping_result.mres_result_buf);
+ }
+ free_mapping_results(&mapping_result);
- mapped_file = scratchbox_path_for_exec("do_exec", my_file,
- NULL/*RO-flag addr.*/, 0/*dont_resolve_final_symlink*/);
SB_LOG(SB_LOGLEVEL_DEBUG,
"do_exec(): my_file = %s, mapped_file = %s",
my_file, mapped_file);
- /* Note: the Lua stack should now have rule and policy objects */
+ /* Note: the Lua stack now contains rule and policy objects */
}
/*