diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2023-01-18 02:00:11 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2023-01-18 02:00:11 +0000 |
commit | 66c13d32f204bf1986d88c6392d7fbcb9bee2d55 (patch) | |
tree | 5916a27cfac95a76d79006f0d1b4c1320e279134 | |
parent | 96d8a33498d20069aceabb592269cf70dee4b994 (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.c | 19 | ||||
-rw-r--r-- | usr.bin/ssh/channels.h | 3 |
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 |