diff options
-rw-r--r-- | lua_scripts/argvenvp.lua | 69 | ||||
-rw-r--r-- | preload/sb_exec.c | 65 | ||||
-rwxr-xr-x | utils/sb2 | 37 |
3 files changed, 154 insertions, 17 deletions
diff --git a/lua_scripts/argvenvp.lua b/lua_scripts/argvenvp.lua index adcb63e..b2f9818 100644 --- a/lua_scripts/argvenvp.lua +++ b/lua_scripts/argvenvp.lua @@ -202,6 +202,66 @@ function sb_execve_postprocess_native_executable(rule, exec_policy, return 1, mapped_file, filename, #argv, argv, #envp, envp end +if string.match(sbox_cputransparency_method, "qemu") then + cputransparency_method_is_qemu = true +end + +function sb_execve_postprocess_cpu_transparency_executable(rule, exec_policy, + exec_type, mapped_file, filename, argv, envp) + sb.log("debug", "postprocessing cpu_transparency for " .. filename) + + if cputransparency_method_is_qemu then + local new_envp = {} + local new_argv = {} + local new_filename = sbox_cputransparency_method + + new_argv[1] = sbox_cputransparency_method + -- drop LD_PRELOAD env.var. + new_argv[2] = "-drop-ld-preload" + -- target runtime linker comes from / + new_argv[3] = "-L" + new_argv[4] = "/" + + if conf_cputransparency_has_argv0_flag then + -- set target argv[0] + new_argv[5] = "-0" + new_argv[6] = argv[1] + end + + if conf_cputransparency_qemu_has_env_control_flags then + for i = 1, #envp do + -- drop LD_TRACE_ from target environment + if not string.match(envp[i], "^LD_TRACE_.*") then + table.insert(new_envp, envp[i]) + else + -- .. and move it to qemu command line + table.insert(new_argv, "-E") + table.insert(new_argv, envp[i]) + end + end + end + + -- unmapped file is exec'd + table.insert(new_argv, filename) + -- + -- Append arguments for target process (skip argv[0] + -- as this is done using -0 switch). + -- + for i = 2, #argv do + table.insert(new_argv, argv[i]) + end + + -- environment&args were changed + return 0, new_filename, filename, #new_argv, new_argv, + #new_envp, new_envp + -- FIXME: here we should have "elseif cputransparency_method_is_sbrsh".. + end + + -- no changes + return 1, mapped_file, filename, #argv, argv, #envp, envp +end + + -- This is called from C: function sb_execve_postprocess(rule, exec_policy, exec_type, mapped_file, filename, binaryname, argv, envp) @@ -267,17 +327,22 @@ function sb_execve_postprocess(rule, exec_policy, exec_type, exec_policy.name)) end + sb.log("debug", string.format("sb_execve_postprocess:type=%s", + exec_type)) + -- End of generic part. Rest of postprocessing depends on type of -- the executable. if (exec_type == "native") then - sb.log("debug", string.format("sb_execve_postprocess:type=%s", exec_type)) return sb_execve_postprocess_native_executable(rule, exec_policy, exec_type, mapped_file, filename, argv, envp) + elseif (exec_type == "cpu_transparency") then + return sb_execve_postprocess_cpu_transparency_executable(rule, + exec_policy, exec_type, mapped_file, + filename, argv, envp) else -- all other exec_types: allow exec with orig.args - sb.log("debug", string.format("sb_execve_postprocess:type=%s", exec_type)) return 1, mapped_file, filename, #argv, argv, #envp, envp end end diff --git a/preload/sb_exec.c b/preload/sb_exec.c index 2fe88cf..7256130 100644 --- a/preload/sb_exec.c +++ b/preload/sb_exec.c @@ -68,8 +68,10 @@ * 4c. Target binaries (when target architecture != host architecture) * are started in "cpu transparency mode", which typically means * that either "qemu" or "sbrsh" is used to execute them. - * [FIXME: This step should also call the same exec postprocesing code - * as alternative 4b does, but that is not the case currently] + * This is partially handled by exec postprocessing (like 4b. above), + * but "sbrsh" method is still handled here. + * [FIXME: This step should also call the exec postprocesing code + * for "sbrsh", but that haven't been implemented yet] * * 5. When all decisions and all possible conversions have been made, * sb_next_execve() will be called. It transfers control to the real @@ -243,27 +245,25 @@ static int run_sbrsh(const char *sbrsh_bin, char *const *sbrsh_args, const char *target_root, const char *orig_file, char *const *argv, char *const *envp); +static char *cputransp_method = NULL; + +static enum { + CPUTRANSP_UNKNOWN = 0, + CPUTRANSP_QEMU, + CPUTRANSP_SBRSH, +} cputransp_type = CPUTRANSP_UNKNOWN; + /* file is mangled, unmapped_file is not */ static int run_cputransparency(const char *file, const char *unmapped_file, char *const *argv, char *const *envp) { - static char *cputransp_method = NULL; static char *target_root = NULL; char *cputransp_bin; char **cputransp_tokens, **cputransp_args, **p; char *basec, *bname; int token_count, i; - if (!cputransp_method) { - cputransp_method = sb2__read_string_variable_from_lua__( - "sbox_cputransparency_method"); - } - - if (!cputransp_method) { - fprintf(stderr, "sbox_cputransparency_method not set, " - "unable to execute the target binary\n"); - return -1; - } + if (!cputransp_method) return -1; cputransp_tokens = split_to_tokens(cputransp_method); token_count = elem_count(cputransp_tokens); @@ -915,6 +915,7 @@ static int strvec_contains(char *const *strvec, const char *id) return(0); } + int do_exec(const char *exec_fn_name, const char *orig_file, char *const *orig_argv, char *const *orig_envp) { @@ -1022,8 +1023,42 @@ int do_exec(const char *exec_fn_name, const char *orig_file, SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/target %s", mapped_file); - return run_cputransparency(mapped_file, *my_file, - *my_argv, *my_envp); + if (!cputransp_method) { + cputransp_method = sb2__read_string_variable_from_lua__( + "sbox_cputransparency_method"); + if (strstr(cputransp_method, "qemu")) { + cputransp_type = CPUTRANSP_QEMU; + } else if (strstr(cputransp_method, "sbrsh")) { + cputransp_type = CPUTRANSP_SBRSH; + } else { + cputransp_type = CPUTRANSP_UNKNOWN; + } + } + + if (!cputransp_method) { + fprintf(stderr, "sbox_cputransparency_method not set, " + "unable to execute the target binary\n"); + errno = EINVAL; + return -1; + } + + if (cputransp_type == CPUTRANSP_SBRSH) { + /* FIXME: to be converted to use + * exec postprocesing + */ + return run_cputransparency(mapped_file, + *my_file, *my_argv, *my_envp); + } + + postprocess_result = sb_execve_postprocess( + "cpu_transparency", &mapped_file, my_file, + binaryname, my_argv, my_envp); + if (postprocess_result < 0) { + errno = EINVAL; + return (-1); + } + + return sb_next_execve(mapped_file, *my_argv, *my_envp); case BIN_INVALID: /* = can't be executed, no X permission */ /* don't even try to exec, errno has been set.*/ @@ -303,6 +303,30 @@ function write_ld_library_path_replacement_to_exec_config() echo " \"\"" >>$SBOX_SESSION_DIR/exec_config.lua } +# Test if qemu has "-0 argv0" and "-E envvar=value" flags +function check_qemu_features() +{ + qemu_path=$1 + + test_output=`$qemu_path -h | grep '^-0'` + if [ -n "$test_output" ] + then + # -0 is suported + conf_cputransparency_has_argv0_flag="true" + else + conf_cputransparency_has_argv0_flag="false" + fi + + test_output=`$qemu_path -h | grep '^-E'` + if [ -n "$test_output" ] + then + # -E is suported + conf_cputransparency_qemu_has_env_control_flags="true" + else + conf_cputransparency_qemu_has_env_control_flags="false" + fi +} + # Test if the "--argv0" flag is supported by the ld.so function check_ld_so_argv0_feature() { @@ -440,6 +464,9 @@ END fi # 2. Exec settings for rootstrap + conf_cputransparency_has_argv0_flag="false" + conf_cputransparency_qemu_has_env_control_flags="false" + if [ "$SBOX_CPUTRANSPARENCY_METHOD" == "" ]; then # CPU transparency method has not been set: # host CPU == target CPU @@ -461,7 +488,17 @@ conf_target_sbox_dir = "" conf_target_ld_so = nil conf_target_ld_so_supports_argv0 = false END + + case "$SBOX_CPUTRANSPARENCY_METHOD" in + *qemu*) check_qemu_features $SBOX_CPUTRANSPARENCY_METHOD + ;; + esac fi + + cat <<END >>$SBOX_SESSION_DIR/exec_config.lua +conf_cputransparency_has_argv0_flag=$conf_cputransparency_has_argv0_flag +conf_cputransparency_qemu_has_env_control_flags=$conf_cputransparency_qemu_has_env_control_flags +END } my_path=$_ |