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
This commit is contained in:
djm@openbsd.org 2023-01-18 02:00:10 +00:00 committed by Damien Miller
parent 7d17ea151c
commit 35253af01d
No known key found for this signature in database
2 changed files with 16 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.426 2023/01/06 02:47:18 djm Exp $ */
/* $OpenBSD: channels.c,v 1.427 2023/01/18 02:00:10 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -417,16 +417,19 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
*/
if (rfd != -1 && !isatty(rfd) &&
(val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
c->restore_flags[0] = val;
c->restore_block |= CHANNEL_RESTORE_RFD;
set_nonblock(rfd);
}
if (wfd != -1 && !isatty(wfd) &&
(val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
c->restore_flags[1] = val;
c->restore_block |= CHANNEL_RESTORE_WFD;
set_nonblock(wfd);
}
if (efd != -1 && !isatty(efd) &&
(val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
c->restore_flags[2] = val;
c->restore_block |= CHANNEL_RESTORE_EFD;
set_nonblock(efd);
}
@ -510,10 +513,16 @@ channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
if (fd == -1)
return 0;
if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
(*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
(*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
(void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */
/* restore blocking */
if (*fdp == c->rfd &&
(c->restore_block & CHANNEL_RESTORE_RFD) != 0)
(void)fcntl(*fdp, F_SETFL, c->restore_flags[0]);
else if (*fdp == c->wfd &&
(c->restore_block & CHANNEL_RESTORE_WFD) != 0)
(void)fcntl(*fdp, F_SETFL, c->restore_flags[1]);
else if (*fdp == c->efd &&
(c->restore_block & CHANNEL_RESTORE_EFD) != 0)
(void)fcntl(*fdp, F_SETFL, c->restore_flags[2]);
if (*fdp == c->rfd) {
c->io_want &= ~SSH_CHAN_IO_RFD;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.147 2023/01/06 02:47:18 djm Exp $ */
/* $OpenBSD: channels.h,v 1.148 2023/01/18 02:00:10 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -153,6 +153,7 @@ struct Channel {
* this way post-IO handlers are not
* accidentally called if a FD gets reused */
int restore_block; /* fd mask to restore blocking status */
int restore_flags[3];/* flags to restore */
struct sshbuf *input; /* data read from socket, to be sent over
* encrypted connection */
struct sshbuf *output; /* data received over encrypted connection for