[openssh-commits] [openssh] 72/87: upstream: check for errors when writing known_hosts files and

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 30 20:21:49 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 bb7ffdd7966c044361e86be1663b459fd0f6274c
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Fri Oct 30 08:23:58 2026 +0000

    upstream: check for errors when writing known_hosts files and
    
    refuse to replace if the replacement is incomplete.
    
    Anthropic ANT-2026-SZY2YGUM
    
    OpenBSD-Commit-ID: 6d2137c4db55664397ba1ecb4cd4dc29d21eefe5
---
 hostfile.c   | 20 ++++++++++++++++----
 ssh-keygen.c | 10 +++++++---
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/hostfile.c b/hostfile.c
index c02662601..6b0e084eb 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.101 2026/10/30 07:48:23 djm Exp $ */
+/* $OpenBSD: hostfile.c,v 1.102 2026/10/30 08:23:58 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -592,7 +592,8 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx)
 			if (!sshkey_equal(ctx->keys[i], l->key))
 				continue;
 			ctx->match_keys[i] |= l->match;
-			fprintf(ctx->out, "%s\n", l->line);
+			if (fprintf(ctx->out, "%s\n", l->line) < 0)
+				return SSH_ERR_SYSTEM_ERROR;
 			debug3_f("%s key already at %s:%ld",
 			    sshkey_type(l->key), l->path, l->linenum);
 			return 0;
@@ -614,7 +615,8 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx)
 		    ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "",
 		    l->path, l->linenum);
 	}
-	fprintf(ctx->out, "%s\n", l->line);
+	if (fprintf(ctx->out, "%s\n", l->line) < 0)
+		return SSH_ERR_SYSTEM_ERROR;
 	return 0;
 }
 
@@ -717,8 +719,15 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
 		fp = NULL;
 		ctx.modified = 1;
 	}
-	fclose(ctx.out);
+	/* Don't replace the original with an incompletely-written copy */
+	r = fclose(ctx.out);
 	ctx.out = NULL;
+	if (r != 0) {
+		oerrno = errno;
+		error_f("fclose \"%s\": %s", temp, strerror(oerrno));
+		r = SSH_ERR_SYSTEM_ERROR;
+		goto fail;
+	}
 
 	if (ctx.modified) {
 		/* Backup the original file and replace it with the temporary */
@@ -955,6 +964,9 @@ hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback,
 		if ((r = callback(&lineinfo, ctx)) != 0)
 			break;
 	}
+	/* A read error must not be mistaken for the end of the file */
+	if (r == 0 && ferror(f))
+		r = SSH_ERR_SYSTEM_ERROR;
 	sshkey_free(lineinfo.key);
 	free(lineinfo.line);
 	free(line);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 2980cc27a..22ed27ea8 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.499 2026/10/30 03:47:56 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.500 2026/10/30 08:23:58 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1350,8 +1350,12 @@ do_known_hosts(struct passwd *pw, const char *name, int find_host,
 		fatal_fr(r, "hostkeys_foreach");
 	}
 
-	if (inplace)
-		fclose(ctx.out);
+	/* Don't replace the original with an incompletely-written copy */
+	if (inplace && (ferror(ctx.out) || fclose(ctx.out) != 0)) {
+		oerrno = errno;
+		unlink(tmp);
+		fatal("write %s: %s", tmp, strerror(oerrno));
+	}
 
 	if (ctx.invalid) {
 		error("%s is not a valid known_hosts file.", identity_file);

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


More information about the openssh-commits mailing list