openssh: Fix CVE-2026-60001

This patch applies the upstream OpenSSH 10.4 backport for
CVE-2026-60001. The upstream fix commit is referenced in [1],
and the public CVE advisory is referenced in [2].

[1] d43ba60c91
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-60001

(From OE-Core rev: 11cf9397c6ca0d8c080fbceb190d2a2b72b40da6)

Signed-off-by: Devansh Patel <devanshp@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Devansh Patel
2026-07-20 11:57:47 -07:00
committed by Paul Barker
parent 6f56dca72f
commit b2a7dabed0
2 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
From ef41798b35a53757f8aa08ad14ee1463b0fe9b15 Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Mon, 6 Jul 2026 07:44:48 +0000
Subject: [PATCH] upstream: Fix cases in GSSAPI and keyboard-interactive
authentication where the minimum per-attempt delay was not being enforced.
Reported by Orange Cyberdefense Vulnerability Team
CVE: CVE-2026-60001
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/d43ba60c91cb323ca921049b7d43b1908c318454]
Backport Changes:
- Kept Scarthgap's PRIVSEP(ssh_gssapi_userok()) interface and GSSAPI
display-name recording while adding the upstream failure-delay calls;
mm_ssh_gssapi_userok() belongs to the later split-sshd architecture.
- Retained the Scarthgap OpenBSD revision identifiers in auth.h,
auth2-chall.c, auth2-gss.c, and auth2.c.
OpenBSD-Commit-ID: c40bd35cc2428fcaccad7a141703c28baa6da01e
(cherry picked from commit d43ba60c91cb323ca921049b7d43b1908c318454)
Signed-off-by: Devansh Patel <devanshp@cisco.com>
---
auth.h | 1 +
auth2-chall.c | 4 ++++
auth2-gss.c | 7 +++++++
auth2.c | 10 ++++++++--
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/auth.h b/auth.h
index 6d2d39762..9ad4898c5 100644
--- a/auth.h
+++ b/auth.h
@@ -173,6 +173,7 @@ void auth_log(struct ssh *, int, int, const char *, const char *);
void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
void userauth_finish(struct ssh *, int, const char *, const char *);
int auth_root_allowed(struct ssh *, const char *);
+void auth_failure_delay(Authctxt *, double);
char *auth2_read_banner(void);
int auth2_methods_valid(const char *, int);
diff --git a/auth2-chall.c b/auth2-chall.c
index 021df8291..20e70d222 100644
--- a/auth2-chall.c
+++ b/auth2-chall.c
@@ -296,6 +296,7 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
u_int i, nresp;
const char *devicename = NULL;
char **response = NULL;
+ double tstart = monotime_double();
if (authctxt == NULL)
fatal_f("no authctxt");
@@ -354,6 +355,9 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
auth2_challenge_start(ssh);
}
}
+
+ if (!authenticated)
+ auth_failure_delay(authctxt, tstart);
userauth_finish(ssh, authenticated, "keyboard-interactive",
devicename);
return 0;
diff --git a/auth2-gss.c b/auth2-gss.c
index f72a38998..195578bcf 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -255,6 +255,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
Authctxt *authctxt = ssh->authctxt;
int r, authenticated;
const char *displayname;
+ double tstart = monotime_double();
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
fatal("No authentication or GSSAPI context");
@@ -268,6 +269,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
fatal_fr(r, "parse packet");
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+ if (!authenticated)
+ auth_failure_delay(authctxt, tstart);
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
@@ -293,6 +296,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
const char *displayname;
u_char *p;
size_t len;
+ double tstart = monotime_double();
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
fatal("No authentication or GSSAPI context");
@@ -320,6 +324,9 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
sshbuf_free(b);
free(mic.value);
+ if (!authenticated)
+ auth_failure_delay(authctxt, tstart);
+
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
auth2_record_info(authctxt, "%s", displayname);
diff --git a/auth2.c b/auth2.c
index 271789a77..18077d625 100644
--- a/auth2.c
+++ b/auth2.c
@@ -265,6 +265,12 @@ ensure_minimum_time_since(double start, double seconds)
nanosleep(&ts, NULL);
}
+void
+auth_failure_delay(Authctxt *authctxt, double tstart)
+{
+ ensure_minimum_time_since(tstart, user_specific_delay(authctxt->user));
+}
+
static int
input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
{
@@ -348,8 +354,8 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
authenticated = m->userauth(ssh, method);
}
if (!authctxt->authenticated && strcmp(method, "none") != 0)
- ensure_minimum_time_since(tstart,
- user_specific_delay(authctxt->user));
+ auth_failure_delay(authctxt, tstart);
+
userauth_finish(ssh, authenticated, method, NULL);
r = 0;
out:

View File

@@ -41,6 +41,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
file://CVE-2026-59997.patch \
file://CVE-2026-59996.patch \
file://CVE-2026-59995.patch \
file://CVE-2026-60001.patch \
"
SRC_URI[sha256sum] = "910211c07255a8c5ad654391b40ee59800710dd8119dd5362de09385aa7a777c"