Skip to content

Commit

Permalink
Treat zero timeout as infinite
Browse files Browse the repository at this point in the history
The other possible behavior (instantly failing the service call) is not
useful.

Fixes: QubesOS/qubes-issues#9126
Fixes: c664954 ("Avoid using alarm(2) for timeouts")
  • Loading branch information
DemiMarie committed Apr 19, 2024
1 parent 9401273 commit 31e412f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
30 changes: 16 additions & 14 deletions libqrexec/vchan_timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,27 @@ int qubes_wait_for_vchan_connection_with_timeout(
assert(end_tp.tv_nsec >= 0 && end_tp.tv_nsec < BILLION_NANOSECONDS);
end_tp.tv_sec += timeout;
for (;;) {
bool did_timeout = true;
struct pollfd fds = { .fd = wait_fd, .events = POLLIN | POLLHUP, .revents = 0 };
bool did_timeout = timeout > 0;

/* calculate how much time left until connection timeout expire */
if (clock_gettime(CLOCK_MONOTONIC, &now_tp)) {
PERROR("clock_gettime");
return -1;
}
assert(now_tp.tv_nsec >= 0 && now_tp.tv_nsec < BILLION_NANOSECONDS);
if (now_tp.tv_sec <= end_tp.tv_sec) {
timeout_tp.tv_sec = end_tp.tv_sec - now_tp.tv_sec;
timeout_tp.tv_nsec = end_tp.tv_nsec - now_tp.tv_nsec;
if (timeout_tp.tv_nsec < 0) {
timeout_tp.tv_nsec += BILLION_NANOSECONDS;
timeout_tp.tv_sec--;
if (did_timeout) {
if (clock_gettime(CLOCK_MONOTONIC, &now_tp)) {
PERROR("clock_gettime");

Check warning on line 25 in libqrexec/vchan_timeout.c

View check run for this annotation

Codecov / codecov/patch

libqrexec/vchan_timeout.c#L25

Added line #L25 was not covered by tests
return -1;
}
assert(now_tp.tv_nsec >= 0 && now_tp.tv_nsec < BILLION_NANOSECONDS);
if (now_tp.tv_sec <= end_tp.tv_sec) {
timeout_tp.tv_sec = end_tp.tv_sec - now_tp.tv_sec;
timeout_tp.tv_nsec = end_tp.tv_nsec - now_tp.tv_nsec;
if (timeout_tp.tv_nsec < 0) {
timeout_tp.tv_nsec += BILLION_NANOSECONDS;
timeout_tp.tv_sec--;
}
did_timeout = timeout_tp.tv_sec < 0;
}
did_timeout = timeout_tp.tv_sec < 0;
}
switch (did_timeout ? 0 : ppoll(&fds, 1, &timeout_tp, NULL)) {
switch (did_timeout ? 0 : ppoll(&fds, 1, timeout > 0 ? &timeout_tp : NULL, NULL)) {
case -1:
if (errno == EINTR)
break;
Expand Down
5 changes: 3 additions & 2 deletions qrexec/tests/socket/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ def test_run_vm_command_and_connect_vm(self):
self.client.wait()
self.assertEqual(self.client.returncode, 0)

def connect_service_request(self, cmd):
def connect_service_request(self, cmd, timeout=None):
request_id = "SOCKET11"
src_domain_name = "src_domain"
src_domain = 43
Expand All @@ -749,6 +749,7 @@ def connect_service_request(self, cmd):
"dom0",
"-c",
"{},{},{}".format(request_id, src_domain_name, src_domain),
*([f"-w{timeout}"] if timeout is not None else []),
cmd,
]
)
Expand Down Expand Up @@ -1010,7 +1011,7 @@ def test_run_dom0_service_socket_shutdown_rd(self):
server = qrexec.socket_server(socket_path)
self.addCleanup(server.close)
cmd = "QUBESRPC qubes.SocketService+arg src_domain name src_domain"
source = self.connect_service_request(cmd)
source = self.connect_service_request(cmd, timeout=0)

server.accept()
header = cmd[len("QUBESRPC ") :].encode() + b"\0"
Expand Down

0 comments on commit 31e412f

Please sign in to comment.