guix-mirrors/gnu/packages/patches/openssh-trust-guix-store-directory.patch
Sergey Trofimov eab097c682
gnu: openssh: Adapt for root-less guix store.
Fixes <https://issues.guix.gnu.org/78067>.

Previously sshd would use /gnu/store/…-openssh-…/var/empty as its
PRIVSEP_PATH.  However, when using the unprivileged daemon, that
directory would belong to guix-daemon:guix-daemon, leading to this
error:

  sshd[234]: fatal: /gnu/store/…-openssh-10.0p1/var/empty must be owned by root and not group or world-writable.

Fix that by switching to /var/empty.

* gnu/packages/patches/openssh-trust-guix-store-directory.patch
(openssh): Adjust to trust files in guix store owned by guix-daemon.
* gnu/packages/ssh.scm (openssh)[arguments]:  Remove ‘reset-/var/empty’
phase; change ‘install’ phase to not create PRIVSEP_PATH..  Append
ending slash when substituting STORE_DIRECTORY.

Change-Id: I3bd01f8b9d6406e3b886eea8f4b8c265a51cc72f
Reported-by: Zack Weinberg <zack@owlfolio.org>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-06 00:16:33 +02:00

65 lines
2.2 KiB
Diff

From 0d85bbd42ddcd442864a9ba4719aca8b70d68048 Mon Sep 17 00:00:00 2001
From: Alexey Abramov <levenson@mmer.org>
Date: Fri, 22 Apr 2022 11:32:15 +0200
Subject: [PATCH] Trust guix store directory
To be able to execute binaries defined in OpenSSH configuration, we need to
tell OpenSSH that we can trust Guix store objects. safe_path procedure is
patched to assume files in Guix store to be safe. Additionally configuration
file placed in Guix store is assumed to be safe to load.
---
misc.c | 6 ++++++
readconf.c | 7 ++++---
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/misc.c b/misc.c
index dd0bd032a..6b866464c 100644
--- a/misc.c
+++ b/misc.c
@@ -2254,6 +2254,7 @@ int
safe_path(const char *name, struct stat *stp, const char *pw_dir,
uid_t uid, char *err, size_t errlen)
{
+ static const char guix_store[] = @STORE_DIRECTORY@;
char buf[PATH_MAX], homedir[PATH_MAX];
char *cp;
int comparehome = 0;
@@ -2271,6 +2272,11 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
snprintf(err, errlen, "%s is not a regular file", buf);
return -1;
}
+ // the file is trusted when it is located in guix store
+ if (strncmp(buf, guix_store, strlen(guix_store)) == 0) {
+ return 0;
+ }
+
if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
(stp->st_mode & 022) != 0) {
snprintf(err, errlen, "bad ownership or modes for file %s",
diff --git a/readconf.c b/readconf.c
index 7cbe7d2c2..40a5f1ace 100644
--- a/readconf.c
+++ b/readconf.c
@@ -2566,6 +2566,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
{
FILE *f;
char *line = NULL;
+ char errmsg[512];
size_t linesize = 0;
int linenum;
int bad_options = 0;
@@ -2581,9 +2582,9 @@ read_config_file_depth(const char *filename, struct passwd *pw,
if (fstat(fileno(f), &sb) == -1)
fatal("fstat %s: %s", filename, strerror(errno));
- if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
- (sb.st_mode & 022) != 0))
- fatal("Bad owner or permissions on %s", filename);
+ if (safe_path(filename, &sb, pw->pw_dir, pw->pw_uid, errmsg, sizeof(errmsg)) != 0) {
+ fatal(errmsg);
+ }
}
debug("Reading configuration data %.200s", filename);
--
2.49.0