Skip to content

Commit

Permalink
Avoid leaking vchans
Browse files Browse the repository at this point in the history
Leaking vchans will cause Xenstore entries to also leak, which is bad.
If it happens in a VM it will cause quota problems, while if it happens
in dom0 it will just slow down Xenstore.
  • Loading branch information
DemiMarie committed Apr 28, 2024
1 parent e06514b commit 76790cb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 14 deletions.
1 change: 1 addition & 0 deletions daemon/qrexec-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ int main(int argc, char **argv)
if (qubes_wait_for_vchan_connection_with_timeout(
data_vchan, fd, true, connection_timeout) < 0) {
LOG(ERROR, "qrexec connection timeout");
libvchan_close(data_vchan);
rc = QREXEC_EXIT_PROBLEM;
goto cleanup;
}
Expand Down
25 changes: 14 additions & 11 deletions daemon/qrexec-daemon-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ int run_qrexec_to_dom0(const struct service_params *svc_params,
if (qubes_wait_for_vchan_connection_with_timeout(
data_vchan, wait_fd, false, connection_timeout) < 0) {
LOG(ERROR, "qrexec connection timeout");
libvchan_close(data_vchan);
return QREXEC_EXIT_PROBLEM;
}

Expand All @@ -496,23 +497,25 @@ int run_qrexec_to_dom0(const struct service_params *svc_params,

int handshake_and_go(struct handshake_params *params)
{
int rc = QREXEC_EXIT_PROBLEM;
if (params->data_vchan == NULL || !libvchan_is_open(params->data_vchan)) {
LOG(ERROR, "Failed to open data vchan connection");
return QREXEC_EXIT_PROBLEM;
goto cleanup;
}
int rc;
int data_protocol_version = handle_agent_handshake(params->data_vchan,
params->remote_send_first);
if (data_protocol_version < 0) {
rc = QREXEC_EXIT_PROBLEM;
} else if (params->prepare_ret != 0) {
rc = params->prepare_ret == -1 ? QREXEC_EXIT_SERVICE_NOT_FOUND : QREXEC_EXIT_PROBLEM;
handle_failed_exec(params->data_vchan, params->remote_send_first, rc);
} else {
params->data_protocol_version = data_protocol_version;
rc = select_loop(params);
if (data_protocol_version >= 0) {
if (params->prepare_ret != 0) {
rc = params->prepare_ret == -1 ? QREXEC_EXIT_SERVICE_NOT_FOUND : QREXEC_EXIT_PROBLEM;
handle_failed_exec(params->data_vchan, params->remote_send_first, rc);
} else {
params->data_protocol_version = data_protocol_version;
rc = select_loop(params);
}
}
libvchan_close(params->data_vchan);
cleanup:
if (params->data_vchan != NULL)
libvchan_close(params->data_vchan);
params->data_vchan = NULL;
return rc;
}
6 changes: 4 additions & 2 deletions libqrexec/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,14 @@ static int do_fork_exec(const char *user,
(stderr_fd && socketpair(AF_UNIX, SOCK_STREAM, 0, errpipe)) ||
socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, statuspipe)) {
PERROR("socketpair");
exit(1);
/* FD leaks do not matter, we exit soon anyway */
return -2;
}
switch (*pid = fork()) {
case -1:
PERROR("fork");
exit(-1);
/* ditto */
return -2;
case 0: {
int status;
if (signal(SIGPIPE, SIG_DFL) == SIG_ERR)
Expand Down
2 changes: 1 addition & 1 deletion libqrexec/libqrexec-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int execute_parsed_qubes_rpc_command(
*/
__attribute__((visibility("default")))
int find_qrexec_service(
const struct qrexec_parsed_command *cmd,
struct qrexec_parsed_command *cmd,
int *socket_fd, struct buffer *stdin_buffer);

/** Suggested buffer size for the path buffer of find_qrexec_service. */
Expand Down

0 comments on commit 76790cb

Please sign in to comment.