fseek to end of known_hosts before writing to it. POSIX and ANSI C
authordtucker <dtucker@openbsd.org>
Tue, 21 Feb 2023 06:48:18 +0000 (06:48 +0000)
committerdtucker <dtucker@openbsd.org>
Tue, 21 Feb 2023 06:48:18 +0000 (06:48 +0000)
require that applications call fseek or similar between read and writing
to a RW file.  OpenBSD doesn't enforce this, but some (System V derived)
platforms need this to prevent it from writing a spurious extra byte (in
this case, a newline).  ok djm@ deraadt@

usr.bin/ssh/hostfile.c

index 47b4ade..dc56ca5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.94 2023/02/09 09:54:11 dtucker Exp $ */
+/* $OpenBSD: hostfile.c,v 1.95 2023/02/21 06:48:18 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -508,7 +508,7 @@ add_host_to_hostfile(const char *filename, const char *host,
     const struct sshkey *key, int store_hash)
 {
        FILE *f;
-       int success;
+       int success, addnl = 0;
 
        if (key == NULL)
                return 1;       /* XXX ? */
@@ -518,12 +518,13 @@ add_host_to_hostfile(const char *filename, const char *host,
                return 0;
        /* Make sure we have a terminating newline. */
        if (fseek(f, -1L, SEEK_END) == 0 && fgetc(f) != '\n')
-               if (fputc('\n', f) != '\n') {
-                       error("Failed to add terminating newline to %s: %s",
-                          filename, strerror(errno));
-                       fclose(f);
-                       return 0;
-               }
+               addnl = 1;
+       if (fseek(f, 0L, SEEK_END) != 0 || (addnl && fputc('\n', f) != '\n')) {
+               error("Failed to add terminating newline to %s: %s",
+                  filename, strerror(errno));
+               fclose(f);
+               return 0;
+       }
        success = write_host_entry(f, host, NULL, key, store_hash);
        fclose(f);
        return success;