Skip to content

Commit

Permalink
daemon: prevent collisions between port numbers
Browse files Browse the repository at this point in the history
Should prevent the situations where a wrong vchan connection is
terminated, which causes e.g. premature termination of a DispVM.

See longer discussion in QubesOS/qubes-issues#3318.
  • Loading branch information
pwmarcz authored and marmarek committed May 9, 2020
1 parent 4276746 commit 10149da
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions qrexec/qrexec-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,39 @@ static int send_client_hello(int fd)
return 0;
}

static int allocate_vchan_port(int new_state)
static int allocate_vchan_port(int connect_domain)
{
int i;
/*
Make sure the allocated ports numbers are unique for a given {domX, domY}
set.
For domX-domY connections, both daemons can allocate ports. If they both
allocate the same port number, this can cause trouble:
- We might receive MSG_CONNECTION_TERMINATED for the wrong connection.
- Although vchan connections in both directions can exist independently,
the direction (client-server or server-client) is not always
the same, so collision is still possible.
To prevent that from happening, for X < Y allow the daemon for X to
allocate only odd port numbers, and the daemon for Y to allocate only
even port numbers.
(This does not apply if we are connecting to/from dom0, as there is no
separate daemon running for dom0).
*/

for (i = 0; i < MAX_CLIENTS; i++) {
int i, step;
if (connect_domain == 0) {
i = 0;
step = 1;
} else {
i = connect_domain > remote_domain_id ? 1 : 0;
step = 2;
}

for (; i < MAX_CLIENTS; i += step) {
if (used_vchan_ports[i] == VCHAN_PORT_UNUSED) {
used_vchan_ports[i] = new_state;
used_vchan_ports[i] = connect_domain;
return VCHAN_BASE_DATA_PORT+i;
}
}
Expand Down

0 comments on commit 10149da

Please sign in to comment.