From 66c15196232c7690899af37ba731af0885f6e797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 3 Dec 2024 05:32:23 +0100 Subject: [PATCH] Try to retrieve exit code of a failed service call When service call fails, the remote (service) side sends EOF + exit code and closes the vchan immediately. If the client side tries to send something, it will fail and exit immediately (with code 1). But reading data that was queued in the vchan before its closing is still possible. So, on send error check if there is anything interesting to receive (especially exit code, but potentially also some service output) and, if yes, don't exit immediately. Since the service exit code is sent last (after all stdout/stderr data and their EOF), it's okay to check just for remote_status. This is relevant only to the service client side, as exit status of the service-handling process is not relevant. Fixes QubesOS/qubes-issues#9618 --- libqrexec/process_io.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libqrexec/process_io.c b/libqrexec/process_io.c index c1dd8714..b0524876 100644 --- a/libqrexec/process_io.c +++ b/libqrexec/process_io.c @@ -346,7 +346,16 @@ int qrexec_process_io(const struct process_io_request *req, vchan, stdout_fd, stdout_msg_type, &prefix, &remote_buffer)) { case REMOTE_ERROR: - handle_vchan_error("send(handle_input stdout)"); + if (!is_service && remote_status == -1) { + /* Even if sending fails, still try to read remaining + * data, if any - especially the exit code. But don't + * send anything anymore. + */ + LOG(ERROR, "Error while vchan send (handle_input stdout), reading remaining data"); + close_stdout(); + } else { + handle_vchan_error("send(handle_input stdout)"); + } break; case REMOTE_EOF: close_stdout();