Пример #1
0
void	free_mapping_results(mapping_results_t *res)
{
	if (res->mres_result_buf) free(res->mres_result_buf);
	if (res->mres_result_path_was_allocated && res->mres_result_path)
		free(res->mres_result_path);
	if (res->mres_virtual_cwd) free(res->mres_virtual_cwd);
	if (res->mres_allocated_exec_policy_name) free(res->mres_allocated_exec_policy_name);
	/* res->mres_error_text is a constant string, and not freed, ever */
#if 1
	/* res->mres_fallback_to_lua_mapping_engine is a constant string, and not freed, ever */
#endif
	clear_mapping_results_struct(res);
}
Пример #2
0
/* FIXME: why there was #if !defined(HAVE___OPENDIR2) around fts_open() ???? */
FTS * fts_open_gate(
	int *result_errno_ptr,
	FTS * (*real_fts_open_ptr)(char * const *path_argv,
		int options, int (*compar)(const FTSENT **,const FTSENT **)),
	const char *realfnname,
	char * const *path_argv,
	int options,
	int (*compar)(const FTSENT **,const FTSENT **))
{
	char *path;
	char * const *p;
	char **new_path_argv;
	char **np;
	int n;
	FTS *result;

	for (n=0, p=path_argv; *p; n++, p++);
	if ((new_path_argv = calloc(n+1, (sizeof(char *)))) == NULL) {
		return NULL;
	}

	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_map_path(realfnname, path,
			0/*flags*/, &res,
			SB2_INTERFACE_CLASS_FTSOPEN);
		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 */

	errno = *result_errno_ptr; /* restore to orig.value */
	result = (*real_fts_open_ptr)(new_path_argv, options, compar);
	*result_errno_ptr = errno;
	return(result);
}
Пример #3
0
char *bindtextdomain_gate(int *result_errno_ptr,
	char *(*realfn)(const char *, const char *),
	const char *realfn_name, const char *domainname, const char *dirname)
{
	mapping_results_t res;
	const char *mapped_dirname = dirname;
	char *result = NULL;

	clear_mapping_results_struct(&res);

	if (dirname != NULL) { 
		sbox_map_path(realfn_name, dirname, 0, &res);
		assert(res.mres_result_path != NULL);

		mapped_dirname = res.mres_result_path;

		SB_LOG(SB_LOGLEVEL_DEBUG, "binding domain %s to %s",
		    domainname, mapped_dirname);
	}

	errno = *result_errno_ptr; /* restore to orig.value */
	result = (*realfn)(domainname, mapped_dirname);
	*result_errno_ptr = errno;

	free_mapping_results(&res);
	if (result && (*result != '\0')) {
		char *sbox_path = NULL;
		sbox_path = scratchbox_reverse_path(realfn_name, result);
		if (sbox_path) {
			/* FIXME: this will leak memory. nobody will free
			 * the buffer at *sbox_path; in fact the manual
			 * page denies that ("..must not be modified
			 * or freed")
			*/
			result = sbox_path;
		}
	}
	return (result);
}
Пример #4
0
/* ----- EXPORTED from interface.master: ----- */
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) {
		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);
}
Пример #5
0
char *bindtextdomain_gate(char *(*realfn)(const char *, const char *),
    const char *realfn_name, const char *domainname, const char *dirname)
{
	mapping_results_t res;
	const char *mapped_dirname = dirname;
	char *result = NULL;

	clear_mapping_results_struct(&res);

	if (dirname != NULL) { 
		sbox_map_path(realfn_name, dirname, 0, &res);
		assert(res.mres_result_path != NULL);

		mapped_dirname = res.mres_result_path;

		SB_LOG(SB_LOGLEVEL_DEBUG, "binding domain %s to %s",
		    domainname, mapped_dirname);
	}

	result = (*realfn)(domainname, mapped_dirname);
	free_mapping_results(&res);
	return (result);
}
Пример #6
0
/* Map script interpreter:
 * Called with "rule" and "exec_policy" already in lua's stack,
 * leaves (possibly modified) "rule" and "exec_policy" to lua's stack.
*/
char *sb_execve_map_script_interpreter(
    const char *interpreter,
    const char *interp_arg,
    const char *mapped_script_filename,
    const char *orig_script_filename,
    char ***argv,
    char ***envp)
{
    struct lua_instance *luaif;
    char *mapped_interpreter;
    int new_argc, new_envc;
    int res;

    luaif = get_lua();
    if (!luaif) return(0);

    if (!argv || !envp) {
        SB_LOG(SB_LOGLEVEL_ERROR,
               "ERROR: sb_execve_map_script_interpreter: "
               "(argv || envp) == NULL");
        release_lua(luaif);
        return NULL;
    }

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: gettop=%d"
           " interpreter=%s interp_arg=%s "
           "mapped_script_filename=%s orig_script_filename=%s",
           lua_gettop(luaif->lua), interpreter, interp_arg,
           mapped_script_filename, orig_script_filename);

    lua_getfield(luaif->lua, LUA_GLOBALSINDEX,
                 "sb_execve_map_script_interpreter");

    /* stack now contains "rule", "exec_policy" and
     * "sb_execve_map_script_interpreter".
     * move "sb_execve_map_script_interpreter" to the bottom : */
    lua_insert(luaif->lua, -3);

    lua_pushstring(luaif->lua, interpreter);
    if (interp_arg) lua_pushstring(luaif->lua, interp_arg);
    else lua_pushnil(luaif->lua);
    lua_pushstring(luaif->lua, mapped_script_filename);
    lua_pushstring(luaif->lua, orig_script_filename);
    strvec_to_lua_table(luaif, *argv);
    strvec_to_lua_table(luaif, *envp);

    /* args: rule, exec_policy, interpreter, interp_arg,
     *	 mapped_script_filename, orig_script_filename,
     *	 argv, envp
     * returns: rule, policy, result, mapped_interpreter, #argv, argv,
     *	#envp, envp
     * "result" is one of:
     *  0: argv / envp were modified; mapped_interpreter was set
     *  1: argv / envp were not modified; mapped_interpreter was set
     * -1: deny exec.
    */
    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter M1", luaif->lua);
    }
    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: call lua, gettop=%d",
           lua_gettop(luaif->lua));
    lua_call(luaif->lua, 8, 8);
    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: return from lua, gettop=%d",
           lua_gettop(luaif->lua));
    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter M2", luaif->lua);
    }

    mapped_interpreter = (char *)lua_tostring(luaif->lua, -5);
    if (mapped_interpreter) mapped_interpreter = strdup(mapped_interpreter);

    res = lua_tointeger(luaif->lua, -6);
    switch (res) {

    case 0:
        /* exec arguments were modified, replace contents of
         * argv and envp vectors */
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: Updated argv&envp");

        strvec_free(*argv);
        new_argc = lua_tointeger(luaif->lua, -4);
        lua_string_table_to_strvec(luaif, -3, argv, new_argc);

        new_envc = lua_tointeger(luaif->lua, -2);
        strvec_free(*envp);
        lua_string_table_to_strvec(luaif, -1, envp, new_envc);

        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;

    case 1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: argv&envp were not modified");
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;

    case 2:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: use sbox_map_path_for_exec");
        /* remove all return values from the stack. */
        lua_pop(luaif->lua, 8);
        if (mapped_interpreter) free(mapped_interpreter);
        mapped_interpreter = NULL;
        {
            mapping_results_t	mapping_result;

            clear_mapping_results_struct(&mapping_result);
            sbox_map_path_for_exec("script_interp",
                                   interpreter, &mapping_result);
            if (mapping_result.mres_result_buf) {
                mapped_interpreter =
                    strdup(mapping_result.mres_result_buf);
            }
            free_mapping_results(&mapping_result);
        }
        SB_LOG(SB_LOGLEVEL_DEBUG, "sb_execve_map_script_interpreter: "
               "interpreter=%s mapped_interpreter=%s",
               interpreter, mapped_interpreter);
        break;

    case -1:
        SB_LOG(SB_LOGLEVEL_DEBUG,
               "sb_execve_map_script_interpreter: exec denied");
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        if (mapped_interpreter) free(mapped_interpreter);
        mapped_interpreter = NULL;
        break;

    default:
        SB_LOG(SB_LOGLEVEL_ERROR,
               "sb_execve_map_script_interpreter: Unsupported result %d", res);
        /* remove return values from the stack, leave rule & policy.  */
        lua_pop(luaif->lua, 6);
        break;
    }


    if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
        dump_lua_stack("sb_execve_map_script_interpreter E2", luaif->lua);
    }

    SB_LOG(SB_LOGLEVEL_NOISE,
           "sb_execve_map_script_interpreter: at exit, gettop=%d",
           lua_gettop(luaif->lua));
    release_lua(luaif);
    return mapped_interpreter;
}
Пример #7
0
static int prepare_hashbang(
	char **mapped_file,	/* In: script, out: mapped script interpreter */
	char *orig_file,
	char ***argvp,
	char ***envpp,
	const char *exec_policy_name)
{
	int argc, fd, c, i, j, n;
	char ch;
	char *mapped_interpreter = NULL;
	char **new_argv = NULL;
	char hashbang[SBOX_MAXPATH]; /* only 60 needed on linux, just be safe */
	char interpreter[SBOX_MAXPATH];
	char *interp_arg = NULL;
	char *tmp = NULL, *mapped_binaryname = NULL;
	int result = 0;

	if ((fd = open_nomap(*mapped_file, O_RDONLY)) < 0) {
		/* unexpected error, just run it */
		return 0;
	}

	if ((c = read(fd, &hashbang[0], SBOX_MAXPATH - 1)) < 2) {
		/* again unexpected error, close fd and run it */
		close_nomap_nolog(fd);
		return 0;
	}

	argc = elem_count(*argvp);

	/* extra element for hashbang argument */
	new_argv = calloc(argc + 3, sizeof(char *));

	/* skip any initial whitespace following "#!" */
	for (i = 2; (hashbang[i] == ' ' 
			|| hashbang[i] == '\t') && i < c; i++)
		;

	for (n = 0, j = i; i < c; i++) {
		ch = hashbang[i];
		if (hashbang[i] == 0
			|| hashbang[i] == ' '
			|| hashbang[i] == '\t'
			|| hashbang[i] == '\n') {
			hashbang[i] = 0;
			if (i > j) {
				if (n == 0) {
					char *ptr = &hashbang[j];
					strcpy(interpreter, ptr);
					new_argv[n++] = strdup(interpreter);
				} else {
					/* this was the one and only
					 * allowed argument for the
					 * interpreter
					 */
					interp_arg = strdup(&hashbang[j]);
					new_argv[n++] = interp_arg;
					break;
				}
			}
			j = i + 1;
		}
		if (ch == '\n' || ch == 0) break;
	}

	new_argv[n++] = strdup(orig_file); /* the unmapped script path */
	for (i = 1; (*argvp)[i] != NULL && i < argc; ) {
		new_argv[n++] = (*argvp)[i++];
	}
	new_argv[n] = NULL;

	/* Now we need to update __SB2_ORIG_BINARYNAME to point to 
	 * the unmapped script interpreter (exec_map_script_interpreter
	 * may change it again (not currently, but in the future)
	*/
	change_environment_variable(
		*envpp, "__SB2_ORIG_BINARYNAME=", interpreter);

	/* script interpreter mapping in C */
	exec_policy_handle_t     eph = find_exec_policy_handle(exec_policy_name);
	int c_mapping_result_code;
	const char *c_new_exec_policy_name = NULL;
	
	c_mapping_result_code = exec_map_script_interpreter(eph, exec_policy_name,
		interpreter, interp_arg, *mapped_file,
		orig_file, new_argv, &c_new_exec_policy_name, &mapped_interpreter);
	SB_LOG(SB_LOGLEVEL_DEBUG,
		"back from exec_map_script_interpreter => %d (%s)",
		c_mapping_result_code, (mapped_interpreter ? mapped_interpreter : "<NULL>"));

	switch (c_mapping_result_code) {
	case 0:
                /* exec arguments were modified, argv has been modified */
                SB_LOG(SB_LOGLEVEL_DEBUG,
                        "%s: <0> argv has been updated", __func__);
		break;
	case 1:
                SB_LOG(SB_LOGLEVEL_DEBUG,
                        "%s: <1> argv was not modified", __func__);
		break;
	case 2:
                SB_LOG(SB_LOGLEVEL_DEBUG,
                        "%s: <2> Use ordinary path mapping", __func__);
		if (mapped_interpreter) free(mapped_interpreter);
                mapped_interpreter = NULL;
                {
                        mapping_results_t       mapping_result;

                        clear_mapping_results_struct(&mapping_result);
                        sbox_map_path_for_exec("script_interp",
                                interpreter, &mapping_result);
                        if (mapping_result.mres_result_buf) {
                                mapped_interpreter =
                                        strdup(mapping_result.mres_result_buf);
                        }
                        if (mapping_result.mres_exec_policy_name)
				c_new_exec_policy_name = strdup(mapping_result.mres_exec_policy_name);
			else
				c_new_exec_policy_name = NULL;
                        free_mapping_results(&mapping_result);
                }
                SB_LOG(SB_LOGLEVEL_DEBUG, "%s: "
                        "interpreter=%s mapped_interpreter=%s policy=%s",
                        __func__, interpreter, mapped_interpreter,
                        c_new_exec_policy_name ? c_new_exec_policy_name : "NULL");
		break;
	case -1:
		SB_LOG(SB_LOGLEVEL_DEBUG, "%s: <-1> exec denied", __func__);
		if (mapped_interpreter) free(mapped_interpreter);
		mapped_interpreter = NULL;
		return(-1);
	default:
                SB_LOG(SB_LOGLEVEL_ERROR,
                        "%s: Unsupported result %d", __func__, c_mapping_result_code);
		return(-1);
	}
	exec_policy_name = c_new_exec_policy_name;

	if (!mapped_interpreter) {
		SB_LOG(SB_LOGLEVEL_ERROR,
			"failed to map script interpreter=%s", interpreter);
		return(-1);
	}

	/*
	 * Binaryname (the one expected by the rules) comes still from
	 * the interpreter name so we set it here.  Note that it is now
	 * basename of the mapped interpreter (not the original one)!
	 */
	tmp = strdup(mapped_interpreter);
	mapped_binaryname = strdup(basename(tmp));
	change_environment_variable(*envpp, "__SB2_BINARYNAME=",
	    mapped_binaryname);
	free(mapped_binaryname);
	free(tmp);
	
	SB_LOG(SB_LOGLEVEL_DEBUG, "prepare_hashbang(): interpreter=%s,"
			"mapped_interpreter=%s", interpreter,
			mapped_interpreter);

	/* feed this through prepare_exec to let it deal with
	 * cpu transparency etc.
	 */
	result = prepare_exec("run_hashbang",
		exec_policy_name,
		mapped_interpreter,
		1/*file_has_been_mapped, and rue&policy exist*/,
		new_argv, *envpp,
		(enum binary_type*)NULL,
		mapped_file, argvp, envpp);

	SB_LOG(SB_LOGLEVEL_DEBUG, "prepare_hashbang done: mapped_file='%s'",
			*mapped_file);

	return(result);
}
Пример #8
0
static int prepare_exec(const char *exec_fn_name,
	const char *exec_policy_name,
	const char *orig_file,
	int file_has_been_mapped,
	char *const *orig_argv,
	char *const *orig_envp,
	enum binary_type *typep,
	char **new_file,  /* return value */
	char ***new_argv,
	char ***new_envp) /* *new_envp must be filled by the caller */
{
	char **my_envp = *new_envp; /* FIXME */
	const char **my_new_envp = NULL;
	const char **my_new_argv = NULL;
	char **my_argv = NULL, *my_file = NULL;
	char *binaryname, *tmp, *mapped_file;
	int err = 0;
	enum binary_type type;
	int postprocess_result = 0;
	int ret = 0; /* 0: ok to exec, ret<0: exec fails */
	int file_mode;
	uid_t file_uid;
	gid_t file_gid;
	PROCESSCLOCK(clk1)
	PROCESSCLOCK(clk4)

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "prepare_exec");
	(void)exec_fn_name; /* not yet used */
	(void)orig_envp; /* not used */

	SB_LOG(SB_LOGLEVEL_DEBUG,
		"prepare_exec(): orig_file='%s'",
		orig_file);
	SB_LOG(SB_LOGLEVEL_NOISE,
		"%s: exec_policy_name='%s'", __func__, exec_policy_name);

	tmp = strdup(orig_file);
	binaryname = strdup(basename(tmp)); /* basename may modify *tmp */
	free(tmp);
	
	my_file = strdup(orig_file);

	my_argv = duplicate_argv(orig_argv);

	if (!file_has_been_mapped) {
		PROCESSCLOCK(clk2)

		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk2, "execve_preprocess");
		if ((err = apply_exec_preprocessing_rules(&my_file, &my_argv, &my_envp)) != 0) {
			SB_LOG(SB_LOGLEVEL_ERROR, "argvenvp processing error %i", err);
		}
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk2, my_file);
	}

	/* test if mapping is enabled during the exec()..
	 * (host-* tools disable it)
	*/
	if (file_has_been_mapped) {
		/* (e.g. we came back from run_hashbang()) */
		SB_LOG(SB_LOGLEVEL_DEBUG,
			"prepare_exec(): no double mapping, my_file = %s", my_file);
		mapped_file = strdup(my_file);
	} else if (strvec_contains_prefix(my_envp, "SBOX_DISABLE_MAPPING=1", NULL)) {
		SB_LOG(SB_LOGLEVEL_DEBUG,
			"do_exec(): mapping disabled, my_file = %s", my_file);
		mapped_file = strdup(my_file);

		/* we won't call sbox_map_path_for_exec() because mapping
		 * is disabled.  */
	} else {
		/* 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;
		PROCESSCLOCK(clk3)

		clear_mapping_results_struct(&mapping_result);
		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk3, "map_path_for_exec");
		sbox_map_path_for_exec("do_exec", my_file, &mapping_result);
		mapped_file = (mapping_result.mres_result_buf ?
			strdup(mapping_result.mres_result_buf) : NULL);
		exec_policy_name = (mapping_result.mres_exec_policy_name ?
			strdup(mapping_result.mres_exec_policy_name) : NULL);
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk3, mapped_file);
			
		free_mapping_results(&mapping_result);

		SB_LOG(SB_LOGLEVEL_DEBUG,
			"do_exec(): my_file = %s, mapped_file = %s",
			my_file, mapped_file);
	}

	/*
	 * prepare_envp_for_do_exec() left us placeholder in envp array
	 * that we will fill now with fully mangled binary name.
	 */
	change_environment_variable(my_envp,
		"__SB2_REAL_BINARYNAME=", mapped_file);

	/* inspect the completely mangled filename */
	type = inspect_binary(mapped_file, 1/*check_x_permission*/,
		&file_mode, &file_uid, &file_gid);
	if (typep) *typep = type;

	if (!exec_policy_name) {
		if ((type != BIN_INVALID) && (type != BIN_NONE)) {
			exec_policy_name = find_exec_policy_name(mapped_file, my_file);
			if (!exec_policy_name) {
				errno = ENOEXEC;
				ret = -1;
				SB_LOG(SB_LOGLEVEL_ERROR,
					"No exec policy (%s,%s) => ENOEXEC",
					my_file, mapped_file);
				goto out;
			}
		}
	}
	SB_LOG(SB_LOGLEVEL_DEBUG, "%s: exec_policy_name=%s", __func__, exec_policy_name);

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk4, "exec/typeswitch");
	switch (type) {
		case BIN_HASHBANG:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/hashbang %s", mapped_file);
			/* prepare_hashbang() will call prepare_exec()
			 * recursively */
			ret = prepare_hashbang(&mapped_file, my_file,
					&my_argv, &my_envp, exec_policy_name);
			break;

		case BIN_HOST_DYNAMIC:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/host-dynamic %s",
					mapped_file);

