Skip to content

Commit 6bddcfc

Browse files
committed
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.
1 parent ea0cd0f commit 6bddcfc

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

qrexec/qrexec-agent-data.c

+26-19
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,10 @@ int handle_remote_data(libvchan_t *data_vchan, int stdin_fd, int *status,
237237
if (hdr.len == 0) {
238238
/* restore flags */
239239
set_block(stdin_fd);
240-
if (shutdown(stdin_fd, SHUT_WR) < 0) {
241-
if (errno == ENOTSOCK)
242-
close(stdin_fd);
240+
if (!child_process_pid || stdin_fd == 1 ||
241+
(shutdown(stdin_fd, SHUT_WR) == -1 &&
242+
errno == ENOTSOCK)) {
243+
close(stdin_fd);
243244
}
244245
stdin_fd = -1;
245246
return 0;
@@ -251,9 +252,10 @@ int handle_remote_data(libvchan_t *data_vchan, int stdin_fd, int *status,
251252
return 1;
252253
case WRITE_STDIN_ERROR:
253254
if (errno == EPIPE || errno == ECONNRESET) {
254-
if (shutdown(stdin_fd, SHUT_WR) < 0) {
255-
if (errno == ENOTSOCK)
256-
close(stdin_fd);
255+
if (!child_process_pid || stdin_fd == 1 ||
256+
(shutdown(stdin_fd, SHUT_WR) == -1 &&
257+
errno == ENOTSOCK)) {
258+
close(stdin_fd);
257259
}
258260
stdin_fd = -1;
259261
} else {
@@ -317,9 +319,10 @@ int process_child_io(libvchan_t *data_vchan,
317319
if (stdin_fd >= 0) {
318320
/* restore flags */
319321
set_block(stdin_fd);
320-
if (shutdown(stdin_fd, SHUT_WR) < 0) {
321-
if (errno == ENOTSOCK)
322-
close(stdin_fd);
322+
if (!child_process_pid || stdin_fd == 1 ||
323+
(shutdown(stdin_fd, SHUT_WR) == -1 &&
324+
errno == ENOTSOCK)) {
325+
close(stdin_fd);
323326
}
324327
stdin_fd = -1;
325328
}
@@ -409,10 +412,12 @@ int process_child_io(libvchan_t *data_vchan,
409412
stdin_fd = -1;
410413
break;
411414
case -2:
412-
/* remote process exited, no sense in sending more data to it */
413-
if (shutdown(stdout_fd, SHUT_RD) < 0) {
414-
if (errno == ENOTSOCK)
415-
close(stdout_fd);
415+
/* remote process exited, no sense in sending more data to it;
416+
* be careful to not shutdown socket inherited from parent */
417+
if (!child_process_pid || stdout_fd == 0 ||
418+
(shutdown(stdout_fd, SHUT_RD) == -1 &&
419+
errno == ENOTSOCK)) {
420+
close(stdout_fd);
416421
}
417422
stdout_fd = -1;
418423
close(stderr_fd);
@@ -448,18 +453,20 @@ int process_child_io(libvchan_t *data_vchan,
448453
if (stdout_fd != -1) {
449454
/* restore flags */
450455
set_block(stdout_fd);
451-
if (shutdown(stdout_fd, SHUT_RD) < 0) {
452-
if (errno == ENOTSOCK)
453-
close(stdout_fd);
456+
/* be careful to not shutdown socket inherited from parent */
457+
if (!child_process_pid || stdout_fd == 0 ||
458+
(shutdown(stdout_fd, SHUT_RD) == -1 && errno == ENOTSOCK)) {
459+
close(stdout_fd);
454460
}
455461
stdout_fd = -1;
456462
}
457463
if (stdin_fd != -1) {
458464
/* restore flags */
459465
set_block(stdin_fd);
460-
if (shutdown(stdin_fd, SHUT_WR) < 0) {
461-
if (errno == ENOTSOCK)
462-
close(stdin_fd);
466+
/* be careful to not shutdown socket inherited from parent */
467+
if (!child_process_pid || stdin_fd == 1 ||
468+
(shutdown(stdin_fd, SHUT_WR) == -1 && errno == ENOTSOCK)) {
469+
close(stdin_fd);
463470
}
464471
stdin_fd = -1;
465472
}

0 commit comments

Comments
 (0)