mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 03:55:08 -06:00
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>
161 lines
4.9 KiB
Text
161 lines
4.9 KiB
Text
dnl -*- Autoconf -*- fragment for the C++ daemon.
|
|
|
|
AC_MSG_CHECKING([whether to build daemon])
|
|
AC_MSG_RESULT([$guix_build_daemon])
|
|
|
|
dnl C++ environment. This macro must be used unconditionnaly.
|
|
AC_PROG_CXX
|
|
AM_PROG_AR
|
|
AC_LANG([C++])
|
|
|
|
if test "x$guix_build_daemon" = "xyes"; then
|
|
|
|
GUIX_ASSERT_CXX11
|
|
|
|
AC_PROG_RANLIB
|
|
AC_CONFIG_HEADERS([nix/config.h])
|
|
|
|
dnl Use 64-bit file system calls so that we can support files > 2 GiB.
|
|
AC_SYS_LARGEFILE
|
|
|
|
dnl Look for zlib, a required dependency.
|
|
AC_CHECK_LIB([z], [gzdopen], [true],
|
|
[AC_MSG_ERROR([Guix requires zlib. See http://www.zlib.net/.])])
|
|
AC_CHECK_HEADERS([zlib.h], [true],
|
|
[AC_MSG_ERROR([Guix requires zlib. See http://www.zlib.net/.])])
|
|
|
|
dnl Look for libbz2, an optional dependency.
|
|
AC_CHECK_LIB([bz2], [BZ2_bzWriteOpen], [HAVE_LIBBZ2=yes], [HAVE_LIBBZ2=no])
|
|
if test "x$HAVE_LIBBZ2" = xyes; then
|
|
AC_CHECK_HEADERS([bzlib.h])
|
|
HAVE_LIBBZ2="$ac_cv_header_bzlib_h"
|
|
fi
|
|
|
|
dnl Look for SQLite, a required dependency.
|
|
PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19])
|
|
|
|
AC_DEFINE_UNQUOTED([SYSTEM], ["$guix_system"],
|
|
[Guix host system type--i.e., platform and OS kernel tuple.])
|
|
|
|
case "$LIBGCRYPT_PREFIX" in
|
|
no)
|
|
LIBGCRYPT_CPPFLAGS=""
|
|
;;
|
|
*)
|
|
LIBGCRYPT_CPPFLAGS="-I$LIBGCRYPT_PREFIX/include"
|
|
;;
|
|
esac
|
|
|
|
case "$LIBGCRYPT_LIBDIR" in
|
|
no | "")
|
|
;;
|
|
*)
|
|
LIBGCRYPT_LDFLAGS="-L$LIBGCRYPT_LIBDIR"
|
|
;;
|
|
esac
|
|
|
|
LIBGCRYPT_LIBS="-lgcrypt"
|
|
AC_SUBST([LIBGCRYPT_CPPFLAGS])
|
|
AC_SUBST([LIBGCRYPT_LDFLAGS])
|
|
AC_SUBST([LIBGCRYPT_LIBS])
|
|
|
|
save_CPPFLAGS="$CPPFLAGS"
|
|
save_LDFLAGS="$LDFLAGS"
|
|
save_LIBS="$LIBS"
|
|
CPPFLAGS="$CPPFLAGS $LIBGCRYPT_CPPFLAGS"
|
|
LDFLAGS="$LDFLAGS $LIBGCRYPT_LDFLAGS"
|
|
LIBS="$LIBS $LIBGCRYPT_LIBS"
|
|
|
|
have_gcrypt=yes
|
|
AC_CHECK_LIB([gcrypt], [gcry_md_open], [:], [have_gcrypt=no])
|
|
AC_CHECK_HEADER([gcrypt.h], [:], [have_gcrypt=no])
|
|
if test "x$have_gcrypt" != "xyes"; then
|
|
AC_MSG_ERROR([GNU libgcrypt not found; please install it.])
|
|
fi
|
|
CPPFLAGS="$save_CPPFLAGS"
|
|
LDFLAGS="$save_LDFLAGS"
|
|
LIBS="$save_LIBS"
|
|
|
|
dnl Chroot support.
|
|
AC_CHECK_FUNCS([chroot unshare])
|
|
AC_CHECK_HEADERS([sched.h sys/param.h sys/mount.h sys/syscall.h \
|
|
linux/close_range.h sys/prctl.h])
|
|
|
|
if test "x$ac_cv_func_chroot" != "xyes"; then
|
|
AC_MSG_ERROR(['chroot' function missing, bailing out])
|
|
fi
|
|
|
|
dnl lutimes and lchown: used when canonicalizing store items.
|
|
dnl posix_fallocate: used when extracting archives.
|
|
dnl vfork: to speed up spawning of helper programs.
|
|
dnl `--> now disabled because of unpredictable behavior:
|
|
dnl see <http://lists.gnu.org/archive/html/guix-devel/2014-05/msg00036.html>
|
|
dnl and Nix commit f794465c (Nov. 2012).
|
|
dnl sched_setaffinity: to improve RPC locality.
|
|
dnl statvfs: to detect disk-full conditions.
|
|
dnl strsignal: for error reporting.
|
|
dnl statx: fine-grain 'stat' call, new in glibc 2.28.
|
|
AC_CHECK_FUNCS([lutimes lchown posix_fallocate sched_setaffinity \
|
|
statvfs nanosleep strsignal statx close_range])
|
|
|
|
dnl Check for <locale>.
|
|
AC_LANG_PUSH(C++)
|
|
AC_CHECK_HEADERS([locale])
|
|
AC_LANG_POP(C++)
|
|
|
|
|
|
dnl Check whether we have the `personality' syscall, which allows us
|
|
dnl to do i686-linux builds on x86_64-linux machines.
|
|
AC_CHECK_HEADERS([sys/personality.h])
|
|
|
|
dnl Determine the appropriate default list of substitute URLs (GnuTLS
|
|
dnl is required so we can default to 'https'.)
|
|
GUIX_SUBSTITUTE_URLS="https://bordeaux.guix.gnu.org https://ci.guix.gnu.org"
|
|
|
|
AC_MSG_CHECKING([for default substitute URLs])
|
|
AC_MSG_RESULT([$GUIX_SUBSTITUTE_URLS])
|
|
AC_SUBST([GUIX_SUBSTITUTE_URLS])
|
|
|
|
AC_DEFINE_UNQUOTED([GUIX_SUBSTITUTE_URLS], ["$GUIX_SUBSTITUTE_URLS"],
|
|
[Default list of substitute URLs used by 'guix-daemon'.])
|
|
|
|
dnl Check for Guile-SSH, which is required by 'guix offload'.
|
|
GUIX_CHECK_GUILE_SSH
|
|
|
|
case "x$guix_cv_have_recent_guile_ssh" in
|
|
xyes)
|
|
guix_build_daemon_offload="yes"
|
|
AC_DEFINE([HAVE_DAEMON_OFFLOAD_HOOK], [1],
|
|
[Define if the daemon's 'offload' build hook is being built (requires Guile-SSH).])
|
|
;;
|
|
*)
|
|
guix_build_daemon_offload="no"
|
|
;;
|
|
esac
|
|
|
|
dnl Temporary directory used to store the daemon's data.
|
|
GUIX_TEST_ROOT_DIRECTORY
|
|
GUIX_TEST_ROOT="$ac_cv_guix_test_root"
|
|
AC_SUBST([GUIX_TEST_ROOT])
|
|
|
|
GUIX_CHECK_LOCALSTATEDIR
|
|
|
|
case "x$host_os" in
|
|
x*linux*)
|
|
AC_CHECK_PROG([have_slirp4netns], [slirp4netns], [yes])
|
|
if test "x$have_slirp4netns" != "xyes"
|
|
then
|
|
AC_MSG_WARN([Slirp4netns not found; fixed-output chroot builds won't work without it.])
|
|
fi
|
|
;;
|
|
esac
|
|
AC_PATH_PROG([SLIRP4NETNS], [slirp4netns], [slirp4netns])
|
|
AC_DEFINE_UNQUOTED([SLIRP4NETNS], ["$SLIRP4NETNS"],
|
|
[Path to the slirp4netns program, if any.])
|
|
fi
|
|
|
|
AM_CONDITIONAL([HAVE_LIBBZ2], [test "x$HAVE_LIBBZ2" = "xyes"])
|
|
AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"])
|
|
AM_CONDITIONAL([BUILD_DAEMON_OFFLOAD], \
|
|
[test "x$guix_build_daemon" = "xyes" \
|
|
&& test "x$guix_build_daemon_offload" = "xyes"])
|