From 50bc9db0ae4d1ac30171633eff20af57b73c4326 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Sun, 19 May 2024 18:14:09 -0400 Subject: [PATCH] Send EOF on stdout when exiting due to EOF on stdin Previously, if a service with exit-on-client-eof=true received EOF on stdin while stdout was still open, no EOF would be sent on stdout. This is a (currently harmless) violation of the qrexec protocol. Fix this by sending an empty MSG_DATA_STDOUT to indicate EOF on stdout. Fixes: QubesOS/qubes-issues#9429 --- libqrexec/process_io.c | 8 ++++++++ qrexec/tests/socket/agent.py | 1 + 2 files changed, 9 insertions(+) diff --git a/libqrexec/process_io.c b/libqrexec/process_io.c index aba6b78d..f100fc72 100644 --- a/libqrexec/process_io.c +++ b/libqrexec/process_io.c @@ -169,6 +169,14 @@ int qrexec_process_io(const struct process_io_request *req, /* Convenience macros that eliminate a ton of error-prone boilerplate */ #define close_stdin() do { \ if (exit_on_stdin_eof) { \ + /* If stdout is still open, send EOF */ \ + if (stdout_fd != -1) { \ + const struct msg_header hdr = { \ + .type = stdout_msg_type, \ + .len = 0, \ + }; \ + libvchan_send(vchan, &hdr, sizeof(hdr)); \ + }; \ /* Set stdin_fd and stdout_fd to -1. \ * No need to close them as the process \ * will soon exit. */ \ diff --git a/qrexec/tests/socket/agent.py b/qrexec/tests/socket/agent.py index 6efc20fc..32260a05 100644 --- a/qrexec/tests/socket/agent.py +++ b/qrexec/tests/socket/agent.py @@ -758,6 +758,7 @@ def test_connect_socket_exit_on_stdin_eof(self): self.assertEqual(target.recv_all_messages(), [ (qrexec.MSG_DATA_STDERR, b""), + (qrexec.MSG_DATA_STDOUT, b""), (qrexec.MSG_DATA_EXIT_CODE, b"\0\0\0\0"), ]) self.check_dom0(dom0)