Includes fixes for CVE-2025-6424, CVE-2025-6425, CVE-2025-6426,
CVE-2025-6429, and CVE-2025-6430.
* gnu/packages/gnuzilla.scm (mozilla-115-compare-locales)
(mozilla-115-locale, mozilla-115-locales, update-mozilla-115-locales)
(all-mozilla-115-locales, %icecat-115-base-version)
(%icecat-115-version %icecat-115-build-id, icecat-115-source): New
bindings, retaining the previous meanings (before this commit) of
mozilla-compare-locales, mozilla-locale, mozilla-locales,
update-mozilla-locales, all-mozilla-locales, %icecat-base-version,
%icecat-version, %icecat-build-id, and icecat-source, respectively.
(mozilla-locale, mozilla-locales, update-mozilla-locales)
(all-mozilla-locales): Remove bindings.
(mozilla-compare-locales): Switch to new Github URL.
(mozilla-l10n): New variable.
(%icecat-locales): Move definition above "%icecat-base-version".
Add new locales "sat" and "skr".
(%icecat-base-version, %icecat-version, %icecat-build-id): Update.
(icecat-source): Update 'gnuzilla-commit' and hashes.
Remove 'upstream-icecat-base-version' local variable
and associated comments. Modify the code
within (with-directory-excursion "l10n" ...) to adapt to new
upstream handling of locales.
(icecat-minimal) [inputs]: Switch from 'ffmpeg-5' to 'ffmpeg'.
Update the comment on why we are still using the bundled NSS.
[native-inputs]: Switch from 'rust-cbindgen-0.24' to 'rust-cbindgen'.
[arguments]: Add "--enable-rust-simd" to configure-flags.
Adapt 'remove-cargo-frozen-flag' phase to work on IceCat 128.
(comm-source->locales+changeset): Use 'update-mozilla-115-locales'.
(icedove-source): Use 'icecat-115-source'.
* gnu/packages/patches/icecat-use-system-wide-dir.patch,
gnu/packages/patches/icecat-compare-paths.patch: Adapt to IceCat 128.
* gnu/packages/patches/icecat-102-makeicecat.patch: Delete file
* gnu/local.mk (dist_patch_DATA): Remove it.
Previously, if an attacker managed to introduce a hard link or a symlink
on one of the destination file names before it is opened,
‘copyFileRecursively’ would overwrite the symlink’s target or the hard
link’s content.
This kind of attack could be carried out while guix-daemon is copying
the output or the chroot directory of a failed fixed-output derivation
build, possibly allowing the attacker to escalate to the privileges of
the build user.
* nix/libutil/util.cc (copyFileRecursively): In the ‘S_ISREG’ case, open
‘destination’ with O_NOFOLLOW | O_EXCL. In the ‘S_ISDIR’ case, open
‘destination’ with O_NOFOLLOW.
Reported-by: Reepca Russelstein <reepca@russelstein.xyz>
Change-Id: I94273efe4e92c1a4270a98c5ec47bd098e9227c9
Signed-off-by: John Kehayias <john.kehayias@protonmail.com>
The container that slirp4netns runs in should already be quite difficult to do
anything malicious in beyond basic denial of service or sending of network
traffic. There is, however, one hole remaining in the case in which there is
an adversary able to run code locally: abstract unix sockets. Because these
are governed by network namespaces, not IPC namespaces, and slirp4netns is in
the root network namespace, any process in the root network namespace can
cooperate with the slirp4netns process to take over its user.
To close this, we use seccomp to block the creation of unix-domain sockets by
slirp4netns. This requires some finesse, since slirp4netns absolutely needs
to be able to create other types of sockets - at minimum AF_INET and AF_INET6
Seccomp has many, many pitfalls. To name a few:
1. Seccomp provides you with an "arch" field, but this does not uniquely
determine the ABI being used; the actual meaning of a system call number
depends on both the number (which is often the result of ORing a related
system call with a flag for an alternate ABI) and the architecture.
2. Seccomp provides no direct way of knowing what the native value for the
arch field should be; the user must do configure/compile-time testing for
every architecture+ABI combination they want to support. Amusingly enough,
the linux-internal header files have this exact information
(SECCOMP_ARCH_NATIVE), but they aren't sharing it.
3. The only system call numbers we naturally have are the native ones in
asm/unistd.h. __NR_socket will always refer to the system call number for
the target system's ABI.
4. Seccomp can only manipulate 32-bit words, but represents every system call
argument as a uint64.
5. New system call numbers with as-yet-unknown semantics can be added to the
kernel at any time.
6. Based on this comment in arch/x86/entry/syscalls/syscall_32.tbl:
# 251 is available for reuse (was briefly sys_set_zone_reclaim)
previously-invalid system call numbers may later be reused for new system
calls.
7. Most architecture+ABI combinations have system call tables with many gaps
in them. arm-eabi, for example, has 35 such gaps (note: this is just the
number of distinct gaps, not the number of system call numbers contained in
those gaps).
8. Seccomp's BPF filters require a fully-acyclic control flow graph.
Any operation on a data structure must therefore first be fully
unrolled before it can be run.
9. Seccomp cannot dereference pointers. Only the raw bits provided to the
system calls can be inspected.
10. Some architecture+ABI combos have multiplexer system calls. For example,
socketcall can perform any socket-related system call. The arguments to
the multiplexed system call are passed indirectly, via a pointer to user
memory. They therefore cannot be inspected by seccomp.
11. Some valid system calls are not listed in any table in the kernel source.
For example, __ARM_NR_cacheflush is an "ARM private" system call. It does
not appear in any *.tbl file.
12. Conditional branches are limited to relative jumps of at most 256
instructions forward.
13. Prior to Linux 4.8, any process able to spawn another process and call
ptrace could bypass seccomp restrictions.
To address (1), (2), and (3), we include preprocessor checks to identify the
native architecture value, and reject all system calls that don't use the
native architecture.
To address (4), we use the AC_C_BIGENDIAN autoconf check to conditionally
define WORDS_BIGENDIAN, and match up the proper portions of any uint64 we test
for with the value in the accumulator being tested against.
To address (5) and (6), we use system call pinning. That is, we hardcode a
snapshot of all the valid system call numbers at the time of writing, and
reject any system call numbers not in the recorded set. A set is recorded for
every architecture+ABI combo, and the native one is chosen at compile-time.
This ensures that not only are non-native architectures rejected, but so are
non-native ABIs. For the sake of conciseness, we represent these sets as sets
of disjoint ranges. Due to (7), checking each range in turn could add a lot
of overhead to each system call, so we instead binary search through the
ranges. Due to (8), this binary search has to be fully unrolled, so we do
that too.
It can be tedious and error-prone to manually produce the syscall ranges by
looking at linux's *.tbl files, since the gaps are often small and
uncommented. To address this, a script, build-aux/extract-syscall-ranges.sh,
is added that will produce them given a *.tbl filename and an ABI regex (some
tables seem to abuse the ABI field with strange values like "memfd_secret").
Note that producing the final values still requires looking at the proper
asm/unistd.h file to find any private numbers and to identify any offsets and
ABI variants used.
(10) used to have no good solution, but in the past decade most architectures
have gained dedicated system call alternatives to at least socketcall, so we
can (hopefully) just block it entirely.
To address (13), we block ptrace also.
* build-aux/extract-syscall-ranges.sh: new script.
* Makefile.am (EXTRA_DIST): register it.
* config-daemon.ac: use AC_C_BIGENDIAN.
* nix/libutil/spawn.cc (setNoNewPrivsAction, addSeccompFilterAction): new
functions.
* nix/libutil/spawn.hh (setNoNewPrivsAction, addSeccompFilterAction): new
declarations.
(SpawnContext)[setNoNewPrivs, addSeccompFilter]: new fields.
* nix/libutil/seccomp.hh: new header file.
* nix/libutil/seccomp.cc: new file.
* nix/local.mk (libutil_a_SOURCES, libutil_headers): register them.
* nix/libstore/build.cc (slirpSeccompFilter, writeSeccompFilterDot):
new functions.
(spawnSlirp4netns): use them, set seccomp filter for slirp4netns.
Change-Id: Ic92c7f564ab12596b87ed0801b22f88fbb543b95
Signed-off-by: John Kehayias <john.kehayias@protonmail.com>
Previously, the builder of a fixed-output derivation could communicate with an
external process via an abstract Unix-domain socket. In particular, it could
send an open file descriptor to the store, granting write access to some of
its output files in the store provided the derivation build fails—the fix for
CVE-2024-27297 did not address this specific case. It could also send an open
file descriptor to a setuid program, which could then be executed using
execveat to gain the privileges of the build user.
With this change, fixed-output derivations other than “builtin:download”
and “builtin:git-download” always run in a separate network namespace
and have network access provided by a TAP device backed by slirp4netns,
thereby closing the abstract Unix-domain socket channel.
* nix/libstore/globals.hh (Settings)[useHostLoopback, slirp4netns]: new
fields.
* config-daemon.ac (SLIRP4NETNS): new C preprocessor definition.
* nix/libstore/globals.cc (Settings::Settings): initialize them to defaults.
* nix/nix-daemon/guix-daemon.cc (options): add --isolate-host-loopback option.
* doc/guix.texi: document it.
* nix/libstore/build.cc (DerivationGoal)[slirp]: New field.
(setupTap, setupTapAction, waitForSlirpReadyAction, enableRouteLocalnetAction,
prepareSlirpChrootAction, spawnSlirp4netns, haveGlobalIPv6Address,
remapIdsTo0Action): New functions.
(initializeUserNamespace): allow the guest UID and GID to be specified.
(DerivationGoal::killChild): When ‘slirp’ is not -1, call ‘kill’.
(DerivationGoal::startBuilder): Unconditionally add CLONE_NEWNET to FLAGS.
When ‘fixedOutput’ is true, spawn ‘slirp4netns’.
When ‘fixedOutput’ and ‘useChroot’ are true, add setupTapAction,
waitForSlirpReadyAction, and enableRouteLocalnetAction to builder setup
phases.
Create a /etc/resolv.conf for fixed-output derivations that directs them to
slirp4netns's dns address.
When settings.useHostLoopback is true, supply fixed-output derivations with a
/etc/hosts that resolves "localhost" to slirp4netns's address for accessing
the host loopback.
* nix/libutil/util.cc (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
findProgram): New functions.
* nix/libutil/util.hh (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
findProgram): New declarations.
* gnu/packages/package-management.scm (guix): add slirp4netns input for linux
targets.
* tests/derivations.scm (builder-network-isolated?): new variable.
("fixed-output derivation, network access, localhost", "fixed-output
derivation, network access, external host"):
skip test case if fixed output derivations are isolated from the network.
Change-Id: Ia3fea2ab7add56df66800071cf15cdafe7bfab96
Signed-off-by: John Kehayias <john.kehayias@protonmail.com>
This adds a mechanism for manipulating and running "spawn phases" similarly to
how builder-side code manipulates "build phases". The main difference is that
spawn phases take a (reference to a) single structure that they can both read
from and write to, with their writes being visible to subsequent phases. The
base structure type for this is SpawnContext.
It also adds some predefined phase sequences, namely basicSpawnPhases and
cloneSpawnPhases, and exposes each of the actions performed by these phases.
Finally, it modifies build.cc to replace runChild() with use of this new code.
* nix/libutil/util.cc (keepOnExec, waitForMessage): new functions.
* nix/libutil.util.hh (keepOnExec, waitForMessage): add prototypes.
* nix/libutil/spawn.cc, nix/libutil/spawn.hh: new files.
(addPhaseAfter, addPhaseBefore, prependPhase, appendPhase, deletePhase,
replacePhase, reset_writeToStderrAction, restoreAffinityAction,
setsidAction, earlyIOSetupAction, dropAmbientCapabilitiesAction,
chrootAction, chdirAction, closeMostFDsAction, setPersonalityAction,
oomSacrificeAction, setIDsAction, restoreSIGPIPEAction, setupSuccessAction,
execAction, getBasicSpawnPhases, usernsInitSyncAction, usernsSetIDsAction,
initLoopbackAction, setHostAndDomainAction, makeFilesystemsPrivateAction,
makeChrootSeparateFilesystemAction, statfsToMountFlags, bindMount,
mountIntoChroot, mountIntoChrootAction, mountProcAction, mountDevshmAction,
mountDevptsAction, pivotRootAction, lockMountsAction, getCloneSpawnPhases,
runChildSetup, runChildSetupEntry, cloneChild, idMapToIdentityMap,
unshareAndInitUserns): new procedures.
* nix/local.mk (libutil_a_SOURCES): add spawn.cc.
(libutil_headers): add spawn.hh.
* nix/libstore/build.cc (restoreSIGPIPE, DerivationGoal::runChild,
childEntry): removed procedures.
(DerivationGoal::{dirsInChroot,env,readiness}): removed.
(execBuilderOrBuiltin, execBuilderOrBuiltinAction,
clearRootWritePermsAction): new procedures.
(DerivationGoal::startBuilder): modified to use a CloneSpawnContext if
chroot builds are available, otherwise a SpawnContext.
Change-Id: Ifd50110de077378ee151502eda62b99973d083bf
Change-Id: I76e10d3f928cc30566e1e6ca79077196972349f8
spawn.cc, util.cc, util.hh changes
Change-Id: I287320e63197cb4f65665ee5b3fdb3a0e125ebac
Signed-off-by: John Kehayias <john.kehayias@protonmail.com>
deletePath needs to be able to operate securely in unfriendly environments,
where adversaries may be concurrently modifying the files being operated on.
For example, directories that we are currently recursing through may be
replaced with symbolic links.
We err on the side of early failure here: if a file or directory is
concurrently modified in a way that causes one of the system calls to fail, we
throw an exception immediately instead of trying to adapt to the change.
Note that we use fstat instead of fstatat for verifying the directory's
st_mode field because AT_EMPTY_PATH is linux-specific.
* nix/libutil/util.cc (_deletePathAt): new procedure.
(_deletePath): use it.
Change-Id: I7ccfe6f1f74dbab95617b24034494e0f63030582
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Signed-off-by: John Kehayias <john.kehayias@protonmail.com>
* gnu/packages/python-xyz.scm (python-bitstruct): Update to 8.21.0.
[build-system]: Use pyproject.
[native-inputs]: Add python-pytest, python-setuptools-next, and
python-wheel.
[description]: Start from a new line, apply fill-column indentation.
Change-Id: I669b99d5687d173e9d9667d3e7339a2d5bf62006
* gnu/packages/emacs-xyz.scm (emacs-defaultencrypt): New variable.
(emacs-default-encrypt): Mark it as deprecated by the above.
Change-Id: I391e8edb489aa463344401fd691727734a47e428
Signed-off-by: Andreas Enge <andreas@enge.fr>