[openssh-commits] [openssh] 38/87: upstream: enforce a global limit on the number of keys ssh-agent

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 30 20:21:15 AEDT 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit ea1b64a4047d3280877e58fa9430bae4f2817b68
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Fri Oct 30 04:08:33 2026 +0000

    upstream: enforce a global limit on the number of keys ssh-agent
    
    will store in destination constraints, also avoid calculating fingerprints
    for keys for use in debugging messages if debugging isn't enabled
    
    avoids more worst-case behaviour in ssh-agent.
    
    Anthropic ANT-2026-S1SM8TCF
    
    OpenBSD-Commit-ID: 0a9861be6ffcf7c60e945d85eb96651fa9393823
---
 ssh-agent.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/ssh-agent.c b/ssh-agent.c
index 9951345dd..542dd683c 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.333 2026/09/22 22:30:27 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.334 2026/10/30 04:08:33 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -100,6 +100,8 @@
 #define AGENT_MAX_SID_LEN		128
 /* Maximum number of destination constraints to accept on a key */
 #define AGENT_MAX_DEST_CONSTRAINTS	1024
+/* Maximum number of destination constraint hostkeys to hold across all keys */
+#define AGENT_MAX_DEST_CONSTRAINT_KEYS	16384
 /* Maximum number of associated certificate constraints to accept on a key */
 #define AGENT_MAX_EXT_CERTS		1024
 /* Max length of username constraint */
@@ -376,13 +378,15 @@ match_key_hop(const char *tag, const struct sshkey *key,
 		if (dch->keys[i] == NULL)
 			return -1;
 		/* XXX logspam */
-		if ((fp = sshkey_fingerprint(dch->keys[i], SSH_FP_HASH_DEFAULT,
-		    SSH_FP_DEFAULT)) == NULL)
-			fatal_f("fingerprint failed");
-		debug3_f("%s: key %u: %s%s %s", tag, i,
-		    dch->key_is_ca[i] ? "CA " : "",
-		    sshkey_type(dch->keys[i]), fp);
-		free(fp);
+		if (log_level_get() >= SYSLOG_LEVEL_DEBUG3) {
+			if ((fp = sshkey_fingerprint(dch->keys[i],
+			    SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL)
+				fatal_f("fingerprint failed");
+			debug3_f("%s: key %u: %s%s %s", tag, i,
+			    dch->key_is_ca[i] ? "CA " : "",
+			    sshkey_type(dch->keys[i]), fp);
+			free(fp);
+		}
 		if (!sshkey_is_cert(key)) {
 			/* plain key */
 			if (dch->key_is_ca[i] ||
@@ -584,6 +588,38 @@ lookup_identity(struct sshkey *key)
 	return (NULL);
 }
 
+static size_t
+count_dest_constraint_keys(const struct dest_constraint *dcs, size_t ndcs)
+{
+	size_t i, ret = 0;
+
+	for (i = 0; i < ndcs; i++)
+		ret += (size_t)dcs[i].from.nkeys + dcs[i].to.nkeys;
+	return ret;
+}
+
+/*
+ * Check whether the hostkeys in 'dcs' (replacing those of the existing
+ * identity 'old', if not NULL) would exceed the total number of destination
+ * constraint hostkeys the agent is willing to hold across all identities.
+ * Returns 0 if within limits or -1 otherwise.
+ */
+static int
+check_dest_constraint_space(const struct dest_constraint *dcs, size_t ndcs,
+    const Identity *old)
+{
+	Identity *id;
+	size_t nkeys = count_dest_constraint_keys(dcs, ndcs);
+
+	TAILQ_FOREACH(id, &idtab->idlist, next) {
+		if (id == old)
+			continue;
+		nkeys += count_dest_constraint_keys(id->dest_constraints,
+		    id->ndest_constraints);
+	}
+	return nkeys <= AGENT_MAX_DEST_CONSTRAINT_KEYS ? 0 : -1;
+}
+
 /* Check confirmation of keysign request */
 static int
 confirm_key(Identity *id, const char *extra)
@@ -1404,6 +1440,11 @@ process_add_identity(SocketEntry *e)
 			}
 		}
 	}
+	if (check_dest_constraint_space(dest_constraints, ndest_constraints,
+	    lookup_identity(k)) != 0) {
+		error_f("too many destination constraint hostkeys loaded");
+		goto out;
+	}
 	if ((r = sshkey_shield_private(k)) != 0) {
 		error_fr(r, "shield private");
 		goto out;
@@ -1540,6 +1581,13 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider,
 		free(comment);
 		return;
 	}
+	if (check_dest_constraint_space(dest_constraints, ndest_constraints,
+	    NULL) != 0) {
+		error_f("too many destination constraint hostkeys loaded");
+		sshkey_free(key);
+		free(comment);
+		return;
+	}
 	id = xcalloc(1, sizeof(Identity));
 	id->key = key;
 	id->comment = comment;

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list