mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2026-05-28 03:51:53 +02:00
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>
This commit is contained in:
committed by
Ludovic Courtès
parent
d9e0bb44c0
commit
eab097c682
@@ -3,20 +3,20 @@ From: Alexey Abramov <levenson@mmer.org>
|
|||||||
Date: Fri, 22 Apr 2022 11:32:15 +0200
|
Date: Fri, 22 Apr 2022 11:32:15 +0200
|
||||||
Subject: [PATCH] Trust guix store directory
|
Subject: [PATCH] Trust guix store directory
|
||||||
|
|
||||||
To be able to execute binaries defined in OpenSSH configuration, we
|
To be able to execute binaries defined in OpenSSH configuration, we need to
|
||||||
need to tell OpenSSH that we can trust Guix store objects. safe_path
|
tell OpenSSH that we can trust Guix store objects. safe_path procedure is
|
||||||
procedure takes a canonical path and for each component, walking
|
patched to assume files in Guix store to be safe. Additionally configuration
|
||||||
upwards, checks ownership and permissions constrains which are: must
|
file placed in Guix store is assumed to be safe to load.
|
||||||
be owned by root, not writable by group or others.
|
|
||||||
---
|
---
|
||||||
misc.c | 5 +++++
|
misc.c | 6 ++++++
|
||||||
1 file changed, 5 insertions(+)
|
readconf.c | 7 ++++---
|
||||||
|
2 files changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
diff --git a/misc.c b/misc.c
|
diff --git a/misc.c b/misc.c
|
||||||
index 0134d69..7131d5e 100644
|
index dd0bd032a..6b866464c 100644
|
||||||
--- a/misc.c
|
--- a/misc.c
|
||||||
+++ b/misc.c
|
+++ b/misc.c
|
||||||
@@ -2146,6 +2146,7 @@ int
|
@@ -2254,6 +2254,7 @@ int
|
||||||
safe_path(const char *name, struct stat *stp, const char *pw_dir,
|
safe_path(const char *name, struct stat *stp, const char *pw_dir,
|
||||||
uid_t uid, char *err, size_t errlen)
|
uid_t uid, char *err, size_t errlen)
|
||||||
{
|
{
|
||||||
@@ -24,17 +24,42 @@ index 0134d69..7131d5e 100644
|
|||||||
char buf[PATH_MAX], homedir[PATH_MAX];
|
char buf[PATH_MAX], homedir[PATH_MAX];
|
||||||
char *cp;
|
char *cp;
|
||||||
int comparehome = 0;
|
int comparehome = 0;
|
||||||
@@ -2178,6 +2179,10 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
|
@@ -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);
|
||||||
strlcpy(buf, cp, sizeof(buf));
|
return -1;
|
||||||
|
}
|
||||||
+ /* If we are past the Guix store then we can stop */
|
+ // the file is trusted when it is located in guix store
|
||||||
+ if (strcmp(guix_store, buf) == 0)
|
+ if (strncmp(buf, guix_store, strlen(guix_store)) == 0) {
|
||||||
+ break;
|
+ return 0;
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
if (stat(buf, &st) == -1 ||
|
if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
|
||||||
(!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
|
(stp->st_mode & 022) != 0) {
|
||||||
(st.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.34.0
|
2.49.0
|
||||||
|
|
||||||
|
|||||||
@@ -275,16 +275,11 @@ a server that supports the SSH-2 protocol.")
|
|||||||
'()))
|
'()))
|
||||||
#:phases
|
#:phases
|
||||||
#~(modify-phases %standard-phases
|
#~(modify-phases %standard-phases
|
||||||
(add-after 'configure 'reset-/var/empty
|
|
||||||
(lambda _
|
|
||||||
(substitute* "Makefile"
|
|
||||||
(("PRIVSEP_PATH=/var/empty")
|
|
||||||
(string-append "PRIVSEP_PATH=" #$output "/var/empty")))))
|
|
||||||
(add-after 'configure 'set-store-location
|
(add-after 'configure 'set-store-location
|
||||||
(lambda _
|
(lambda _
|
||||||
(substitute* "misc.c"
|
(substitute* "misc.c"
|
||||||
(("@STORE_DIRECTORY@")
|
(("@STORE_DIRECTORY@")
|
||||||
(string-append "\"" (%store-directory) "\"")))))
|
(string-append "\"" (%store-directory) "/\"")))))
|
||||||
(add-before 'check 'patch-tests
|
(add-before 'check 'patch-tests
|
||||||
(lambda _
|
(lambda _
|
||||||
(substitute* "regress/test-exec.sh"
|
(substitute* "regress/test-exec.sh"
|
||||||
@@ -297,9 +292,10 @@ a server that supports the SSH-2 protocol.")
|
|||||||
(string-append pre post)))))
|
(string-append pre post)))))
|
||||||
(replace 'install
|
(replace 'install
|
||||||
(lambda* (#:key (make-flags '()) #:allow-other-keys)
|
(lambda* (#:key (make-flags '()) #:allow-other-keys)
|
||||||
;; Install without host keys and system configuration files. This
|
;; Don't create /var/empty.
|
||||||
;; will install /var/empty to the store, which is needed by the
|
(substitute* "Makefile"
|
||||||
;; system openssh-service-type.
|
((".*MKDIR_P.*PRIVSEP_PATH.*") ""))
|
||||||
|
;; Install without host keys and system configuration files.
|
||||||
(apply invoke "make" "install-nosysconf" make-flags)
|
(apply invoke "make" "install-nosysconf" make-flags)
|
||||||
(with-directory-excursion "contrib"
|
(with-directory-excursion "contrib"
|
||||||
(chmod "ssh-copy-id" #o555)
|
(chmod "ssh-copy-id" #o555)
|
||||||
|
|||||||
Reference in New Issue
Block a user