diff --git a/SOURCES/openssh-6.7p1-coverity.patch b/SOURCES/openssh-6.7p1-coverity.patch
index 15d489d..0159482 100644
--- a/SOURCES/openssh-6.7p1-coverity.patch
+++ b/SOURCES/openssh-6.7p1-coverity.patch
@@ -1,25 +1,29 @@
-diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
---- openssh-7.4p1/channels.c.coverity	2016-12-23 16:40:26.881788686 +0100
-+++ openssh-7.4p1/channels.c	2016-12-23 16:42:36.244818763 +0100
-@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd
- 
- 	/* enable nonblocking mode */
- 	if (nonblock) {
--		if (rfd != -1)
-+		if (rfd >= 0)
+diff -up openssh-8.0p1/channels.c.coverity openssh-8.0p1/channels.c
+--- 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)
-+		if (wfd >= 0)
+ 		}
+-		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)
-+		if (efd >= 0)
+ 		}
+-		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-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
+ 		}
+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-7.7p1-fips.patch b/SOURCES/openssh-7.7p1-fips.patch
index 32091e3..2fb8200 100644
--- a/SOURCES/openssh-7.7p1-fips.patch
+++ b/SOURCES/openssh-7.7p1-fips.patch
@@ -296,17 +296,17 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
  #include "openbsd-compat/sys-queue.h"
  
  #include "xmalloc.h"
