Skip to content

Commit 35253af

Browse files
committed
upstream: when restoring non-blocking mode to stdio fds, restore
exactly the flags that ssh started with and don't just clobber them with zero, as this could also remove the append flag from the set; bz3523; ok dtucker@ OpenBSD-Commit-ID: 1336b03e881db7564a4b66014eb24c5230e9a0c0
1 parent 7d17ea1 commit 35253af

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

channels.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: channels.c,v 1.426 2023/01/06 02:47:18 djm Exp $ */
1+
/* $OpenBSD: channels.c,v 1.427 2023/01/18 02:00:10 djm Exp $ */
22
/*
33
* Author: Tatu Ylonen <[email protected]>
44
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
@@ -417,16 +417,19 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
417417
*/
418418
if (rfd != -1 && !isatty(rfd) &&
419419
(val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
420+
c->restore_flags[0] = val;
420421
c->restore_block |= CHANNEL_RESTORE_RFD;
421422
set_nonblock(rfd);
422423
}
423424
if (wfd != -1 && !isatty(wfd) &&
424425
(val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
426+
c->restore_flags[1] = val;
425427
c->restore_block |= CHANNEL_RESTORE_WFD;
426428
set_nonblock(wfd);
427429
}
428430
if (efd != -1 && !isatty(efd) &&
429431
(val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
432+
c->restore_flags[2] = val;
430433
c->restore_block |= CHANNEL_RESTORE_EFD;
431434
set_nonblock(efd);
432435
}
@@ -510,10 +513,16 @@ channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
510513
if (fd == -1)
511514
return 0;
512515

513-
if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
514-
(*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
515-
(*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
516-
(void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */
516+
/* restore blocking */
517+
if (*fdp == c->rfd &&
518+
(c->restore_block & CHANNEL_RESTORE_RFD) != 0)
519+
(void)fcntl(*fdp, F_SETFL, c->restore_flags[0]);
520+
else if (*fdp == c->wfd &&
521+
(c->restore_block & CHANNEL_RESTORE_WFD) != 0)
522+
(void)fcntl(*fdp, F_SETFL, c->restore_flags[1]);
523+
else if (*fdp == c->efd &&
524+
(c->restore_block & CHANNEL_RESTORE_EFD) != 0)
525+
(void)fcntl(*fdp, F_SETFL, c->restore_flags[2]);
517526

518527
if (*fdp == c->rfd) {
519528
c->io_want &= ~SSH_CHAN_IO_RFD;

channels.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: channels.h,v 1.147 2023/01/06 02:47:18 djm Exp $ */
1+
/* $OpenBSD: channels.h,v 1.148 2023/01/18 02:00:10 djm Exp $ */
22

33
/*
44
* Author: Tatu Ylonen <[email protected]>
@@ -153,6 +153,7 @@ struct Channel {
153153
* this way post-IO handlers are not
154154
* accidentally called if a FD gets reused */
155155
int restore_block; /* fd mask to restore blocking status */
156+
int restore_flags[3];/* flags to restore */
156157
struct sshbuf *input; /* data read from socket, to be sent over
157158
* encrypted connection */
158159
struct sshbuf *output; /* data received over encrypted connection for

0 commit comments

Comments
 (0)