示例#1
0
/* ----- EXPORTED from interface.master: ----- */
int sb2show__execve_mods__(
	char *file,
	char *const *orig_argv, char *const *orig_envp,
	char **new_file, char ***new_argv, char ***new_envp)
{
	int	ret = 0;
	char	*tmp, *binaryname;

	if (!sb2_global_vars_initialized__) sb2_initialize_global_variables();

	SB_LOG(SB_LOGLEVEL_DEBUG, "%s '%s'", __func__, orig_argv[0]);

	if (!file) return(ret);

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

	*new_envp = prepare_envp_for_do_exec(file, binaryname, orig_envp);

	ret = prepare_exec("sb2show_exec", NULL/*exec_policy_name*/,
		file, 0, orig_argv, orig_envp,
		NULL, new_file, new_argv, new_envp);

	if (!*new_file) *new_file = strdup(file);
	if (!*new_argv) *new_argv = duplicate_argv(orig_argv);
	if (!*new_envp) *new_envp = duplicate_argv(orig_envp);

	return(ret);
}
int launch_app_with_nice(const char *file, char *const argv[], pid_t *pid, int _nice)
{
	int ret;
	int _pid;

	if (file == NULL || access(file, X_OK) != 0) {
		PRT_TRACE_ERR("launch app error: Invalid input");
		errno = EINVAL;
		return -1;
	}

	if (pid && (*pid > 0 && kill(*pid, 0) != -1))
		return *pid;

	_pid = fork();

	if (_pid == -1) {
		PRT_TRACE_ERR("fork error: %s", strerror(errno));
		/* keep errno */
		return -1;
	}

	if (_pid > 0) {     /* parent */
		if (pid)
			*pid = _pid;
		return _pid;
	}

	/* child */
	prepare_exec();

	ret = nice(_nice);

	if (ret == -1 && errno != 0)
		PRT_TRACE_ERR("nice error: %s", strerror(errno));

	ret = execvp(file, argv);

	/* If failed... */
	PRT_TRACE_ERR("exec. error: %s", strerror(errno));
	return -2;
}
示例#3
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);
}
示例#4
0
int do_exec(int *result_errno_ptr,
	const char *exec_fn_name, const char *orig_file,
	char *const *orig_argv, char *const *orig_envp)
{
	char *new_file = NULL;
	char **new_argv = NULL;
	char **new_envp = NULL;
	int  result;
	PROCESSCLOCK(clk1)

	START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "do_exec");
	if (getenv("SBOX_DISABLE_MAPPING")) {
		/* just run it, don't worry, be happy! */
	} else {
		int	r;
		char	**my_envp_copy = NULL; /* used only for debug log */
		char	*tmp, *binaryname;
		enum binary_type type;

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

		if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
			char *buf = strvec_to_string(orig_argv);

			SB_LOG(SB_LOGLEVEL_DEBUG,
				"EXEC/Orig.args: %s : %s", orig_file, buf);
			free(buf);
		
			/* create a copy of intended environment for logging,
			 * before preprocessing */
			my_envp_copy = prepare_envp_for_do_exec(orig_file,
				binaryname, orig_envp);
		}
		
		new_envp = prepare_envp_for_do_exec(orig_file, binaryname, orig_envp);

		r = prepare_exec(exec_fn_name, NULL/*exec_policy_name: not yet known*/,
			orig_file, 0, orig_argv, orig_envp,
			&type, &new_file, &new_argv, &new_envp);

		if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
			/* find out and log if preprocessing did something */
			compare_and_log_strvec_changes("argv", orig_argv, new_argv);
			compare_and_log_strvec_changes("envp", my_envp_copy, new_envp);
		}

		if (r < 0) {
			SB_LOG(SB_LOGLEVEL_DEBUG,
				"EXEC denied by prepare_exec(), %s", orig_file);
			*result_errno_ptr = errno;
			STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Exec denied");
			return(r); /* exec denied */
		}

		if (check_envp_has_ld_preload_and_ld_library_path(
			new_envp ? new_envp : orig_envp) == 0) {

			SB_LOG(SB_LOGLEVEL_ERROR,
				"exec(%s) failed, internal configuration error: "
				"LD_LIBRARY_PATH and/or LD_PRELOAD were not set "
				"by exec mapping logic", orig_file);
			*result_errno_ptr = EINVAL;
			STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Config error");
			return(-1);
		}
	}

	errno = *result_errno_ptr; /* restore to orig.value */
	STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, orig_file);
	result = sb_next_execve(
		(new_file ? new_file : orig_file),
		(new_argv ? new_argv : orig_argv),
		(new_envp ? new_envp : orig_envp));
	*result_errno_ptr = errno;
	SB_LOG(SB_LOGLEVEL_DEBUG,
		"EXEC failed (%s), errno=%d", orig_file, *result_errno_ptr);
	return(result);
}