#if 0
			postprocess_result = sb_execve_postprocess("native",
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				&my_argv, &my_envp);
#else
			postprocess_result = exec_postprocess_native_executable(
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				(const char **)my_argv, &my_new_argv, (const char **)*new_envp, &my_new_envp);
			my_envp = (char**)my_new_envp; /* FIXME */
			my_argv = (char**)my_new_argv; /* FIXME */
#endif

			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					1/*host_compatible_binary*/);
			}
			break;

		case BIN_HOST_STATIC:
#if 0
			postprocess_result = sb_execve_postprocess("static",
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				&my_argv, &my_envp);
#else
			{
				const char			*namev_in_ruletree[4];
				const char			*cputransp_cmd = NULL;
				ruletree_object_offset_t	cmd_offs;

				namev_in_ruletree[0] = "cputransparency";
				namev_in_ruletree[1] = "native";
				namev_in_ruletree[2] = "cmd";
				namev_in_ruletree[3] = NULL;
				cmd_offs = ruletree_catalog_vget(namev_in_ruletree);
				if (cmd_offs) {
					cputransp_cmd = offset_to_ruletree_string_ptr(cmd_offs, NULL);
				}
				if (cputransp_cmd && (cputransp_cmd[0] != '\0')) {
					postprocess_result = exec_postprocess_cpu_transparency_executable(
						exec_policy_name,
						&mapped_file, &my_file, binaryname,
						(const char **)my_argv, &my_new_argv,
						(const char **)*new_envp, &my_new_envp,
						"native");
					my_envp = (char**)my_new_envp; /* FIXME */
					my_argv = (char**)my_new_argv; /* FIXME */
				} else {
					const char *allow_static_bin = NULL;

					/* don't print warning, if this static binary
					 * has been allowed (see the wrapper for
					 * ldconfig - we don't want to see warnings
					 * every time when someone executes that)
					*/
					allow_static_bin = getenv("SBOX_ALLOW_STATIC_BINARY");
					if (allow_static_bin &&
					    !strcmp(allow_static_bin, mapped_file)) {
						/* no warnning, just debug */
						SB_LOG(SB_LOGLEVEL_DEBUG,
							"statically linked "
							"native binary %s (allowed)",
							mapped_file);
					} else {
						SB_LOG(SB_LOGLEVEL_WARNING,
							"Executing statically "
							"linked native binary %s",
							mapped_file);
					}
					/* Add LD_LIBRARY_PATH and LD_PRELOAD.
					 * the static binary itself does not need
					 * these, but if it executes another 
					 * program, then there is at least some
					 * hope of getting back to SB2. It won't
					 * be able to start anything that runs
					 * under CPU transparency, but host-compatible
					 * binaries may be able to get back..
					*/
					postprocess_result = exec_postprocess_host_static_executable(
						exec_policy_name,
						&mapped_file, &my_file, binaryname,
						(const char **)my_argv, &my_new_argv,
						(const char **)*new_envp, &my_new_envp);
					my_envp = (char**)my_new_envp; /* FIXME */
					my_argv = (char**)my_new_argv; /* FIXME */
				}
			}
