[openssh-commits] [openssh] 04/10: upstream: Use getexecpath(3); if it fails use argv[0] as before

git+noreply at mindrot.org git+noreply at mindrot.org
Tue Sep 15 15:38:08 AEST 2026


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

djm pushed a commit to branch master
in repository openssh.

commit 327fb6ce6f91328f5910900be1c38120fc67ec9a
Author: deraadt at openbsd.org <deraadt at openbsd.org>
AuthorDate: Sun Sep 6 18:36:24 2026 +0000

    upstream: Use getexecpath(3); if it fails use argv[0] as before
    
    with the pre-existing code to validate it is an absolute path.  Here's a bit
    of history:  sshd became the first fork+exec privsep daemon (I did some
    arm-twisting). That privsep has recently turned into fork+exec different
    binaries but the SIGHUP restart code still want to re-run the binary from the
    original path. The rc startup sequence always passes an absolute path.  sshd
    was paranoid and validated it.  That made hand-restarts of sshd without
    absolute paths not work.  getexecpath(3) improves the ergonomics. ok djm
    
    OpenBSD-Commit-ID: b84759d60f689f94a4fb45f43a7436ce62e35487
---
 configure.ac                    |  1 +
 openbsd-compat/openbsd-compat.h |  5 +++++
 sshd.c                          | 17 +++++++++++++----
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 005f905db..224f29a5a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2138,6 +2138,7 @@ AC_CHECK_FUNCS([ \
 	getaddrinfo \
 	getcwd \
 	getentropy \
+	getexecpath \
 	getgrouplist \
 	getline \
 	getnameinfo \
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 680ba9db2..c74043adc 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -90,6 +90,11 @@ int getpagesize(void);
 char *getcwd(char *pt, size_t size);
 #endif
 
+#ifndef HAVE_GETEXECPATH
+/* XXX this relies on correct fallback behaviour */
+#define getexecpath(a, b) (-1)
+#endif
+
 #ifndef HAVE_KILLPG
 int killpg(pid_t, int);
 #endif
diff --git a/sshd.c b/sshd.c
index 7d1466d97..10c0da3b3 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.628 2026/06/29 07:36:37 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.629 2026/09/06 18:36:24 deraadt Exp $ */
 /*
  * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  * Copyright (c) 2002 Niels Provos.  All rights reserved.
@@ -103,6 +103,7 @@ ServerOptions options;
 int debug_flag = 0;
 
 /* Saved arguments to main(). */
+static char execpath[PATH_MAX];
 static char **saved_argv;
 static int saved_argc;
 
@@ -520,8 +521,8 @@ sighup_restart(void)
 	close_listen_socks();
 	close_startup_pipes();
 	ssh_signal(SIGHUP, SIG_IGN); /* will be restored after exec */
-	execv(saved_argv[0], saved_argv);
-	logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
+	execv(execpath, saved_argv);
+	logit("RESTART FAILED: execpath='%.100s', error: %.100s.", execpath,
 	    strerror(errno));
 	exit(1);
 }
@@ -1451,7 +1452,15 @@ main(int ac, char **av)
 			break;
 		}
 	}
-	if (!test_flag && !inetd_flag && !do_dump_cfg && !path_absolute(av[0]))
+
+	if (getexecpath(execpath, sizeof execpath) != 0) {
+		if (strlcpy(execpath, av[0], sizeof execpath) >=
+		    sizeof execpath) {
+			fprintf(stderr, "execution path is too long\n");
+			exit(1);
+		}
+	}
+	if (!test_flag && !inetd_flag && !do_dump_cfg && !path_absolute(execpath))
 		fatal("sshd requires execution with an absolute path");
 
 	closefrom(STDERR_FILENO + 1);

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


More information about the openssh-commits mailing list