Skip to content

Commit 31e412f

Browse files
committed
Treat zero timeout as infinite
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")
1 parent 9401273 commit 31e412f

File tree

2 files changed

+19
-16
lines changed

2 files changed

+19
-16
lines changed

libqrexec/vchan_timeout.c

+16-14
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,27 @@ int qubes_wait_for_vchan_connection_with_timeout(
1616
assert(end_tp.tv_nsec >= 0 && end_tp.tv_nsec < BILLION_NANOSECONDS);
1717
end_tp.tv_sec += timeout;
1818
for (;;) {
19-
bool did_timeout = true;
2019
struct pollfd fds = { .fd = wait_fd, .events = POLLIN | POLLHUP, .revents = 0 };
20+
bool did_timeout = timeout > 0;
2121

2222
/* calculate how much time left until connection timeout expire */
23-
if (clock_gettime(CLOCK_MONOTONIC, &now_tp)) {
24-
PERROR("clock_gettime");
25-
return -1;
26-
}
27-
assert(now_tp.tv_nsec >= 0 && now_tp.tv_nsec < BILLION_NANOSECONDS);
28-
if (now_tp.tv_sec <= end_tp.tv_sec) {
29-
timeout_tp.tv_sec = end_tp.tv_sec - now_tp.tv_sec;
30-
timeout_tp.tv_nsec = end_tp.tv_nsec - now_tp.tv_nsec;
31-
if (timeout_tp.tv_nsec < 0) {
32-
timeout_tp.tv_nsec += BILLION_NANOSECONDS;
33-
timeout_tp.tv_sec--;
23+
if (did_timeout) {
24+
if (clock_gettime(CLOCK_MONOTONIC, &now_tp)) {
25+
PERROR("clock_gettime");
26+
return -1;
27+
}
28+
assert(now_tp.tv_nsec >= 0 && now_tp.tv_nsec < BILLION_NANOSECONDS);
29+
if (now_tp.tv_sec <= end_tp.tv_sec) {
30+
timeout_tp.tv_sec = end_tp.tv_sec - now_tp.tv_sec;
31+
timeout_tp.tv_nsec = end_tp.tv_nsec - now_tp.tv_nsec;
32+
if (timeout_tp.tv_nsec < 0) {
33+
timeout_tp.tv_nsec += BILLION_NANOSECONDS;
34+
timeout_tp.tv_sec--;
35+
}
36+
did_timeout = timeout_tp.tv_sec < 0;
3437
}
35-
did_timeout = timeout_tp.tv_sec < 0;
3638
}
37-
switch (did_timeout ? 0 : ppoll(&fds, 1, &timeout_tp, NULL)) {
39+
switch (did_timeout ? 0 : ppoll(&fds, 1, timeout > 0 ? &timeout_tp : NULL, NULL)) {
3840
case -1:
3941
if (errno == EINTR)
4042
break;

qrexec/tests/socket/daemon.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ def test_run_vm_command_and_connect_vm(self):
734734
self.client.wait()
735735
self.assertEqual(self.client.returncode, 0)
736736

737-
def connect_service_request(self, cmd):
737+
def connect_service_request(self, cmd, timeout=None):
738738
request_id = "SOCKET11"
739739
src_domain_name = "src_domain"
740740
src_domain = 43
@@ -749,6 +749,7 @@ def connect_service_request(self, cmd):
749749
"dom0",
750750
"-c",
751751
"{},{},{}".format(request_id, src_domain_name, src_domain),
752+
*([f"-w{timeout}"] if timeout is not None else []),
752753
cmd,
753754
]
754755
)
@@ -1010,7 +1011,7 @@ def test_run_dom0_service_socket_shutdown_rd(self):
10101011
server = qrexec.socket_server(socket_path)
10111012
self.addCleanup(server.close)
10121013
cmd = "QUBESRPC qubes.SocketService+arg src_domain name src_domain"
1013-
source = self.connect_service_request(cmd)
1014+
source = self.connect_service_request(cmd, timeout=0)
10141015

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

0 commit comments

Comments
 (0)