summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2023-01-18 02:00:11 +0000
committerDamien Miller <djm@cvs.openbsd.org>2023-01-18 02:00:11 +0000
commit66c13d32f204bf1986d88c6392d7fbcb9bee2d55 (patch)
tree5916a27cfac95a76d79006f0d1b4c1320e279134
parent96d8a33498d20069aceabb592269cf70dee4b994 (diff)
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@
-rw-r--r--usr.bin/ssh/channels.c19
-rw-r--r--usr.bin/ssh/channels.h3
2 files changed, 16 insertions, 6 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index c7b4c2a235e..3153dab8527 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/channels.c
@@ -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
@@ -405,16 +405,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);
}
@@ -498,10 +501,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;
diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h
index 8d4699a6a53..853ac98b857 100644
--- a/usr.bin/ssh/channels.h
+++ b/usr.bin/ssh/channels.h
@@ -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>
@@ -150,6 +150,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