diff --git a/openssh-9.9p1-copy-data-ext-self-copy.patch b/openssh-9.9p1-copy-data-ext-self-copy.patch
new file mode 100644
index 0000000..1fa43fc
--- /dev/null
+++ b/openssh-9.9p1-copy-data-ext-self-copy.patch
@@ -0,0 +1,51 @@
+diff --color -ruNp a/sftp-server.c b/sftp-server.c
+--- a/sftp-server.c 2026-07-17 16:23:12.293427062 +0200
++++ b/sftp-server.c 2026-07-17 16:29:01.480535500 +0200
+@@ -1625,6 +1625,7 @@ process_extended_copy_data(u_int32_t id)
+ u_int64_t len, read_off, read_len, write_off;
+ int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED;
+ size_t ret;
++ struct stat st_read, st_write;
+
+ if ((r = get_handle(iqueue, &read_handle)) != 0 ||
+ (r = sshbuf_get_u64(iqueue, &read_off)) != 0 ||
+@@ -1647,12 +1648,35 @@ process_extended_copy_data(u_int32_t id)
+ } else
+ copy_until_eof = 0;
+
++ /* Disallow reading & writing to the same handle, path or inode */
+ read_fd = handle_to_fd(read_handle);
+ write_fd = handle_to_fd(write_handle);
+-
+- /* Disallow reading & writing to the same handle or same path or dirs */
+- if (read_handle == write_handle || read_fd < 0 || write_fd < 0 ||
+- !strcmp(handle_to_name(read_handle), handle_to_name(write_handle))) {
++ if (read_fd < 0 || write_fd < 0) {
++ error_f("bad read or write fd");
++ status = errno_to_portable(EBADF);
++ goto out;
++ }
++ if (fstat(read_fd, &st_read) != 0) {
++ status = errno_to_portable(errno);
++ error_f("fstat read_fd failed: %s", strerror(errno));
++ goto out;
++ }
++ if (fstat(write_fd, &st_write) != 0) {
++ status = errno_to_portable(errno);
++ error_f("fstat write_fd failed: %s", strerror(errno));
++ goto out;
++ }
++ if (read_handle == write_handle ||
++ !strcmp(handle_to_name(read_handle), handle_to_name(write_handle)) ||
++ (st_read.st_dev != 0 && st_read.st_ino != 0 &&
++ st_read.st_dev == st_write.st_dev &&
++ st_read.st_ino == st_write.st_ino)) {
++ error_f("refusing to read/write same file: "
++ "read \"%s\" dev %lu ino %lu, write \"%s\" dev %lu ino %lu",
++ handle_to_name(read_handle),
++ (u_long)st_read.st_dev, (u_long)st_read.st_ino,
++ handle_to_name(write_handle),
++ (u_long)st_write.st_dev, (u_long)st_write.st_ino);
+ status = SSH2_FX_FAILURE;
+ goto out;
+ }
diff --git a/openssh-9.9p1-sshd-no-delegate-credentials.patch b/openssh-9.9p1-sshd-no-delegate-credentials.patch
index 59d0120..7132c9b 100644
--- a/openssh-9.9p1-sshd-no-delegate-credentials.patch
+++ b/openssh-9.9p1-sshd-no-delegate-credentials.patch
@@ -111,7 +111,7 @@ diff --color -ruNp a/sshd_config.5 b/sshd_config.5
.Cm yes .
+.It Cm GSSAPIDelegateCredentials
+Accept delegated credentials on the server side. The default is
-+.CM yes .
++.Cm yes .
.It Cm GSSAPIEnablek5users
Specifies whether to look at .k5users file for GSSAPI authentication
access control. Further details are described in
diff --git a/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch b/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
index 2a74740..ef70379 100644
--- a/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
+++ b/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
@@ -170,7 +170,7 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
#include "ssh-gss.h"
-@@ -87,6 +88,33 @@ ssh_gssapi_krb5_init(void)
+@@ -87,6 +88,42 @@ ssh_gssapi_krb5_init(void)
return 1;
}
@@ -178,6 +178,10 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
+ * one of indicators in the list of allowed/denied rules.
+ * In case of the match, apply the decision from the rule.
+ * In case of no indicator from the ticket matching the rule, deny
++ *
++ * Returns -1 on any negative match
++ * Returns 1 on positive match and no negative matches
++ * Returns 0 when no matches occurred
+ */
+
+static int
@@ -187,18 +191,23 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
+ u_int i;
+ *matched = -1;
+
-+ /* Check indicators */
+ for (i = 0; client->indicators[i] != NULL; i++) {
+ ret = match_pattern_list(client->indicators[i],
+ options.gss_indicators, 1);
-+ /* negative or positive match */
-+ if (ret != 0) {
++
++ /* record first positive match */
++ if (ret == 1 && *matched == -1)
+ *matched = i;
-+ return ret;
++
++ /* deny rule matched, return negative */
++ if (ret == -1) {
++ *matched = i;
++ return -1;
+ }
+ }
-+ /* No rule matched */
-+ return 0;
++ /* if there was a match, it was positive,
++ * otherwise no match */
++ return *matched != -1;
+}
+
/* Check if this user is OK to login. This only works with krb5 - other
diff --git a/openssh.spec b/openssh.spec
index 8ab8146..7bda48c 100644
--- a/openssh.spec
+++ b/openssh.spec
@@ -43,7 +43,7 @@
Summary: An open source implementation of SSH protocol version 2
Name: openssh
Version: %{openssh_ver}
-Release: 27%{?dist}.alma.1
+Release: 28%{?dist}.alma.1
URL: http://www.openssh.com/portable.html
Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc
@@ -256,6 +256,9 @@ Patch1044: openssh-9.9p1-proxyjump-username-validity-checks.patch
Patch1045: openssh-9.9p1-scp-remote-glob.patch
# upstream e8bdfb151a356d0171fea4194dd205fbb252be23
Patch1046: openssh-9.9p1-cve-2026-60002.patch
+# upstream 8b05bbeb293c5f777915e37e9ed43a06fb8e7614
+# upstream 5a5e47740b6466d58242aca28b9e584bab4ccf1d
+Patch1047: openssh-9.9p1-copy-data-ext-self-copy.patch
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND snprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant
Requires: /sbin/nologin
@@ -466,6 +469,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch -P 1044 -p1 -b .proxyjump-username-validity-checks
%patch -P 1045 -p1 -b .scp-remote-glob
%patch -P 1046 -p1 -b .cve-2026-60002
+%patch -P 1047 -p1 -b .copy-data-ext-self-copy
%patch -P 100 -p1 -b .coverity
@@ -746,9 +750,18 @@ test -f %{sysconfig_anaconda} && \
%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so
%changelog
-* Thu Jul 16 2026 Koichiro Iwao - 9.9p1-27.alma.1
+* Wed Jul 22 2026 Koichiro Iwao - 9.9p1-28.alma.1
- Unpatch Red Hat help message
+* Thu Jul 16 2026 Zoltan Fridrich - 9.9p1-28
+- Fix GSSAPI indicators check ignoring subsequent deny rules if
+ allow rule matched first
+ Resolves: RHEL-182151
+- Add default value for GSSAPIDelegateCredentials property in sshd_config manpage
+ Resolves: RHEL-211135
+- Fix self-copy guard bypass in copy-data extension
+ Resolves: RHEL-191388
+
* Fri Jun 26 2026 Zoltan Fridrich - 9.9p1-27
- CVE-2026-55653: Fix double free in openssh DH-GEX client path during
FIPS known-group validation that leads to client-side denial of service