From 6bddcfcb523a01b99408bccce1a80acb33bce4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 21 Jun 2017 06:45:13 +0200 Subject: [PATCH] qrexec: do not shutdown stdout socket inherited from parent When qrexec-client-vm is started with socket on its stdout and no local process requested, it will try to shutdown(SHUT_WR) this socket when remote process exists. This is wrong, because this socket may be still needed by other processes (for example shell from where qrexec-client-vm was called). In such a case, simple close() should be used. --- qrexec/qrexec-agent-data.c | 45 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/qrexec/qrexec-agent-data.c b/qrexec/qrexec-agent-data.c index 89ff084..e2fe134 100644 --- a/qrexec/qrexec-agent-data.c +++ b/qrexec/qrexec-agent-data.c @@ -237,9 +237,10 @@ int handle_remote_data(libvchan_t *data_vchan, int stdin_fd, int *status, if (hdr.len == 0) { /* restore flags */ set_block(stdin_fd); - if (shutdown(stdin_fd, SHUT_WR) < 0) { - if (errno == ENOTSOCK) - close(stdin_fd); + if (!child_process_pid || stdin_fd == 1 || + (shutdown(stdin_fd, SHUT_WR) == -1 && + errno == ENOTSOCK)) { + close(stdin_fd); } stdin_fd = -1; return 0; @@ -251,9 +252,10 @@ int handle_remote_data(libvchan_t *data_vchan, int stdin_fd, int *status, return 1; case WRITE_STDIN_ERROR: if (errno == EPIPE || errno == ECONNRESET) { - if (shutdown(stdin_fd, SHUT_WR) < 0) { - if (errno == ENOTSOCK) - close(stdin_fd); + if (!child_process_pid || stdin_fd == 1 || + (shutdown(stdin_fd, SHUT_WR) == -1 && + errno == ENOTSOCK)) { + close(stdin_fd); } stdin_fd = -1; } else { @@ -317,9 +319,10 @@ int process_child_io(libvchan_t *data_vchan, if (stdin_fd >= 0) { /* restore flags */ set_block(stdin_fd); - if (shutdown(stdin_fd, SHUT_WR) < 0) { - if (errno == ENOTSOCK) - close(stdin_fd); + if (!child_process_pid || stdin_fd == 1 || + (shutdown(stdin_fd, SHUT_WR) == -1 && + errno == ENOTSOCK)) { + close(stdin_fd); } stdin_fd = -1; } @@ -409,10 +412,12 @@ int process_child_io(libvchan_t *data_vchan, stdin_fd = -1; break; case -2: - /* remote process exited, no sense in sending more data to it */ - if (shutdown(stdout_fd, SHUT_RD) < 0) { - if (errno == ENOTSOCK) - close(stdout_fd); + /* remote process exited, no sense in sending more data to it; + * be careful to not shutdown socket inherited from parent */ + if (!child_process_pid || stdout_fd == 0 || + (shutdown(stdout_fd, SHUT_RD) == -1 && + errno == ENOTSOCK)) { + close(stdout_fd); } stdout_fd = -1; close(stderr_fd); @@ -448,18 +453,20 @@ int process_child_io(libvchan_t *data_vchan, if (stdout_fd != -1) { /* restore flags */ set_block(stdout_fd); - if (shutdown(stdout_fd, SHUT_RD) < 0) { - if (errno == ENOTSOCK) - close(stdout_fd); + /* be careful to not shutdown socket inherited from parent */ + if (!child_process_pid || stdout_fd == 0 || + (shutdown(stdout_fd, SHUT_RD) == -1 && errno == ENOTSOCK)) { + close(stdout_fd); } stdout_fd = -1; } if (stdin_fd != -1) { /* restore flags */ set_block(stdin_fd); - if (shutdown(stdin_fd, SHUT_WR) < 0) { - if (errno == ENOTSOCK) - close(stdin_fd); + /* be careful to not shutdown socket inherited from parent */ + if (!child_process_pid || stdin_fd == 1 || + (shutdown(stdin_fd, SHUT_WR) == -1 && errno == ENOTSOCK)) { + close(stdin_fd); } stdin_fd = -1; }