#endif
			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				/* the static binary won't get SUID simulation,
				 * but if it executes something else.. */
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					1/*host_compatible_binary*/);
			}
			break;

		case BIN_TARGET:
			SB_LOG(SB_LOGLEVEL_DEBUG, "Exec/target %s",
					mapped_file);

#if 0
			postprocess_result = sb_execve_postprocess(
				"cpu_transparency",
				exec_policy_name,
				&mapped_file, &my_file,
				binaryname, &my_argv, &my_envp);
#else
			postprocess_result = exec_postprocess_cpu_transparency_executable(
				exec_policy_name,
				&mapped_file, &my_file, binaryname,
				(const char **)my_argv, &my_new_argv, (const char **)*new_envp, &my_new_envp,
				"target");
			my_envp = (char**)my_new_envp; /* FIXME */
			my_argv = (char**)my_new_argv; /* FIXME */
#endif

			if (postprocess_result < 0) {
				errno = EINVAL;
				ret = -1;
			} else {
				simulate_suid_and_sgid_if_needed(mapped_file, my_envp,
					file_mode, file_uid, file_gid,
					0/*not host_compatible_binary*/);
			}
			break;

		case BIN_INVALID: /* = can't be executed, no X permission */
	 		/* don't even try to exec, errno has been set.*/
			ret = -1;
			break;

		case BIN_NONE:
			/* file does not exist. errno has been set. */
			ret = -1;
			break;

		case BIN_UNKNOWN:
			errno = ENOEXEC;
			ret = -1;
			SB_LOG(SB_LOGLEVEL_DEBUG,
				"Unidentified executable detected (%s) => ENOEXEC",
				mapped_file);
			break;
	}
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk4, my_file);
    out:
	*new_file = mapped_file;
	*new_argv = my_argv;
	*new_envp = my_envp;
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, orig_file);
	return(ret);
}
Пример #9
0
static void fwd_map_path(
	const char *binary_name,
	const char *func_name,
	const char *virtual_path,
	int dont_resolve_final_symlink,
	int exec_mode,
	uint32_t fn_class,
	mapping_results_t *res)
{
	struct sb2context *sb2ctx = NULL;

	(void)exec_mode; /* not used */

	if (!virtual_path) {
		res->mres_result_buf = res->mres_result_path = NULL;
		res->mres_readonly = 1;
	} else {
#if 0
		mapping_results_t res2;
#endif
		PROCESSCLOCK(clk1)

		sb2ctx = check_mapping_method(1);

		START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "fwd_map_path");
		switch (mapping_method) {
#if 0
		case MAPPING_METHOD_C_ENGINE_WITH_FALLBACKS:
			sbox_map_path_internal__c_engine(sb2ctx, binary_name,
				func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res, 0);
			if (res->mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), fallback to Lua (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
				free_mapping_results(res);
				if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
				sbox_map_path_internal__lua_engine(sb2ctx, binary_name,
					func_name, virtual_path,
					dont_resolve_final_symlink, 0, fn_class, res);
			}
			break;
#endif
		case MAPPING_METHOD_C_ENGINE:
			sbox_map_path_internal__c_engine(sb2ctx, binary_name,
				func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res, 0);
			if (res->mres_fallback_to_lua_mapping_engine &&
			    (res->mres_fallback_to_lua_mapping_engine[0] == '#')) {
#if 0
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), fallback to Lua was forced (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
				free_mapping_results(res);
				if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
				sbox_map_path_internal__lua_engine(sb2ctx, binary_name,
					func_name, virtual_path,
					dont_resolve_final_symlink, 0, fn_class, res);
#else
				SB_LOG(SB_LOGLEVEL_ERROR,
					"C path mapping engine tries to force fallback to Lua, won't do that (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
#endif
			} else if (res->mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_NOTICE,
					"C path mapping engine failed (%s), NO fallback to Lua (%s)",
					res->mres_fallback_to_lua_mapping_engine, virtual_path);
			}
			break;
#if 0
		case MAPPING_METHOD_LUA_ENGINE:
			sbox_map_path_internal__lua_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res);
			break;
		case MAPPING_METHOD_BOTH_ENGINES:
			clear_mapping_results_struct(&res2);
			sbox_map_path_internal__lua_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, res);
			sbox_map_path_internal__c_engine(sb2ctx, binary_name, func_name, virtual_path,
				dont_resolve_final_symlink, 0, fn_class, &res2, 0);
			if (res2.mres_fallback_to_lua_mapping_engine) {
				SB_LOG(SB_LOGLEVEL_ERROR,
					"C path mapping engine => fallback to Lua (%s), (%s)",
					res2.mres_fallback_to_lua_mapping_engine, virtual_path);
			}
			compare_results_from_c_and_lua_engines(
				"result path",
				__func__, res2.mres_result_path,
				res->mres_result_path);
			compare_results_from_c_and_lua_engines(
				"virtual cwd",
				__func__, res2.mres_virtual_cwd,
				res->mres_virtual_cwd);
			free_mapping_results(&res2);
			break;
#endif
		default:
			SB_LOG(SB_LOGLEVEL_ERROR,
				"%s: Invalid mapping method",
				__func__);
		}
		release_sb2context(sb2ctx);
		STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, virtual_path);
	}
}