[PATCH] ssh-keygen: fix overflow check in parse_hex_u64()

Muhammad Bilal meatuni001 at gmail.com
Fri Aug 28 08:08:45 AEST 2026


parse_hex_u64() reads a hex certificate validity time with
strtoull(3) into a local 'unsigned long long ull', then checks for
overflow with:

    if (errno == ERANGE && ull == ULONG_MAX)

strtoull(3) sets ull to ULLONG_MAX (the max value of unsigned long
long) on overflow, per C99/POSIX, not ULONG_MAX (the max value of
plain unsigned long). On LP64 platforms (most 64-bit Unix systems,
including Linux) long and long long are both 64 bits, so the two
constants happen to be equal and the check works by coincidence. On
ILP32 or LLP64 platforms (32-bit Unix, or Windows/Cygwin, where long
stays 32 bits but long long is still 64), ULONG_MAX != ULLONG_MAX, so
a genuine overflow (ull == ULLONG_MAX) never equals the 32-bit
ULONG_MAX being compared against, the ERANGE condition is missed, and
the truncated/wrapped value is silently used as a certificate
validity time.

The similar overflow check for -z serial numbers a few hundred lines
below (ssh-keygen.c, in main()'s option parsing) already compares
against ULLONG_MAX correctly; this makes parse_hex_u64() consistent
with it.

Confirmed by direct source review that this is a straight type
mismatch (ULONG_MAX vs. ULLONG_MAX bound to an unsigned long long
overflow check); could not be exercised as a live behavioural repro
on this 64-bit host since ULONG_MAX == ULLONG_MAX there, which is
exactly the condition that hides the bug on LP64 platforms.
---
 ssh-keygen.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ssh-keygen.c b/ssh-keygen.c
index 6667a5c1b..d19c491dc 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1923,7 +1923,7 @@ parse_hex_u64(const char *s, uint64_t *up)
 	ull = strtoull(s, &ep, 16);
 	if (*s == '\0' || *ep != '\0')
 		fatal("Invalid certificate time: not a number");
-	if (errno == ERANGE && ull == ULONG_MAX)
+	if (errno == ERANGE && ull == ULLONG_MAX)
 		fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
 	*up = (uint64_t)ull;
 }
-- 
2.43.0



More information about the openssh-unix-dev mailing list