]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: when restoring non-blocking mode to stdio fds, restore
authordjm@openbsd.org <djm@openbsd.org>
Wed, 18 Jan 2023 02:00:10 +0000 (02:00 +0000)
committerDamien Miller <djm@mindrot.org>
Wed, 18 Jan 2023 02:21:00 +0000 (13:21 +1100)
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

channels.c
channels.h

index 981746ebd6ec798c132e87bcfc48f6212c7f996e..0d26358cc65e4ac4d2bf55970f2deec5ed1a2f98 100644 (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;
index c80b55d0c7c4344905db2bc7dc25816061372b50..101843a06d15998b06efbdf32f586ea967f43c86 100644 (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