From 70403e5bccb43d8b04c5c0a1596fb00cdfd24a0e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 13 Jul 2021 04:20:55 +0000 Subject: [PATCH] import openssh-8.0p1-10.el8 --- SOURCES/openssh-6.7p1-coverity.patch | 52 ++- SOURCES/openssh-8.0p1-restore-nonblock.patch | 334 +++++++++++-------- SOURCES/openssh-8.0p1-sshd_config.patch | 97 ++++++ SPECS/openssh.spec | 8 +- 4 files changed, 331 insertions(+), 160 deletions(-) create mode 100644 SOURCES/openssh-8.0p1-sshd_config.patch diff --git a/SOURCES/openssh-6.7p1-coverity.patch b/SOURCES/openssh-6.7p1-coverity.patch index 1d0bf27..0159482 100644 --- a/SOURCES/openssh-6.7p1-coverity.patch +++ b/SOURCES/openssh-6.7p1-coverity.patch @@ -1,31 +1,29 @@ diff -up openssh-8.0p1/channels.c.coverity openssh-8.0p1/channels.c ---- openssh-8.0p1/channels.c.coverity 2021-04-26 11:49:58.725597484 +0200 -+++ openssh-8.0p1/channels.c 2021-04-26 12:03:17.756004774 +0200 -@@ -338,17 +338,17 @@ channel_register_fds(struct ssh *ssh, Ch - c->wfd_isatty = is_tty || isatty(c->wfd); - #endif - -- if (rfd != -1) { -+ if (rfd >= 0) { - if ((fcntl(rfd, F_GETFL) & O_NONBLOCK) == 0) - c->nonblock |= NEED_RESTORE_STDIN_NONBLOCK; - channel_register_fd(ssh, rfd, nonblock); - } -- if (wfd != -1 && wfd != rfd) { -+ if (wfd >= 0 && wfd != rfd) { - if ((fcntl(wfd, F_GETFL) & O_NONBLOCK) == 0) - c->nonblock |= NEED_RESTORE_STDOUT_NONBLOCK; - channel_register_fd(ssh, wfd, nonblock); - } -- if (efd != -1 && efd != rfd && efd != wfd) { -+ if (efd >= 0 && efd != rfd && efd != wfd) { - if ((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0) - c->nonblock |= NEED_RESTORE_STDERR_NONBLOCK; - channel_register_fd(ssh, efd, nonblock); -diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100 -@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx +--- openssh-8.0p1/channels.c.coverity 2021-06-21 10:59:17.297473319 +0200 ++++ openssh-8.0p1/channels.c 2021-06-21 11:11:32.467290400 +0200 +@@ -341,15 +341,15 @@ channel_register_fds(struct ssh *ssh, Ch + * restore their blocking state on exit to avoid interfering + * with other programs that follow. + */ +- if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) { ++ if (rfd >= 0 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) { + c->restore_block |= CHANNEL_RESTORE_RFD; + set_nonblock(rfd); + } +- if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) { ++ if (wfd >= 0 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) { + c->restore_block |= CHANNEL_RESTORE_WFD; + set_nonblock(wfd); + } +- if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) { ++ if (efd >= 0 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) { + c->restore_block |= CHANNEL_RESTORE_EFD; + set_nonblock(efd); + } +diff -up openssh-8.0p1/monitor.c.coverity openssh-8.0p1/monitor.c +--- openssh-8.0p1/monitor.c.coverity 2021-06-21 10:59:17.282473202 +0200 ++++ openssh-8.0p1/monitor.c 2021-06-21 10:59:17.297473319 +0200 +@@ -401,7 +401,7 @@ monitor_child_preauth(struct ssh *ssh, s mm_get_keystate(ssh, pmonitor); /* Drain any buffered messages from the child */ diff --git a/SOURCES/openssh-8.0p1-restore-nonblock.patch b/SOURCES/openssh-8.0p1-restore-nonblock.patch index cff647e..b16e17e 100644 --- a/SOURCES/openssh-8.0p1-restore-nonblock.patch +++ b/SOURCES/openssh-8.0p1-restore-nonblock.patch @@ -1,196 +1,256 @@ diff -up openssh-8.0p1/channels.c.restore-nonblock openssh-8.0p1/channels.c ---- openssh-8.0p1/channels.c.restore-nonblock 2021-04-26 11:31:44.037740711 +0200 -+++ openssh-8.0p1/channels.c 2021-04-26 11:43:48.429606396 +0200 -@@ -298,32 +298,38 @@ channel_lookup(struct ssh *ssh, int id) - } - - /* -- * Register filedescriptors for a channel, used when allocating a channel or -- * when the channel consumer/producer is ready, e.g. shell exec'd -+ * Register a filedescriptor. - */ - static void --channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, -- int extusage, int nonblock, int is_tty) -+channel_register_fd(struct ssh *ssh, int fd, int nonblock) - { - struct ssh_channels *sc = ssh->chanctxt; - - /* Update the maximum file descriptor value. */ -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd); -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, wfd); -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, efd); -- -- if (rfd != -1) -- fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -- fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -- fcntl(efd, F_SETFD, FD_CLOEXEC); -+ sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, fd); -+ -+ if (fd != -1) -+ fcntl(fd, F_SETFD, FD_CLOEXEC); - -+ /* enable nonblocking mode */ -+ if (nonblock && fd != -1 && !isatty(fd)) -+ set_nonblock(fd); -+} -+ -+/* -+ * Register filedescriptors for a channel, used when allocating a channel or -+ * when the channel consumer/producer is ready, e.g. shell exec'd -+ */ -+static void -+channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, -+ int extusage, int nonblock, int is_tty) -+{ - c->rfd = rfd; - c->wfd = wfd; - c->sock = (rfd == wfd) ? rfd : -1; - c->efd = efd; - c->extended_usage = extusage; -+ c->nonblock = 0; - - if ((c->isatty = is_tty) != 0) - debug2("channel %d: rfd %d isatty", c->self, c->rfd); -@@ -332,14 +338,20 @@ channel_register_fds(struct ssh *ssh, Ch - c->wfd_isatty = is_tty || isatty(c->wfd); +--- openssh-8.0p1/channels.c.restore-nonblock 2021-06-21 10:44:26.380559612 +0200 ++++ openssh-8.0p1/channels.c 2021-06-21 10:48:47.754579151 +0200 +@@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Ch #endif -- /* enable nonblocking mode */ + /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -- set_nonblock(rfd); -- if (wfd != -1) -- set_nonblock(wfd); -- if (efd != -1) -- set_nonblock(efd); -+ if (rfd != -1) { -+ if ((fcntl(rfd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDIN_NONBLOCK; -+ channel_register_fd(ssh, rfd, nonblock); -+ } -+ if (wfd != -1 && wfd != rfd) { -+ if ((fcntl(wfd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDOUT_NONBLOCK; -+ channel_register_fd(ssh, wfd, nonblock); -+ } -+ if (efd != -1 && efd != rfd && efd != wfd) { -+ if ((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDERR_NONBLOCK; -+ channel_register_fd(ssh, efd, nonblock); - } - } - -@@ -422,11 +434,15 @@ channel_find_maxfd(struct ssh_channels * ++ c->restore_block = 0; ++ if (nonblock == CHANNEL_NONBLOCK_STDIO) { ++ /* ++ * Special handling for stdio file descriptors: do not set ++ * non-blocking mode if they are TTYs. Otherwise prepare to ++ * restore their blocking state on exit to avoid interfering ++ * with other programs that follow. ++ */ ++ if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_RFD; ++ set_nonblock(rfd); ++ } ++ if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_WFD; ++ set_nonblock(wfd); ++ } ++ if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_EFD; ++ set_nonblock(efd); ++ } ++ } else if (nonblock) { + if (rfd != -1) + set_nonblock(rfd); + if (wfd != -1) +@@ -422,17 +442,23 @@ channel_find_maxfd(struct ssh_channels * } int -channel_close_fd(struct ssh *ssh, int *fdp) -+channel_close_fd(struct ssh *ssh, int *fdp, int nonblock) ++channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) { struct ssh_channels *sc = ssh->chanctxt; - int ret = 0, fd = *fdp; +- int ret = 0, fd = *fdp; ++ int ret, fd = *fdp; -+ /* As the fd is duped, restoring the block mode -+ * affects the original fd */ -+ if (nonblock && fd != -1 && !isatty(fd)) -+ unset_nonblock(fd); - if (fd != -1) { - ret = close(fd); - *fdp = -1; -@@ -442,13 +458,13 @@ channel_close_fds(struct ssh *ssh, Chann +- if (fd != -1) { +- ret = close(fd); +- *fdp = -1; +- if (fd == sc->channel_max_fd) +- channel_find_maxfd(sc); +- } ++ 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 */ ++ ++ ret = close(fd); ++ *fdp = -1; ++ if (fd == sc->channel_max_fd) ++ channel_find_maxfd(sc); + return ret; + } + +@@ -442,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Chann { int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); if (rfd != sock) - channel_close_fd(ssh, &c->rfd); -+ channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK); ++ channel_close_fd(ssh, c, &c->rfd); if (wfd != sock && wfd != rfd) - channel_close_fd(ssh, &c->wfd); -+ channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK); ++ channel_close_fd(ssh, c, &c->wfd); if (efd != sock && efd != rfd && efd != wfd) - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } static void -@@ -681,7 +697,7 @@ channel_stop_listening(struct ssh *ssh) +@@ -681,7 +707,7 @@ channel_stop_listening(struct ssh *ssh) case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); channel_free(ssh, c); break; } -@@ -1650,7 +1666,7 @@ channel_post_x11_listener(struct ssh *ss +@@ -1487,7 +1513,8 @@ channel_decode_socks5(Channel *c, struct + + Channel * + channel_connect_stdio_fwd(struct ssh *ssh, +- const char *host_to_connect, u_short port_to_connect, int in, int out) ++ const char *host_to_connect, u_short port_to_connect, ++ int in, int out, int nonblock) + { + Channel *c; + +@@ -1495,7 +1522,7 @@ channel_connect_stdio_fwd(struct ssh *ss + + c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, + -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, +- 0, "stdio-forward", /*nonblock*/0); ++ 0, "stdio-forward", nonblock); + + c->path = xstrdup(host_to_connect); + c->host_port = port_to_connect; +@@ -1650,7 +1677,7 @@ channel_post_x11_listener(struct ssh *ss if (c->single_connection) { oerrno = errno; debug2("single_connection: closing X11 listener."); - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); chan_mark_dead(ssh, c); errno = oerrno; } -@@ -2087,7 +2103,7 @@ channel_handle_efd_write(struct ssh *ssh +@@ -2087,7 +2114,7 @@ channel_handle_efd_write(struct ssh *ssh return 1; if (len <= 0) { debug2("channel %d: closing write-efd %d", c->self, c->efd); - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } else { if ((r = sshbuf_consume(c->extended, len)) != 0) { fatal("%s: channel %d: consume: %s", -@@ -2119,7 +2135,7 @@ channel_handle_efd_read(struct ssh *ssh, +@@ -2119,7 +2146,7 @@ channel_handle_efd_read(struct ssh *ssh, if (len <= 0) { debug2("channel %d: closing read-efd %d", c->self, c->efd); - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } else { if (c->extended_usage == CHAN_EXTENDED_IGNORE) { debug3("channel %d: discard efd", diff -up openssh-8.0p1/channels.h.restore-nonblock openssh-8.0p1/channels.h ---- openssh-8.0p1/channels.h.restore-nonblock 2021-04-26 11:31:44.038740719 +0200 -+++ openssh-8.0p1/channels.h 2021-04-26 11:38:18.151932008 +0200 -@@ -180,8 +180,15 @@ struct Channel { - void *mux_ctx; - int mux_pause; - int mux_downstream_id; -+ -+ /* whether non-blocking is set to descriptors */ -+ int nonblock; - }; +--- openssh-8.0p1/channels.h.restore-nonblock 2021-06-21 10:44:26.380559612 +0200 ++++ openssh-8.0p1/channels.h 2021-06-21 10:44:26.387559665 +0200 +@@ -63,6 +63,16 @@ -+#define NEED_RESTORE_STDIN_NONBLOCK 1 -+#define NEED_RESTORE_STDOUT_NONBLOCK 2 -+#define NEED_RESTORE_STDERR_NONBLOCK 4 + #define CHANNEL_CANCEL_PORT_STATIC -1 + ++/* nonblocking flags for channel_new */ ++#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */ ++#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */ ++#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */ + - #define CHAN_EXTENDED_IGNORE 0 - #define CHAN_EXTENDED_READ 1 - #define CHAN_EXTENDED_WRITE 2 -@@ -258,7 +265,7 @@ void channel_register_filter(struct ssh ++/* c->restore_block mask flags */ ++#define CHANNEL_RESTORE_RFD 0x01 ++#define CHANNEL_RESTORE_WFD 0x02 ++#define CHANNEL_RESTORE_EFD 0x04 ++ + /* TCP forwarding */ + #define FORWARD_DENY 0 + #define FORWARD_REMOTE (1) +@@ -131,6 +141,7 @@ struct Channel { + * to a matching pre-select handler. + * this way post-select handlers are not + * accidentally called if a FD gets reused */ ++ int restore_block; /* fd mask to restore blocking status */ + struct sshbuf *input; /* data read from socket, to be sent over + * encrypted connection */ + struct sshbuf *output; /* data received over encrypted connection for +@@ -258,7 +269,7 @@ void channel_register_filter(struct ssh void channel_register_status_confirm(struct ssh *, int, channel_confirm_cb *, channel_confirm_abandon_cb *, void *); void channel_cancel_cleanup(struct ssh *, int); -int channel_close_fd(struct ssh *, int *); -+int channel_close_fd(struct ssh *, int *, int); ++int channel_close_fd(struct ssh *, Channel *, int *); void channel_send_window_changes(struct ssh *); /* mux proxy support */ +@@ -305,7 +316,7 @@ Channel *channel_connect_to_port(struct + char *, char *, int *, const char **); + Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *); + Channel *channel_connect_stdio_fwd(struct ssh *, const char*, +- u_short, int, int); ++ u_short, int, int, int); + Channel *channel_connect_by_listen_address(struct ssh *, const char *, + u_short, char *, char *); + Channel *channel_connect_by_listen_path(struct ssh *, const char *, +diff -up openssh-8.0p1/clientloop.c.restore-nonblock openssh-8.0p1/clientloop.c +--- openssh-8.0p1/clientloop.c.restore-nonblock 2021-06-21 10:44:26.290558923 +0200 ++++ openssh-8.0p1/clientloop.c 2021-06-21 10:44:26.387559665 +0200 +@@ -1436,14 +1436,6 @@ client_loop(struct ssh *ssh, int have_pt + if (have_pty) + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); + +- /* restore blocking io */ +- if (!isatty(fileno(stdin))) +- unset_nonblock(fileno(stdin)); +- if (!isatty(fileno(stdout))) +- unset_nonblock(fileno(stdout)); +- if (!isatty(fileno(stderr))) +- unset_nonblock(fileno(stderr)); +- + /* + * If there was no shell or command requested, there will be no remote + * exit status to be returned. In that case, clear error code if the +diff -up openssh-8.0p1/mux.c.restore-nonblock openssh-8.0p1/mux.c +--- openssh-8.0p1/mux.c.restore-nonblock 2019-04-18 00:52:57.000000000 +0200 ++++ openssh-8.0p1/mux.c 2021-06-21 10:50:51.007537336 +0200 +@@ -454,14 +454,6 @@ mux_master_process_new_session(struct ss + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error("%s: tcgetattr: %s", __func__, strerror(errno)); + +- /* enable nonblocking unless tty */ +- if (!isatty(new_fd[0])) +- set_nonblock(new_fd[0]); +- if (!isatty(new_fd[1])) +- set_nonblock(new_fd[1]); +- if (!isatty(new_fd[2])) +- set_nonblock(new_fd[2]); +- + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (cctx->want_tty) { +@@ -471,7 +463,7 @@ mux_master_process_new_session(struct ss + + nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], window, packetmax, +- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); ++ CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); + + nc->ctl_chan = c->self; /* link session -> control channel */ + c->remote_id = nc->self; /* link control -> session channel */ +@@ -1033,13 +1025,8 @@ mux_master_process_stdio_fwd(struct ssh + } + } + +- /* enable nonblocking unless tty */ +- if (!isatty(new_fd[0])) +- set_nonblock(new_fd[0]); +- if (!isatty(new_fd[1])) +- set_nonblock(new_fd[1]); +- +- nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); ++ nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1], ++ CHANNEL_NONBLOCK_STDIO); + free(chost); + + nc->ctl_chan = c->self; /* link session -> control channel */ diff -up openssh-8.0p1/nchan.c.restore-nonblock openssh-8.0p1/nchan.c ---- openssh-8.0p1/nchan.c.restore-nonblock 2021-04-26 11:31:44.047740792 +0200 -+++ openssh-8.0p1/nchan.c 2021-04-26 11:42:33.636000753 +0200 +--- openssh-8.0p1/nchan.c.restore-nonblock 2021-06-21 10:44:26.388559673 +0200 ++++ openssh-8.0p1/nchan.c 2021-06-21 10:52:42.685405537 +0200 @@ -387,7 +387,7 @@ chan_shutdown_write(struct ssh *ssh, Cha strerror(errno)); } } else { - if (channel_close_fd(ssh, &c->wfd) < 0) { -+ if (channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->wfd) < 0) { logit("channel %d: %s: close() failed for " "fd %d [i%d o%d]: %.100s", c->self, __func__, c->wfd, c->istate, c->ostate, @@ -199,7 +259,7 @@ diff -up openssh-8.0p1/nchan.c.restore-nonblock openssh-8.0p1/nchan.c } } else { - if (channel_close_fd(ssh, &c->rfd) < 0) { -+ if (channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->rfd) < 0) { logit("channel %d: %s: close() failed for " "fd %d [i%d o%d]: %.100s", c->self, __func__, c->rfd, c->istate, c->ostate, @@ -208,14 +268,24 @@ diff -up openssh-8.0p1/nchan.c.restore-nonblock openssh-8.0p1/nchan.c c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd, channel_format_extended_usage(c)); - if (channel_close_fd(ssh, &c->efd) < 0) { -+ if (channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->efd) < 0) { logit("channel %d: %s: close() failed for " "extended fd %d [i%d o%d]: %.100s", c->self, __func__, c->efd, c->istate, c->ostate, diff -up openssh-8.0p1/ssh.c.restore-nonblock openssh-8.0p1/ssh.c ---- openssh-8.0p1/ssh.c.restore-nonblock 2021-04-26 11:31:44.047740792 +0200 -+++ openssh-8.0p1/ssh.c 2021-04-26 11:39:58.081741180 +0200 -@@ -1862,14 +1862,6 @@ ssh_session2_open(struct ssh *ssh) +--- openssh-8.0p1/ssh.c.restore-nonblock 2021-06-21 10:44:26.389559681 +0200 ++++ openssh-8.0p1/ssh.c 2021-06-21 10:54:47.651377045 +0200 +@@ -1709,7 +1709,8 @@ ssh_init_stdio_forwarding(struct ssh *ss + (out = dup(STDOUT_FILENO)) < 0) + fatal("channel_connect_stdio_fwd: dup() in/out failed"); + if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host, +- options.stdio_forward_port, in, out)) == NULL) ++ options.stdio_forward_port, in, out, ++ CHANNEL_NONBLOCK_STDIO)) == NULL) + fatal("%s: channel_connect_stdio_fwd failed", __func__); + channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); + channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); +@@ -1862,14 +1863,6 @@ ssh_session2_open(struct ssh *ssh) if (in < 0 || out < 0 || err < 0) fatal("dup() in/out/err failed"); @@ -230,12 +300,12 @@ diff -up openssh-8.0p1/ssh.c.restore-nonblock openssh-8.0p1/ssh.c window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { -@@ -1879,7 +1871,7 @@ ssh_session2_open(struct ssh *ssh) +@@ -1879,7 +1872,7 @@ ssh_session2_open(struct ssh *ssh) c = channel_new(ssh, "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, - "client-session", /*nonblock*/0); -+ "client-session", /*nonblock*/1); ++ "client-session", CHANNEL_NONBLOCK_STDIO); debug3("%s: channel_new: %d", __func__, c->self); diff --git a/SOURCES/openssh-8.0p1-sshd_config.patch b/SOURCES/openssh-8.0p1-sshd_config.patch new file mode 100644 index 0000000..e4b7912 --- /dev/null +++ b/SOURCES/openssh-8.0p1-sshd_config.patch @@ -0,0 +1,97 @@ +diff --git a/servconf.c b/servconf.c +index ffac5d2c..340045b2 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1042,7 +1042,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + return -1; + } + if (strcasecmp(attrib, "user") == 0) { +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->user == NULL)) { + result = 0; + continue; + } +@@ -1054,7 +1054,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + debug("user %.100s matched 'User %.100s' at " + "line %d", ci->user, arg, line); + } else if (strcasecmp(attrib, "group") == 0) { +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->user == NULL)) { + result = 0; + continue; + } +@@ -1067,7 +1067,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + result = 0; + } + } else if (strcasecmp(attrib, "host") == 0) { +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->host == NULL)) { + result = 0; + continue; + } +@@ -1079,7 +1079,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + debug("connection from %.100s matched 'Host " + "%.100s' at line %d", ci->host, arg, line); + } else if (strcasecmp(attrib, "address") == 0) { +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->address == NULL)) { + result = 0; + continue; + } +@@ -1098,7 +1098,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + return -1; + } + } else if (strcasecmp(attrib, "localaddress") == 0){ +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->laddress == NULL)) { + result = 0; + continue; + } +@@ -1124,7 +1124,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + arg); + return -1; + } +- if (ci == NULL) { ++ if (ci == NULL || (ci->test && ci->lport == -1)) { + result = 0; + continue; + } +@@ -1138,10 +1138,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) + else + result = 0; + } else if (strcasecmp(attrib, "rdomain") == 0) { +- if (ci == NULL || ci->rdomain == NULL) { ++ if (ci == NULL || (ci->test && ci->rdomain == NULL)) { + result = 0; + continue; + } ++ if (ci->rdomain == NULL) ++ match_test_missing_fatal("RDomain", "rdomain"); + if (match_pattern_list(ci->rdomain, arg, 0) != 1) + result = 0; + else +diff --git a/servconf.h b/servconf.h +index 54e0a8d8..5483da05 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -221,6 +221,8 @@ struct connection_info { + const char *laddress; /* local address */ + int lport; /* local port */ + const char *rdomain; /* routing domain if available */ ++ int test; /* test mode, allow some attributes to be ++ * unspecified */ + }; + + +diff --git a/sshd.c b/sshd.c +index cbd3bce9..1fcde502 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1843,6 +1843,7 @@ main(int ac, char **av) + */ + if (connection_info == NULL) + connection_info = get_connection_info(ssh, 0, 0); ++ connection_info->test = 1; + parse_server_match_config(&options, connection_info); + dump_config(&options); + } diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec index a955991..ab3b01e 100644 --- a/SPECS/openssh.spec +++ b/SPECS/openssh.spec @@ -66,7 +66,7 @@ # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 %global openssh_ver 8.0p1 -%global openssh_rel 9 +%global openssh_rel 10 %global pam_ssh_agent_ver 0.10.3 %global pam_ssh_agent_rel 7 @@ -243,6 +243,8 @@ Patch975: openssh-8.0p1-preserve-pam-errors.patch Patch976: openssh-8.0p1-restore-nonblock.patch # CVE 2020-14145 Patch977: openssh-8.0p1-cve-2020-14145.patch +# sshd -T requires -C when "Match" is used in sshd_config (#1836277) +Patch978: openssh-8.0p1-sshd_config.patch License: BSD Group: Applications/Internet @@ -467,6 +469,7 @@ popd %patch975 -p1 -b .preserve-pam-errors %patch976 -p1 -b .restore-nonblock %patch977 -p1 -b .cve-2020-14145 +%patch978 -p1 -b .sshd_config %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -758,6 +761,9 @@ getent passwd sshd >/dev/null || \ %endif %changelog +* Mon Jun 21 2021 Dmitry Belyavskiy - 8.0p1-10 +- sshd -T requires -C when "Match" is used in sshd_config (#1836277) + * Wed Jun 02 2021 Dmitry Belyavskiy - 8.0p1-9 - CVE-2020-14145 openssh: Observable Discrepancy leading to an information leak in the algorithm negotiation (#1882252)