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.
This commit is contained in:
Marek Marczykowski-Górecki 2017-06-21 06:45:13 +02:00
parent ea0cd0fdc3
commit 6bddcfcb52
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724

View File

@ -237,8 +237,9 @@ 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)
if (!child_process_pid || stdin_fd == 1 ||
(shutdown(stdin_fd, SHUT_WR) == -1 &&
errno == ENOTSOCK)) {
close(stdin_fd);
}
stdin_fd = -1;
@ -251,8 +252,9 @@ 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)
if (!child_process_pid || stdin_fd == 1 ||
(shutdown(stdin_fd, SHUT_WR) == -1 &&
errno == ENOTSOCK)) {
close(stdin_fd);
}
stdin_fd = -1;
@ -317,8 +319,9 @@ 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)
if (!child_process_pid || stdin_fd == 1 ||
(shutdown(stdin_fd, SHUT_WR) == -1 &&
errno == ENOTSOCK)) {
close(stdin_fd);
}
stdin_fd = -1;
@ -409,9 +412,11 @@ 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)
/* 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;
@ -448,8 +453,9 @@ 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)
/* 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;
@ -457,8 +463,9 @@ int process_child_io(libvchan_t *data_vchan,
if (stdin_fd != -1) {
/* restore flags */
set_block(stdin_fd);
if (shutdown(stdin_fd, SHUT_WR) < 0) {
if (errno == ENOTSOCK)
/* 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;