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,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;
}