-@@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc
- 	for (i = 0; i < options.num_system_hostfiles; i++)
- 		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
- 
+@@ -148,7 +150,8 @@ order_hostkeyalgs(char *host, struct soc
+ 	 * Otherwise, prefer the host key algorithms that match known keys
+ 	 * while keeping the ordering of HostkeyAlgorithms as much as possible.
+ 	 */
 -	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
 +	oavail = avail = xstrdup((FIPS_mode()
 +	    ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG));
  	maxlen = strlen(avail) + 1;
  	first = xmalloc(maxlen);
  	last = xmalloc(maxlen);
-@@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho
+@@ -229,14 +232,16 @@ ssh_kex2(struct ssh *ssh, char *host, st
  	if (options.hostkeyalgorithms != NULL) {
  		all_key = sshkey_alg_list(0, 0, 1, ',');
  		if (kex_assemble_names(&options.hostkeyalgorithms,
diff --git a/SOURCES/openssh-7.8p1-role-mls.patch b/SOURCES/openssh-7.8p1-role-mls.patch
index 84ba9b3..c3bec2a 100644
--- a/SOURCES/openssh-7.8p1-role-mls.patch
+++ b/SOURCES/openssh-7.8p1-role-mls.patch
@@ -284,7 +284,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
  		fail++;
  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
  		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-+	if ((s = strchr(p, '/')) != NULL)
++	if ((s = strchr(cp, '/')) != NULL)
 +		*s = '\0';
  	xasprintf(&userstyle, "%s%s%s", authctxt->user,
  	    authctxt->style ? ":" : "",
diff --git a/SOURCES/openssh-7.9p1-ssh-copy-id.patch b/SOURCES/openssh-7.9p1-ssh-copy-id.patch
index d47880a..6ff2b25 100644
--- a/SOURCES/openssh-7.9p1-ssh-copy-id.patch
+++ b/SOURCES/openssh-7.9p1-ssh-copy-id.patch
@@ -11,6 +11,17 @@ diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh
    # implement something like getopt to avoid Solaris pain
    case "$1" in
      -i?*|-o?*|-p?*)
+@@ -185,8 +185,8 @@
+   usage
+ fi
+ 
+-# drop trailing colon
+-USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//')
++# don't drop trailing colon because it can be a valid ipv6 address
++USER_HOST=$(printf "%s\n" "$1")
+ # tack the hostname onto SSH_OPTS
+ SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'"
+ # and populate "$@" for later use (only way to get proper quoting of options)
 @@ -261,7 +262,7 @@ populate_new_ids() {
    fi
    if [ -z "$NEW_IDS" ] ; then
diff --git a/SOURCES/openssh-8.0p1-cve-2020-14145.patch b/SOURCES/openssh-8.0p1-cve-2020-14145.patch
new file mode 100644
index 0000000..c296bc4
--- /dev/null
+++ b/SOURCES/openssh-8.0p1-cve-2020-14145.patch
@@ -0,0 +1,127 @@
+diff -up openssh-8.0p1/hostfile.c.cve-2020-14145 openssh-8.0p1/hostfile.c
+--- openssh-8.0p1/hostfile.c.cve-2020-14145	2019-04-18 00:52:57.000000000 +0200
++++ openssh-8.0p1/hostfile.c	2021-05-17 16:53:38.694577251 +0200
+@@ -409,6 +409,18 @@ lookup_key_in_hostkeys_by_type(struct ho
+ 	    found) == HOST_FOUND);
+ }
+ 
++int
++lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker)
++{
++	u_int i;
++
++	for (i = 0; i < hostkeys->num_entries; i++) {
++		if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker)
++			return 1;
++	}
++	return 0;
++}
++
+ static int
+ write_host_entry(FILE *f, const char *host, const char *ip,
+     const struct sshkey *key, int store_hash)
+diff -up openssh-8.0p1/hostfile.h.cve-2020-14145 openssh-8.0p1/hostfile.h
+--- openssh-8.0p1/hostfile.h.cve-2020-14145	2019-04-18 00:52:57.000000000 +0200
++++ openssh-8.0p1/hostfile.h	2021-05-17 16:53:38.694577251 +0200
+@@ -39,6 +39,7 @@ HostStatus check_key_in_hostkeys(struct
+     const struct hostkey_entry **);
+ int	 lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
+     const struct hostkey_entry **);
++int	 lookup_marker_in_hostkeys(struct hostkeys *, int);
+ 
+ int	 hostfile_read_key(char **, u_int *, struct sshkey *);
+ int	 add_host_to_hostfile(const char *, const char *,
+diff -up openssh-8.0p1/sshconnect2.c.cve-2020-14145 openssh-8.0p1/sshconnect2.c
+--- openssh-8.0p1/sshconnect2.c.cve-2020-14145	2021-05-17 16:53:38.610576561 +0200
++++ openssh-8.0p1/sshconnect2.c	2021-05-17 16:54:58.169230103 +0200
+@@ -98,12 +98,25 @@ verify_host_key_callback(struct sshkey *
+ 	return 0;
+ }
+ 
++/* Returns the first item from a comma-separated algorithm list */
++static char *
++first_alg(const char *algs)
++{
++	char *ret, *cp;
++
++	ret = xstrdup(algs);
++	if ((cp = strchr(ret, ',')) != NULL)
++		*cp = '\0';
++	return ret;
++}
++
+ static char *
+ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
+ {
+-	char *oavail, *avail, *first, *last, *alg, *hostname, *ret;
++	char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL;
++	char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL;
+ 	size_t maxlen;
+-	struct hostkeys *hostkeys;
++	struct hostkeys *hostkeys = NULL;
+ 	int ktype;
+ 	u_int i;
+ 
+@@ -115,6 +128,26 @@ order_hostkeyalgs(char *host, struct soc
+ 	for (i = 0; i < options.num_system_hostfiles; i++)
+ 		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
+ 
++	/*
++	 * If a plain public key exists that matches the type of the best
++	 * preference HostkeyAlgorithms, then use the whole list as is.
++	 * Note that we ignore whether the best preference algorithm is a
++	 * certificate type, as sshconnect.c will downgrade certs to
++	 * plain keys if necessary.
++	 */
++	best = first_alg(options.hostkeyalgorithms);
++	if (lookup_key_in_hostkeys_by_type(hostkeys,
++	    sshkey_type_plain(sshkey_type_from_name(best)), NULL)) {
++		debug3("%s: have matching best-preference key type %s, "
++		    "using HostkeyAlgorithms verbatim", __func__, best);
++		ret = xstrdup(options.hostkeyalgorithms);
++		goto out;
++	}
++
++	/*
++	 * Otherwise, prefer the host key algorithms that match known keys
++	 * while keeping the ordering of HostkeyAlgorithms as much as possible.
++	 */
+ 	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
+ 	maxlen = strlen(avail) + 1;
+ 	first = xmalloc(maxlen);
+@@ -131,11 +164,23 @@ order_hostkeyalgs(char *host, struct soc
+ 	while ((alg = strsep(&avail, ",")) && *alg != '\0') {
+ 		if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
+ 			fatal("%s: unknown alg %s", __func__, alg);
++		/*
++		 * If we have a @cert-authority marker in known_hosts then
++		 * prefer all certificate algorithms.
++		 */
++		if (sshkey_type_is_cert(ktype) &&
++		    lookup_marker_in_hostkeys(hostkeys, MRK_CA)) {
++			ALG_APPEND(first, alg);
++			continue;
++		}
++		/* If the key appears in known_hosts then prefer it */
+ 		if (lookup_key_in_hostkeys_by_type(hostkeys,
+-		    sshkey_type_plain(ktype), NULL))
++		    sshkey_type_plain(ktype), NULL)) {
+ 			ALG_APPEND(first, alg);
+-		else
+-			ALG_APPEND(last, alg);
++			continue;
++		}
++		/* Otherwise, put it last */
++		ALG_APPEND(last, alg);
+ 	}
+ #undef ALG_APPEND
+ 	xasprintf(&ret, "%s%s%s", first,
+@@ -143,6 +188,8 @@ order_hostkeyalgs(char *host, struct soc
+ 	if (*first != '\0')
+ 		debug3("%s: prefer hostkeyalgs: %s", __func__, first);
+ 
++ out:
++	free(best);
+ 	free(first);
+ 	free(last);
+ 	free(hostname);
diff --git a/SOURCES/openssh-8.0p1-keygen-strip-doseol.patch b/SOURCES/openssh-8.0p1-keygen-strip-doseol.patch
new file mode 100644
index 0000000..3117a7a
--- /dev/null
+++ b/SOURCES/openssh-8.0p1-keygen-strip-doseol.patch
@@ -0,0 +1,12 @@
+diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c
+--- openssh-8.0p1/ssh-keygen.c.strip-doseol	2021-03-18 17:41:34.472404994 +0100
++++ openssh-8.0p1/ssh-keygen.c	2021-03-18 17:41:55.255538761 +0100
+@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw)
+ 	while (getline(&line, &linesize, f) != -1) {
+ 		lnum++;
+ 		cp = line;
+-		cp[strcspn(cp, "\n")] = '\0';
++		cp[strcspn(cp, "\r\n")] = '\0';
+ 		/* Trim leading space and comments */
+ 		cp = line + strspn(line, " \t");
+ 		if (*cp == '#' || *cp == '\0')
diff --git a/SOURCES/openssh-8.0p1-pkcs11-uri.patch b/SOURCES/openssh-8.0p1-pkcs11-uri.patch
index a24dea6..80af3e0 100644
--- a/SOURCES/openssh-8.0p1-pkcs11-uri.patch
+++ b/SOURCES/openssh-8.0p1-pkcs11-uri.patch
@@ -1167,7 +1167,7 @@ new file mode 100644
 index 00000000..e1a7b4e0
 --- /dev/null
 +++ b/ssh-pkcs11-uri.c
-@@ -0,0 +1,421 @@
+@@ -0,0 +1,425 @@
 +/*
 + * Copyright (c) 2017 Red Hat
 + *
@@ -1419,6 +1419,10 @@ index 00000000..e1a7b4e0
 +void
 +pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11)
 +{
++	if (pkcs11 == NULL) {
++		return;
++	}
++
 +	free(pkcs11->id);
 +	free(pkcs11->module_path);
 +	free(pkcs11->token);
@@ -2677,6 +2681,9 @@ index 70f06bff..59332945 100644
 +	}
 +
 +	provider_uri = pkcs11_uri_get(uri);
++	if (pin == NULL && uri->pin != NULL) {
++		pin = uri->pin;
++	}
 +	nkeys = 0;
 +	for (i = 0; i < p->module->nslots; i++) {
 +		token = &p->module->slotinfo[i].token;
@@ -2712,9 +2719,6 @@ index 70f06bff..59332945 100644
 +		    provider_uri, (unsigned long)i,
  		    token->label, token->manufacturerID, token->model,
  		    token->serialNumber, token->flags);
-+		if (pin == NULL && uri->pin != NULL) {
-+			pin = uri->pin;
-+		}
  		/*
 -		 * open session, login with pin and retrieve public
 -		 * keys (if keyp is provided)
@@ -2741,8 +2745,8 @@ index 70f06bff..59332945 100644
 +				uri->object = label;
 +			}
  		}
-+		pin = NULL; /* Will be cleaned up with URI */
  	}
++	pin = NULL; /* Will be cleaned up with URI */
  
  	/* now owned by caller */
  	*providerp = p;
diff --git a/SOURCES/openssh-8.0p1-preserve-pam-errors.patch b/SOURCES/openssh-8.0p1-preserve-pam-errors.patch
new file mode 100644
index 0000000..dbdbe93
--- /dev/null
+++ b/SOURCES/openssh-8.0p1-preserve-pam-errors.patch
@@ -0,0 +1,44 @@
+diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
+--- openssh-8.0p1/auth-pam.c.preserve-pam-errors	2021-03-31 17:03:15.618592347 +0200
++++ openssh-8.0p1/auth-pam.c	2021-03-31 17:06:58.115220014 +0200
+@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp)
+ 		goto auth_fail;
+ 
+ 	if (!do_pam_account()) {
+-		sshpam_err = PAM_ACCT_EXPIRED;
++		/* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN.
++		 * Backward compatibility for other errors. */
++		if (sshpam_err != PAM_PERM_DENIED
++			&& sshpam_err != PAM_USER_UNKNOWN)
++			sshpam_err = PAM_ACCT_EXPIRED;
+ 		goto auth_fail;
+ 	}
+ 	if (sshpam_authctxt->force_pwchange) {
+@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp)
+ 	    pam_strerror(sshpam_handle, sshpam_err))) != 0)
+ 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 	/* XXX - can't do much about an error here */
+-	if (sshpam_err == PAM_ACCT_EXPIRED)
+-		ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
++	if (sshpam_err == PAM_PERM_DENIED
++		|| sshpam_err == PAM_USER_UNKNOWN
++		|| sshpam_err == PAM_ACCT_EXPIRED)
++		ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
+ 	else if (sshpam_maxtries_reached)
+ 		ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
+ 	else
+@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha
+ 			plen++;
+ 			free(msg);
+ 			break;
++		case PAM_USER_UNKNOWN:
++		case PAM_PERM_DENIED:
+ 		case PAM_ACCT_EXPIRED:
++			sshpam_account_status = 0;
++			/* FALLTHROUGH */
+ 		case PAM_MAXTRIES:
+-			if (type == PAM_ACCT_EXPIRED)
+-				sshpam_account_status = 0;
+ 			if (type == PAM_MAXTRIES)
+ 				sshpam_set_maxtries_reached(1);
+ 			/* FALLTHROUGH */
diff --git a/SOURCES/openssh-8.0p1-restore-nonblock.patch b/SOURCES/openssh-8.0p1-restore-nonblock.patch
new file mode 100644
index 0000000..b16e17e
--- /dev/null
+++ b/SOURCES/openssh-8.0p1-restore-nonblock.patch
@@ -0,0 +1,311 @@
+diff -up openssh-8.0p1/channels.c.restore-nonblock openssh-8.0p1/channels.c
+--- 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 */
+-	if (nonblock) {
++	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, Channel *c, int *fdp)
+ {
+ 	struct ssh_channels *sc = ssh->chanctxt;
+-	int ret = 0, fd = *fdp;
++	int ret, fd = *fdp;
+ 
+-	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, &c->sock);
+ 	if (rfd != sock)
+-		channel_close_fd(ssh, &c->rfd);
++		channel_close_fd(ssh, c, &c->rfd);
+ 	if (wfd != sock && wfd != rfd)
+-		channel_close_fd(ssh, &c->wfd);
++		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, &c->efd);
+ }
+ 
+ static void
+@@ -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, &c->sock);
+ 				channel_free(ssh, c);
+ 				break;
+ 			}
+@@ -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, &c->sock);
+ 		chan_mark_dead(ssh, c);
+ 		errno = oerrno;
+ 	}
+@@ -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, &c->efd);
+ 	} else {
+ 		if ((r = sshbuf_consume(c->extended, len)) != 0) {
+ 			fatal("%s: channel %d: consume: %s",
+@@ -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, &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-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 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 */
++
++/* 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 *, 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-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, &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,
+@@ -417,7 +417,7 @@ chan_shutdown_read(struct ssh *ssh, Chan
+  			    strerror(errno));
+ 		}
+ 	} else {
+-		if (channel_close_fd(ssh, &c->rfd) < 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,
+@@ -437,7 +437,7 @@ chan_shutdown_extended_read(struct ssh *
+ 	debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
+ 	    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, &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-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");
+ 
+-	/* enable nonblocking unless tty */
+-	if (!isatty(in))
+-		set_nonblock(in);
+-	if (!isatty(out))
+-		set_nonblock(out);
+-	if (!isatty(err))
+-		set_nonblock(err);
+-
+ 	window = CHAN_SES_WINDOW_DEFAULT;
+ 	packetmax = CHAN_SES_PACKET_DEFAULT;
+ 	if (tty_flag) {
+@@ -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", CHANNEL_NONBLOCK_STDIO);
+ 
+ 	debug3("%s: channel_new: %d", __func__, c->self);
+ 
diff --git a/SOURCES/openssh-8.0p1-sftp-timespeccmp.patch b/SOURCES/openssh-8.0p1-sftp-timespeccmp.patch
new file mode 100644
index 0000000..7254b4a
--- /dev/null
+++ b/SOURCES/openssh-8.0p1-sftp-timespeccmp.patch
@@ -0,0 +1,16 @@
+diff -up openssh-8.0p1/sftp.c.original openssh-8.0p1/sftp.c
+--- openssh-8.0p1/sftp.c.original	2020-12-22 17:05:02.105698989 +0900
++++ openssh-8.0p1/sftp.c	2020-12-22 17:05:42.922035780 +0900
+@@ -937,7 +937,11 @@ sglob_comp(const void *aa, const void *b
+ 		return (rmul * strcmp(ap, bp));
+ 	else if (sort_flag & LS_TIME_SORT) {
+ #if defined(HAVE_STRUCT_STAT_ST_MTIM)
+-		return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
++		if (timespeccmp(&as->st_mtim, &bs->st_mtim, <)){
++			return rmul;
++		} else {
++			return -rmul;
++		}
+ #elif defined(HAVE_STRUCT_STAT_ST_MTIME)
+ 		return (rmul * NCMP(as->st_mtime, bs->st_mtime));
+ #else
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 6c281fc..ab3b01e 100644
--- a/SPECS/openssh.spec
+++ b/SPECS/openssh.spec
@@ -66,14 +66,14 @@
 
 # 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 6
+%global openssh_rel 10
 %global pam_ssh_agent_ver 0.10.3
 %global pam_ssh_agent_rel 7
 
 Summary: An open source implementation of SSH protocol version 2
 Name: openssh
 Version: %{openssh_ver}
-Release: %{openssh_rel}%{?dist}%{?rescue_rel}.2
+Release: %{openssh_rel}%{?dist}%{?rescue_rel}
 URL: http://www.openssh.com/portable.html
 #URL1: http://pamsshagentauth.sourceforge.net
 Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
@@ -232,6 +232,19 @@ Patch970: openssh-8.0p1-rdomain.patch
 Patch971: openssh-8.0p1-x11-without-ipv6.patch
 # Client window fix (#1913041)
 Patch972: openssh-8.0p1-channel-limits.patch
+# SFTP sort upon the modification time (#1909988)
+# https://bugzilla.mindrot.org/show_bug.cgi?id=3248
+Patch973: openssh-8.0p1-sftp-timespeccmp.patch
+# ssh-keygen printing fingerprint issue with Windows keys (#1901518)
+Patch974: openssh-8.0p1-keygen-strip-doseol.patch
+# sshd provides PAM an incorrect error code (#1879503)
+Patch975: openssh-8.0p1-preserve-pam-errors.patch
+# ssh incorrectly restores the blocking mode on standard output (#1942901)
+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
@@ -324,7 +337,7 @@ Requires: openssh = %{version}-%{release}
 Summary: PAM module for authentication with ssh-agent
 Group: System Environment/Base
 Version: %{pam_ssh_agent_ver}
-Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}%{?rescue_rel}.1
+Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}%{?rescue_rel}
 License: BSD
 
 %description
@@ -451,6 +464,12 @@ popd
 %patch970 -p1 -b .rdomain
 %patch971 -p1 -b .x11-ipv6
 %patch972 -p1 -b .channel-limits
+%patch973 -p1 -b .sftp-timespeccmp
+%patch974 -p1 -b .keygen-strip-doseol
+%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
@@ -742,14 +761,27 @@ getent passwd sshd >/dev/null || \
 %endif
 
 %changelog
-* Wed Apr 14 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-6.2 + 0.10.3-7.1
-- rebuilt
-
-* Wed Apr 14 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-6.1 + 0.10.3-7
-- rebuilt
-
-* Tue Mar 16 2021 Dmitry Belyavskiy - 8.0p1-6 + 0.10.3-7
-- Openssh client window fix (#1942364)
+* Mon Jun 21 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-10
+- sshd -T requires -C when "Match" is used in sshd_config (#1836277)
+
+* Wed Jun 02 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-9
+- CVE-2020-14145 openssh: Observable Discrepancy leading to an information
+  leak in the algorithm negotiation (#1882252)
+- Hostbased ssh authentication fails if session ID contains a '/' (#1944125)
+
+* Mon Apr 26 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-8
+- ssh doesn't restore the blocking mode on standard output (#1942901)
+
+* Fri Apr 09 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-7 + 0.10.3-7
+- SFTP sort upon the modification time (#1909988)
+- ssh-keygen printing fingerprint issue with Windows keys (#1901518)
+- PIN is lost when iterating over tokens when adding pkcs11 keys to ssh-agent (#1843372)
+- ssh-agent segfaults during ssh-add -s pkcs11 (#1868996)
+- ssh-copy-id could not resolve ipv6 address ends with colon (#1933517)
+- sshd provides PAM an incorrect error code (#1879503)
+
+* Tue Mar 16 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.0p1-6 + 0.10.3-7
+- Openssh client window fix (#1913041)
 
 * Tue Mar 24 2020 Jakub Jelen <jjelen@redhat.com> - 8.0p1-5 + 0.10.3-7
 - Do not print "no slots" warning by default (#1744220)