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); }
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); }