static void handle_execute_service(void)
{
    int i;
    int policy_pending_slot;
    pid_t pid;
    struct trigger_service_params untrusted_params, params;
    char remote_domain_id_str[10];

    if (libvchan_recv(vchan, &untrusted_params, sizeof(untrusted_params)) < 0)
        handle_vchan_error("recv params");

    /* sanitize start */
    ENSURE_NULL_TERMINATED(untrusted_params.service_name);
    ENSURE_NULL_TERMINATED(untrusted_params.target_domain);
    ENSURE_NULL_TERMINATED(untrusted_params.request_id.ident);
    sanitize_name(untrusted_params.service_name, "+");
    sanitize_name(untrusted_params.target_domain, "@:");
    sanitize_name(untrusted_params.request_id.ident, " ");
    params = untrusted_params;
    /* sanitize end */

    policy_pending_slot = find_policy_pending_slot();
    if (policy_pending_slot < 0) {
        fprintf(stderr, "Service request denied, too many pending requests\n");
        send_service_refused(vchan, &untrusted_params.request_id);
        return;
    }

    switch (pid=fork()) {
        case -1:
            perror("fork");
            exit(1);
        case 0:
            break;
        default:
            policy_pending[policy_pending_slot].pid = pid;
            policy_pending[policy_pending_slot].params = untrusted_params.request_id;
            return;
    }
    for (i = 3; i < MAX_FDS; i++)
        close(i);
    signal(SIGCHLD, SIG_DFL);
    signal(SIGPIPE, SIG_DFL);
    snprintf(remote_domain_id_str, sizeof(remote_domain_id_str), "%d",
            remote_domain_id);
    execl("/usr/bin/qrexec-policy", "qrexec-policy", "--",
            remote_domain_id_str, remote_domain_name, params.target_domain,
            params.service_name, params.request_id.ident, NULL);
    perror("execl");
    _exit(1);
}
示例#2
0
void handle_execute_predefined_command()
{
	int i;
	struct trigger_connect_params untrusted_params, params;

	check_children_count_and_wait_if_too_many();
	read_all_vchan_ext(&untrusted_params, sizeof(params));

	/* sanitize start */
	ENSURE_NULL_TERMINATED(untrusted_params.exec_index);
	ENSURE_NULL_TERMINATED(untrusted_params.target_vmname);
	ENSURE_NULL_TERMINATED(untrusted_params.process_fds.ident);
	sanitize_name(untrusted_params.exec_index);
	sanitize_name(untrusted_params.target_vmname);
	sanitize_name(untrusted_params.process_fds.ident);
	params = untrusted_params;
	/* sanitize end */

	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		break;
	default:
		children_count++;
		return;
	}
	for (i = 3; i < MAX_FDS; i++)
		close(i);
	signal(SIGCHLD, SIG_DFL);
	signal(SIGPIPE, SIG_DFL);
	execl("/usr/lib/qubes/qrexec_policy", "qrexec_policy",
	      remote_domain_name, params.target_vmname,
	      params.exec_index, params.process_fds.ident, NULL);
	perror("execl");
	exit(1);
}