forked from lix-project/lix
Compare commits
28 commits
bbfeed2f00
...
ffd36e2852
Author | SHA1 | Date | |
---|---|---|---|
|
ffd36e2852 | ||
|
9a170bdf94 | ||
|
226f707486 | ||
|
2760818f06 | ||
|
eac3546d50 | ||
|
68937f2b64 | ||
|
218630a241 | ||
|
562ff516ab | ||
|
afeaa2371c | ||
|
c71f21da3a | ||
|
dd4a2c1759 | ||
|
a39ba22ff7 | ||
|
f0eb650ee8 | ||
|
d73c40ff3d | ||
|
74513483bc | ||
|
93ebb3e7df | ||
|
8b6d2d3915 | ||
|
f79ee66646 | ||
|
b910551120 | ||
|
5b5a75979a | ||
|
e81ed5f12d | ||
|
2473e1253d | ||
|
9a52e4688c | ||
|
8cd9aa24a8 | ||
|
6b5078c815 | ||
|
81bdf8d2d6 | ||
|
6fd6795bc4 | ||
|
ec5f025ec2 |
|
@ -11,6 +11,10 @@ additional-js = ["redirects.js"]
|
|||
# to just submit a Gerrit CL by the web for trivial stuff.
|
||||
edit-url-template = "https://github.com/lix-project/lix/tree/main/doc/manual/{path}"
|
||||
git-repository-url = "https://git.lix.systems/lix-project/lix"
|
||||
# Folding by default would prevent things like "Ctrl+F for nix-env" from working
|
||||
# trivially, but the user should be able to fold if they want to.
|
||||
fold.enable = true
|
||||
fold.level = 30
|
||||
|
||||
# Handles replacing @docroot@ with a path to ./src relative to that markdown file,
|
||||
# {{#include handlebars}}, and the @generated@ syntax used within these. it mostly
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
nixUnstable = prev.nixUnstable;
|
||||
|
||||
check-headers = final.buildPackages.callPackage ./maintainers/check-headers.nix { };
|
||||
check-syscalls = final.buildPackages.callPackage ./maintainers/check-syscalls.nix { };
|
||||
clangbuildanalyzer = final.buildPackages.callPackage ./misc/clangbuildanalyzer.nix { };
|
||||
|
||||
default-busybox-sandbox-shell = final.busybox.override {
|
||||
|
|
16
maintainers/check-syscalls.nix
Normal file
16
maintainers/check-syscalls.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
runCommandNoCC,
|
||||
lib,
|
||||
libseccomp,
|
||||
writeShellScriptBin,
|
||||
}:
|
||||
let
|
||||
syscalls-csv = runCommandNoCC "syscalls.csv" { } ''
|
||||
echo ${lib.escapeShellArg libseccomp.src}
|
||||
tar -xf ${lib.escapeShellArg libseccomp.src} --strip-components=2 ${libseccomp.name}/src/syscalls.csv
|
||||
mv syscalls.csv "$out"
|
||||
'';
|
||||
in
|
||||
writeShellScriptBin "check-syscalls" ''
|
||||
${./check-syscalls.sh} ${syscalls-csv}
|
||||
''
|
7
maintainers/check-syscalls.sh
Executable file
7
maintainers/check-syscalls.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
diff -u <(awk < src/libstore/build/local-derivation-goal.cc '/BEGIN extract-syscalls/ { extracting = 1; next }
|
||||
match($0, /allowSyscall\(ctx, SCMP_SYS\(([^)]*)\)\);|\/\/ skip ([^ ]*)/, result) { print result[1] result[2] }
|
||||
/END extract-syscalls/ { extracting = 0; next }') <(tail -n+2 "$1" | cut -d, -f 1)
|
93
package.nix
93
package.nix
|
@ -85,6 +85,7 @@
|
|||
let
|
||||
inherit (__forDefaults) canRunInstalled;
|
||||
inherit (lib) fileset;
|
||||
inherit (stdenv) hostPlatform buildPlatform;
|
||||
|
||||
version = lib.fileContents ./.version + versionSuffix;
|
||||
|
||||
|
@ -187,23 +188,23 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
dontBuild = false;
|
||||
|
||||
mesonFlags =
|
||||
lib.optionals stdenv.hostPlatform.isLinux [
|
||||
lib.optionals hostPlatform.isLinux [
|
||||
# You'd think meson could just find this in PATH, but busybox is in buildInputs,
|
||||
# which don't actually get added to PATH. And buildInputs is correct over
|
||||
# nativeBuildInputs since this should be a busybox executable on the host.
|
||||
"-Dsandbox-shell=${lib.getExe' busybox-sandbox-shell "busybox"}"
|
||||
]
|
||||
++ lib.optional stdenv.hostPlatform.isStatic "-Denable-embedded-sandbox-shell=true"
|
||||
++ lib.optional hostPlatform.isStatic "-Denable-embedded-sandbox-shell=true"
|
||||
++ lib.optional (finalAttrs.dontBuild) "-Denable-build=false"
|
||||
++ [
|
||||
# mesonConfigurePhase automatically passes -Dauto_features=enabled,
|
||||
# so we must explicitly enable or disable features that we are not passing
|
||||
# dependencies for.
|
||||
(lib.mesonEnable "internal-api-docs" internalApiDocs)
|
||||
(lib.mesonBool "enable-tests" finalAttrs.doCheck)
|
||||
(lib.mesonBool "enable-tests" finalAttrs.finalPackage.doCheck)
|
||||
(lib.mesonBool "enable-docs" canRunInstalled)
|
||||
]
|
||||
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--cross-file=${mesonCrossFile}";
|
||||
++ lib.optional (hostPlatform != buildPlatform) "--cross-file=${mesonCrossFile}";
|
||||
|
||||
# We only include CMake so that Meson can locate toml11, which only ships CMake dependency metadata.
|
||||
dontUseCmakeConfigure = true;
|
||||
|
@ -231,7 +232,7 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
jq
|
||||
lsof
|
||||
]
|
||||
++ lib.optional stdenv.hostPlatform.isLinux util-linuxMinimal
|
||||
++ lib.optional hostPlatform.isLinux util-linuxMinimal
|
||||
++ lib.optional (!officialRelease && buildUnreleasedNotes) build-release-notes
|
||||
++ lib.optional internalApiDocs doxygen;
|
||||
|
||||
|
@ -251,14 +252,14 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
toml11
|
||||
lix-doc
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
++ lib.optionals hostPlatform.isLinux [
|
||||
libseccomp
|
||||
busybox-sandbox-shell
|
||||
]
|
||||
++ lib.optional internalApiDocs rapidcheck
|
||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||
++ lib.optional hostPlatform.isx86_64 libcpuid
|
||||
# There have been issues building these dependencies
|
||||
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform) aws-sdk-cpp-nix
|
||||
++ lib.optional (hostPlatform == buildPlatform) aws-sdk-cpp-nix
|
||||
++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs;
|
||||
|
||||
checkInputs = [
|
||||
|
@ -278,18 +279,18 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
};
|
||||
|
||||
preConfigure =
|
||||
lib.optionalString (!finalAttrs.dontBuild && !stdenv.hostPlatform.isStatic) ''
|
||||
lib.optionalString (!finalAttrs.dontBuild && !hostPlatform.isStatic) ''
|
||||
# Copy libboost_context so we don't get all of Boost in our closure.
|
||||
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||
mkdir -p $out/lib
|
||||
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
|
||||
rm -f $out/lib/*.a
|
||||
''
|
||||
+ lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isLinux) ''
|
||||
+ lib.optionalString (!finalAttrs.dontBuild && hostPlatform.isLinux && !hostPlatform.isStatic) ''
|
||||
chmod u+w $out/lib/*.so.*
|
||||
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
|
||||
''
|
||||
+ lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isDarwin) ''
|
||||
+ lib.optionalString (!finalAttrs.dontBuild && hostPlatform.isDarwin) ''
|
||||
for LIB in $out/lib/*.dylib; do
|
||||
chmod u+w $LIB
|
||||
install_name_tool -id $LIB $LIB
|
||||
|
@ -333,7 +334,7 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
mkdir -p $doc/nix-support
|
||||
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
|
||||
''
|
||||
+ lib.optionalString stdenv.hostPlatform.isStatic ''
|
||||
+ lib.optionalString hostPlatform.isStatic ''
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
|
||||
''
|
||||
|
@ -364,12 +365,12 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
runHook postInstallCheck
|
||||
'';
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic && !finalAttrs.dontBuild;
|
||||
separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
# strictoverflow is disabled because we trap on signed overflow instead
|
||||
hardeningDisable = [ "strictoverflow" ] ++ lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
hardeningDisable = [ "strictoverflow" ] ++ lib.optional hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
mainProgram = "nix";
|
||||
|
@ -396,9 +397,10 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
llvmPackages,
|
||||
clangbuildanalyzer,
|
||||
contribNotice,
|
||||
check-syscalls,
|
||||
}:
|
||||
let
|
||||
glibcFix = lib.optionalAttrs (stdenv.buildPlatform.isLinux && glibcLocales != null) {
|
||||
glibcFix = lib.optionalAttrs (buildPlatform.isLinux && glibcLocales != null) {
|
||||
# Required to make non-NixOS Linux not complain about missing locale files during configure in a dev shell
|
||||
LOCALE_ARCHIVE = "${lib.getLib pkgs.glibcLocales}/lib/locale/locale-archive";
|
||||
};
|
||||
|
@ -416,14 +418,21 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
|
||||
name = "lix-shell-env";
|
||||
|
||||
inputsFrom = [ finalAttrs ];
|
||||
# finalPackage is necessary to propagate stuff that is set by mkDerivation itself,
|
||||
# like doCheck.
|
||||
inputsFrom = [ finalAttrs.finalPackage ];
|
||||
|
||||
# For Meson to find Boost.
|
||||
env = finalAttrs.env;
|
||||
|
||||
# I guess this is necessary because mesonFlags to mkDerivation doesn't propagate in inputsFrom,
|
||||
# which only propagates stuff set in hooks? idk.
|
||||
inherit (finalAttrs) mesonFlags;
|
||||
|
||||
packages =
|
||||
lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) clang-tools_llvm
|
||||
lib.optional (stdenv.cc.isClang && hostPlatform == buildPlatform) clang-tools_llvm
|
||||
++ [
|
||||
check-syscalls
|
||||
just
|
||||
nixfmt
|
||||
# Load-bearing order. Must come before clang-unwrapped below, but after clang_tools above.
|
||||
|
@ -435,37 +444,41 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
llvmPackages.clang-unwrapped.dev
|
||||
]
|
||||
++ lib.optional (pre-commit-checks ? enabledPackages) pre-commit-checks.enabledPackages
|
||||
++ lib.optional (lib.meta.availableOn stdenv.buildPlatform clangbuildanalyzer) clangbuildanalyzer
|
||||
++ lib.optional (lib.meta.availableOn buildPlatform clangbuildanalyzer) clangbuildanalyzer
|
||||
++ finalAttrs.checkInputs;
|
||||
|
||||
shellHook = ''
|
||||
# don't re-run the hook in (other) nested nix-shells
|
||||
if [[ $name != lix-shell-env ]]; then
|
||||
return;
|
||||
fi
|
||||
function lixShellHook() {
|
||||
if [[ $name != lix-shell-env ]]; then
|
||||
return;
|
||||
fi
|
||||
|
||||
PATH=$prefix/bin:$PATH
|
||||
unset PYTHONPATH
|
||||
export MANPATH=$out/share/man:$MANPATH
|
||||
PATH=$prefix/bin:$PATH
|
||||
unset PYTHONPATH
|
||||
export MANPATH=$out/share/man:$MANPATH
|
||||
|
||||
# Make bash completion work.
|
||||
XDG_DATA_DIRS+=:$out/share
|
||||
# Make bash completion work.
|
||||
XDG_DATA_DIRS+=:$out/share
|
||||
|
||||
${lib.optionalString (pre-commit-checks ? shellHook) pre-commit-checks.shellHook}
|
||||
# Allow `touch .nocontribmsg` to turn this notice off.
|
||||
if ! [[ -f .nocontribmsg ]]; then
|
||||
cat ${contribNotice}
|
||||
fi
|
||||
${lib.optionalString (pre-commit-checks ? shellHook) pre-commit-checks.shellHook}
|
||||
# Allow `touch .nocontribmsg` to turn this notice off.
|
||||
if ! [[ -f .nocontribmsg ]]; then
|
||||
cat ${contribNotice}
|
||||
fi
|
||||
|
||||
# Install the Gerrit commit-msg hook.
|
||||
# (git common dir is the main .git, including for worktrees)
|
||||
if gitcommondir=$(git rev-parse --git-common-dir 2>/dev/null) && [[ ! -f "$gitcommondir/hooks/commit-msg" ]]; then
|
||||
echo 'Installing Gerrit commit-msg hook (adds Change-Id to commit messages)' >&2
|
||||
mkdir -p "$gitcommondir/hooks"
|
||||
curl -s -Lo "$gitcommondir/hooks/commit-msg" https://gerrit.lix.systems/tools/hooks/commit-msg
|
||||
chmod u+x "$gitcommondir/hooks/commit-msg"
|
||||
fi
|
||||
unset gitcommondir
|
||||
# Install the Gerrit commit-msg hook.
|
||||
# (git common dir is the main .git, including for worktrees)
|
||||
if gitcommondir=$(git rev-parse --git-common-dir 2>/dev/null) && [[ ! -f "$gitcommondir/hooks/commit-msg" ]]; then
|
||||
echo 'Installing Gerrit commit-msg hook (adds Change-Id to commit messages)' >&2
|
||||
mkdir -p "$gitcommondir/hooks"
|
||||
curl -s -Lo "$gitcommondir/hooks/commit-msg" https://gerrit.lix.systems/tools/hooks/commit-msg
|
||||
chmod u+x "$gitcommondir/hooks/commit-msg"
|
||||
fi
|
||||
unset gitcommondir
|
||||
}
|
||||
|
||||
lixShellHook
|
||||
'';
|
||||
}
|
||||
);
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "derivations.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "crypto.hh"
|
||||
|
||||
#include <sodium.h>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "common-eval-args.hh"
|
||||
#include "shared.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "util.hh"
|
||||
#include "eval.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "registry.hh"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "util.hh"
|
||||
#include "editor-for.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "source-path.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "globals.hh"
|
||||
#include "installable-attr-path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "globals.hh"
|
||||
#include "installable-value.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "installable-flake.hh"
|
||||
#include "installable-derived-path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
|
|
|
@ -3,26 +3,21 @@
|
|||
#include "installable-derived-path.hh"
|
||||
#include "installable-attr-path.hh"
|
||||
#include "installable-flake.hh"
|
||||
#include "logging.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "derivations.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "shared.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "derived-path.hh"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "markdown.hh"
|
||||
#include "util.hh"
|
||||
#include "error.hh"
|
||||
#include "finally.hh"
|
||||
#include "terminal.hh"
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <lowdown.h>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#include "error.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
@ -18,11 +22,8 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
#include "signals.hh"
|
||||
#include "finally.hh"
|
||||
#include "repl-interacter.hh"
|
||||
#include "util.hh"
|
||||
#include "repl.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "print.hh"
|
||||
#include "progress-bar.hh"
|
||||
#include "gc-small-vector.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
#define GC_INCLUDE_NEW
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "attr-path.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "util.hh"
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "eval-cache.hh"
|
||||
#include "sqlite.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "store-api.hh"
|
||||
#include "users.hh"
|
||||
|
||||
namespace nix::eval_cache {
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "file-system.hh"
|
||||
#include "globals.hh"
|
||||
#include "profiles.hh"
|
||||
#include "eval.hh"
|
||||
#include "users.hh"
|
||||
#include "eval-settings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "print-options.hh"
|
||||
#include "shared.hh"
|
||||
#include "types.hh"
|
||||
#include "util.hh"
|
||||
#include "store-api.hh"
|
||||
#include "derivations.hh"
|
||||
#include "downstream-placeholder.hh"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "flake.hh"
|
||||
#include "globals.hh"
|
||||
#include "logging.hh"
|
||||
#include "users.hh"
|
||||
#include "fetch-settings.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "fetchers.hh"
|
||||
#include "finally.hh"
|
||||
#include "fetch-settings.hh"
|
||||
#include "terminal.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "get-drvs.hh"
|
||||
#include "util.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "derivations.hh"
|
||||
#include "eval.hh"
|
||||
#include "symbol-table.hh"
|
||||
#include "util.hh"
|
||||
#include "print.hh"
|
||||
#include "escape-string.hh"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <variant>
|
||||
|
||||
#include "finally.hh"
|
||||
#include "util.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include "nixexpr.hh"
|
||||
#include "eval.hh"
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "json-to-value.hh"
|
||||
#include "names.hh"
|
||||
#include "path-references.hh"
|
||||
#include "processes.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "value-to-json.hh"
|
||||
#include "value-to-xml.hh"
|
||||
#include "primops.hh"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "print-ambiguous.hh"
|
||||
#include "attr-set.hh"
|
||||
#include "logging.hh"
|
||||
#include "print.hh"
|
||||
#include "eval.hh"
|
||||
#include "signals.hh"
|
||||
#include "escape-string.hh"
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "english.hh"
|
||||
#include "signals.hh"
|
||||
#include "eval.hh"
|
||||
#include "terminal.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "search-path.hh"
|
||||
#include "util.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "value-to-json.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "util.hh"
|
||||
#include "signals.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#include "value-to-xml.hh"
|
||||
#include "xml-writer.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "util.hh"
|
||||
#include "signals.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "comparator.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "variant-wrapper.hh"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "sqlite.hh"
|
||||
#include "sync.hh"
|
||||
#include "store-api.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "types.hh"
|
||||
#include "config.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <map>
|
||||
#include <limits>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "source-path.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "repair-flag.hh"
|
||||
#include "content-address.hh"
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "fetchers.hh"
|
||||
#include "cache.hh"
|
||||
#include "globals.hh"
|
||||
#include "processes.hh"
|
||||
#include "tarfile.hh"
|
||||
#include "store-api.hh"
|
||||
#include "url-parts.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "util.hh"
|
||||
#include "users.hh"
|
||||
#include "git.hh"
|
||||
#include "logging.hh"
|
||||
#include "finally.hh"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "fetchers.hh"
|
||||
#include "cache.hh"
|
||||
#include "globals.hh"
|
||||
#include "tarfile.hh"
|
||||
#include "processes.hh"
|
||||
#include "store-api.hh"
|
||||
#include "url-parts.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include "fetch-settings.hh"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "registry.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "util.hh"
|
||||
#include "users.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "local-fs-store.hh"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "args/root.hh"
|
||||
#include "globals.hh"
|
||||
#include "loggers.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "environment-variables.hh"
|
||||
#include "loggers.hh"
|
||||
#include "progress-bar.hh"
|
||||
#include "util.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "progress-bar.hh"
|
||||
#include "util.hh"
|
||||
#include "sync.hh"
|
||||
#include "store-api.hh"
|
||||
#include "names.hh"
|
||||
#include "terminal.hh"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
#include "gc-store.hh"
|
||||
#include "util.hh"
|
||||
#include "signals.hh"
|
||||
#include "loggers.hh"
|
||||
#include "progress-bar.hh"
|
||||
#include "current-process.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "args.hh"
|
||||
#include "args/root.hh"
|
||||
#include "common-args.hh"
|
||||
#include "path.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "processes.hh"
|
||||
#include "exit.hh"
|
||||
|
||||
#include <signal.h>
|
||||
|
|
33
src/libstore/build/child.cc
Normal file
33
src/libstore/build/child.cc
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "current-process.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void commonChildInit()
|
||||
{
|
||||
logger = makeSimpleLogger();
|
||||
|
||||
const static std::string pathNullDevice = "/dev/null";
|
||||
restoreProcessContext(false);
|
||||
|
||||
/* Put the child in a separate session (and thus a separate
|
||||
process group) so that it has no controlling terminal (meaning
|
||||
that e.g. ssh cannot open /dev/tty) and it doesn't receive
|
||||
terminal signals. */
|
||||
if (setsid() == -1)
|
||||
throw SysError("creating a new session");
|
||||
|
||||
/* Dup stderr to stdout. */
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
|
||||
throw SysError("cannot dup stderr into stdout");
|
||||
|
||||
/* Reroute stdin to /dev/null. */
|
||||
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
||||
if (fdDevNull == -1)
|
||||
throw SysError("cannot open '%1%'", pathNullDevice);
|
||||
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
||||
throw SysError("cannot dup null device into stdin");
|
||||
close(fdDevNull);
|
||||
}
|
||||
|
||||
}
|
11
src/libstore/build/child.hh
Normal file
11
src/libstore/build/child.hh
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Common initialisation performed in child processes.
|
||||
*/
|
||||
void commonChildInit();
|
||||
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
#include "builtins/buildenv.hh"
|
||||
#include "references.hh"
|
||||
#include "finally.hh"
|
||||
#include "util.hh"
|
||||
#include "archive.hh"
|
||||
#include "compression.hh"
|
||||
#include "common-protocol.hh"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "child.hh"
|
||||
#include "file-system.hh"
|
||||
#include "globals.hh"
|
||||
#include "hook-instance.hh"
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
///@file
|
||||
|
||||
#include "logging.hh"
|
||||
#include "processes.hh"
|
||||
#include "serialise.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "builtins/buildenv.hh"
|
||||
#include "path-references.hh"
|
||||
#include "finally.hh"
|
||||
#include "util.hh"
|
||||
#include "archive.hh"
|
||||
#include "compression.hh"
|
||||
#include "daemon.hh"
|
||||
|
@ -15,6 +14,8 @@
|
|||
#include "cgroup.hh"
|
||||
#include "personality.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "child.hh"
|
||||
#include "unix-domain-socket.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
|
@ -43,7 +44,6 @@
|
|||
#include <sys/prctl.h>
|
||||
#include <sys/syscall.h>
|
||||
#if HAVE_SECCOMP
|
||||
#include "linux/fchmodat2-compat.hh"
|
||||
#include <seccomp.h>
|
||||
#endif
|
||||
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
|
||||
|
@ -63,6 +63,11 @@ extern "C" int sandbox_init_with_parameters(const char *profile, uint64_t flags,
|
|||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* The system for which Nix is compiled.
|
||||
*/
|
||||
constexpr std::string_view nativeSystem = SYSTEM;
|
||||
|
||||
void handleDiffHook(
|
||||
uid_t uid, uid_t gid,
|
||||
const Path & tryA, const Path & tryB,
|
||||
|
@ -1608,6 +1613,12 @@ void LocalDerivationGoal::chownToBuilder(const Path & path)
|
|||
throw SysError("cannot change ownership of '%1%'", path);
|
||||
}
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void allowSyscall(scmp_filter_ctx ctx, int syscall) {
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscall, 0) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupSeccomp()
|
||||
{
|
||||
|
@ -1615,7 +1626,9 @@ void setupSeccomp()
|
|||
#if HAVE_SECCOMP
|
||||
scmp_filter_ctx ctx;
|
||||
|
||||
if (!(ctx = seccomp_init(SCMP_ACT_ALLOW)))
|
||||
// Pretend that syscalls we don't yet know about don't exist.
|
||||
// This is the best option for compatibility: after all, they did in fact not exist not too long ago.
|
||||
if (!(ctx = seccomp_init(SCMP_ACT_ERRNO(ENOSYS))))
|
||||
throw SysError("unable to initialize seccomp mode 2");
|
||||
|
||||
Finally cleanup([&]() {
|
||||
|
@ -1650,28 +1663,520 @@ void setupSeccomp()
|
|||
seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32) != 0)
|
||||
printError("unable to add mips64el-*abin32 seccomp architecture");
|
||||
|
||||
/* Prevent builders from creating setuid/setgid binaries. */
|
||||
for (int perm : { S_ISUID, S_ISGID }) {
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
// This list is intended for machine consumption.
|
||||
// Please keep its format, order and BEGIN/END markers.
|
||||
//
|
||||
// Currently, it is up to date with libseccomp 2.5.5 and glibc 2.38.
|
||||
// Run check-syscalls to determine which new syscalls should be added.
|
||||
// New syscalls must be audited and handled in a way that blocks the following dangerous operations:
|
||||
// * Creation of non-empty setuid/setgid files
|
||||
// * Creation of extended attributes (including ACLs)
|
||||
//
|
||||
// BEGIN extract-syscalls
|
||||
allowSyscall(ctx, SCMP_SYS(accept));
|
||||
allowSyscall(ctx, SCMP_SYS(accept4));
|
||||
allowSyscall(ctx, SCMP_SYS(access));
|
||||
allowSyscall(ctx, SCMP_SYS(acct));
|
||||
allowSyscall(ctx, SCMP_SYS(add_key));
|
||||
allowSyscall(ctx, SCMP_SYS(adjtimex));
|
||||
allowSyscall(ctx, SCMP_SYS(afs_syscall));
|
||||
allowSyscall(ctx, SCMP_SYS(alarm));
|
||||
allowSyscall(ctx, SCMP_SYS(arch_prctl));
|
||||
allowSyscall(ctx, SCMP_SYS(arm_fadvise64_64));
|
||||
allowSyscall(ctx, SCMP_SYS(arm_sync_file_range));
|
||||
allowSyscall(ctx, SCMP_SYS(bdflush));
|
||||
allowSyscall(ctx, SCMP_SYS(bind));
|
||||
allowSyscall(ctx, SCMP_SYS(bpf));
|
||||
allowSyscall(ctx, SCMP_SYS(break));
|
||||
allowSyscall(ctx, SCMP_SYS(breakpoint));
|
||||
allowSyscall(ctx, SCMP_SYS(brk));
|
||||
allowSyscall(ctx, SCMP_SYS(cachectl));
|
||||
allowSyscall(ctx, SCMP_SYS(cacheflush));
|
||||
allowSyscall(ctx, SCMP_SYS(cachestat));
|
||||
allowSyscall(ctx, SCMP_SYS(capget));
|
||||
allowSyscall(ctx, SCMP_SYS(capset));
|
||||
allowSyscall(ctx, SCMP_SYS(chdir));
|
||||
// skip chmod (dangerous)
|
||||
allowSyscall(ctx, SCMP_SYS(chown));
|
||||
allowSyscall(ctx, SCMP_SYS(chown32));
|
||||
allowSyscall(ctx, SCMP_SYS(chroot));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_adjtime));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_adjtime64));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_getres));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_getres_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_gettime));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_gettime64));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_nanosleep));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_nanosleep_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_settime));
|
||||
allowSyscall(ctx, SCMP_SYS(clock_settime64));
|
||||
allowSyscall(ctx, SCMP_SYS(clone));
|
||||
allowSyscall(ctx, SCMP_SYS(clone3));
|
||||
allowSyscall(ctx, SCMP_SYS(close));
|
||||
allowSyscall(ctx, SCMP_SYS(close_range));
|
||||
allowSyscall(ctx, SCMP_SYS(connect));
|
||||
allowSyscall(ctx, SCMP_SYS(copy_file_range));
|
||||
allowSyscall(ctx, SCMP_SYS(creat));
|
||||
allowSyscall(ctx, SCMP_SYS(create_module));
|
||||
allowSyscall(ctx, SCMP_SYS(delete_module));
|
||||
allowSyscall(ctx, SCMP_SYS(dup));
|
||||
allowSyscall(ctx, SCMP_SYS(dup2));
|
||||
allowSyscall(ctx, SCMP_SYS(dup3));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_create));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_create1));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_ctl));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_ctl_old));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_pwait));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_pwait2));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_wait));
|
||||
allowSyscall(ctx, SCMP_SYS(epoll_wait_old));
|
||||
allowSyscall(ctx, SCMP_SYS(eventfd));
|
||||
allowSyscall(ctx, SCMP_SYS(eventfd2));
|
||||
allowSyscall(ctx, SCMP_SYS(execve));
|
||||
allowSyscall(ctx, SCMP_SYS(execveat));
|
||||
allowSyscall(ctx, SCMP_SYS(exit));
|
||||
allowSyscall(ctx, SCMP_SYS(exit_group));
|
||||
allowSyscall(ctx, SCMP_SYS(faccessat));
|
||||
allowSyscall(ctx, SCMP_SYS(faccessat2));
|
||||
allowSyscall(ctx, SCMP_SYS(fadvise64));
|
||||
allowSyscall(ctx, SCMP_SYS(fadvise64_64));
|
||||
allowSyscall(ctx, SCMP_SYS(fallocate));
|
||||
allowSyscall(ctx, SCMP_SYS(fanotify_init));
|
||||
allowSyscall(ctx, SCMP_SYS(fanotify_mark));
|
||||
allowSyscall(ctx, SCMP_SYS(fchdir));
|
||||
// skip fchmod (dangerous)
|
||||
// skip fchmodat (dangerous)
|
||||
// skip fchmodat2 (requires glibc 2.39, dangerous)
|
||||
allowSyscall(ctx, SCMP_SYS(fchown));
|
||||
allowSyscall(ctx, SCMP_SYS(fchown32));
|
||||
allowSyscall(ctx, SCMP_SYS(fchownat));
|
||||
allowSyscall(ctx, SCMP_SYS(fcntl));
|
||||
allowSyscall(ctx, SCMP_SYS(fcntl64));
|
||||
allowSyscall(ctx, SCMP_SYS(fdatasync));
|
||||
allowSyscall(ctx, SCMP_SYS(fgetxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(finit_module));
|
||||
allowSyscall(ctx, SCMP_SYS(flistxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(flock));
|
||||
allowSyscall(ctx, SCMP_SYS(fork));
|
||||
allowSyscall(ctx, SCMP_SYS(fremovexattr));
|
||||
allowSyscall(ctx, SCMP_SYS(fsconfig));
|
||||
// skip fsetxattr (dangerous)
|
||||
allowSyscall(ctx, SCMP_SYS(fsmount));
|
||||
allowSyscall(ctx, SCMP_SYS(fsopen));
|
||||
allowSyscall(ctx, SCMP_SYS(fspick));
|
||||
allowSyscall(ctx, SCMP_SYS(fstat));
|
||||
allowSyscall(ctx, SCMP_SYS(fstat64));
|
||||
allowSyscall(ctx, SCMP_SYS(fstatat64));
|
||||
allowSyscall(ctx, SCMP_SYS(fstatfs));
|
||||
allowSyscall(ctx, SCMP_SYS(fstatfs64));
|
||||
allowSyscall(ctx, SCMP_SYS(fsync));
|
||||
allowSyscall(ctx, SCMP_SYS(ftime));
|
||||
allowSyscall(ctx, SCMP_SYS(ftruncate));
|
||||
allowSyscall(ctx, SCMP_SYS(ftruncate64));
|
||||
allowSyscall(ctx, SCMP_SYS(futex));
|
||||
// skip futex_requeue (requires glibc 2.39)
|
||||
allowSyscall(ctx, SCMP_SYS(futex_time64));
|
||||
// skip futex_wait (requires glibc 2.39)
|
||||
allowSyscall(ctx, SCMP_SYS(futex_waitv));
|
||||
// skip futex_wake (requires glibc 2.39)
|
||||
allowSyscall(ctx, SCMP_SYS(futimesat));
|
||||
allowSyscall(ctx, SCMP_SYS(getcpu));
|
||||
allowSyscall(ctx, SCMP_SYS(getcwd));
|
||||
allowSyscall(ctx, SCMP_SYS(getdents));
|
||||
allowSyscall(ctx, SCMP_SYS(getdents64));
|
||||
allowSyscall(ctx, SCMP_SYS(getegid));
|
||||
allowSyscall(ctx, SCMP_SYS(getegid32));
|
||||
allowSyscall(ctx, SCMP_SYS(geteuid));
|
||||
allowSyscall(ctx, SCMP_SYS(geteuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(getgid));
|
||||
allowSyscall(ctx, SCMP_SYS(getgid32));
|
||||
allowSyscall(ctx, SCMP_SYS(getgroups));
|
||||
allowSyscall(ctx, SCMP_SYS(getgroups32));
|
||||
allowSyscall(ctx, SCMP_SYS(getitimer));
|
||||
allowSyscall(ctx, SCMP_SYS(get_kernel_syms));
|
||||
allowSyscall(ctx, SCMP_SYS(get_mempolicy));
|
||||
allowSyscall(ctx, SCMP_SYS(getpeername));
|
||||
allowSyscall(ctx, SCMP_SYS(getpgid));
|
||||
allowSyscall(ctx, SCMP_SYS(getpgrp));
|
||||
allowSyscall(ctx, SCMP_SYS(getpid));
|
||||
allowSyscall(ctx, SCMP_SYS(getpmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(getppid));
|
||||
allowSyscall(ctx, SCMP_SYS(getpriority));
|
||||
allowSyscall(ctx, SCMP_SYS(getrandom));
|
||||
allowSyscall(ctx, SCMP_SYS(getresgid));
|
||||
allowSyscall(ctx, SCMP_SYS(getresgid32));
|
||||
allowSyscall(ctx, SCMP_SYS(getresuid));
|
||||
allowSyscall(ctx, SCMP_SYS(getresuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(getrlimit));
|
||||
allowSyscall(ctx, SCMP_SYS(get_robust_list));
|
||||
allowSyscall(ctx, SCMP_SYS(getrusage));
|
||||
allowSyscall(ctx, SCMP_SYS(getsid));
|
||||
allowSyscall(ctx, SCMP_SYS(getsockname));
|
||||
allowSyscall(ctx, SCMP_SYS(getsockopt));
|
||||
allowSyscall(ctx, SCMP_SYS(get_thread_area));
|
||||
allowSyscall(ctx, SCMP_SYS(gettid));
|
||||
allowSyscall(ctx, SCMP_SYS(gettimeofday));
|
||||
allowSyscall(ctx, SCMP_SYS(get_tls));
|
||||
allowSyscall(ctx, SCMP_SYS(getuid));
|
||||
allowSyscall(ctx, SCMP_SYS(getuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(getxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(gtty));
|
||||
allowSyscall(ctx, SCMP_SYS(idle));
|
||||
allowSyscall(ctx, SCMP_SYS(init_module));
|
||||
allowSyscall(ctx, SCMP_SYS(inotify_add_watch));
|
||||
allowSyscall(ctx, SCMP_SYS(inotify_init));
|
||||
allowSyscall(ctx, SCMP_SYS(inotify_init1));
|
||||
allowSyscall(ctx, SCMP_SYS(inotify_rm_watch));
|
||||
allowSyscall(ctx, SCMP_SYS(io_cancel));
|
||||
allowSyscall(ctx, SCMP_SYS(ioctl));
|
||||
allowSyscall(ctx, SCMP_SYS(io_destroy));
|
||||
allowSyscall(ctx, SCMP_SYS(io_getevents));
|
||||
allowSyscall(ctx, SCMP_SYS(ioperm));
|
||||
allowSyscall(ctx, SCMP_SYS(io_pgetevents));
|
||||
allowSyscall(ctx, SCMP_SYS(io_pgetevents_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(iopl));
|
||||
allowSyscall(ctx, SCMP_SYS(ioprio_get));
|
||||
allowSyscall(ctx, SCMP_SYS(ioprio_set));
|
||||
allowSyscall(ctx, SCMP_SYS(io_setup));
|
||||
allowSyscall(ctx, SCMP_SYS(io_submit));
|
||||
allowSyscall(ctx, SCMP_SYS(io_uring_enter));
|
||||
allowSyscall(ctx, SCMP_SYS(io_uring_register));
|
||||
allowSyscall(ctx, SCMP_SYS(io_uring_setup));
|
||||
allowSyscall(ctx, SCMP_SYS(ipc));
|
||||
allowSyscall(ctx, SCMP_SYS(kcmp));
|
||||
allowSyscall(ctx, SCMP_SYS(kexec_file_load));
|
||||
allowSyscall(ctx, SCMP_SYS(kexec_load));
|
||||
allowSyscall(ctx, SCMP_SYS(keyctl));
|
||||
allowSyscall(ctx, SCMP_SYS(kill));
|
||||
allowSyscall(ctx, SCMP_SYS(landlock_add_rule));
|
||||
allowSyscall(ctx, SCMP_SYS(landlock_create_ruleset));
|
||||
allowSyscall(ctx, SCMP_SYS(landlock_restrict_self));
|
||||
allowSyscall(ctx, SCMP_SYS(lchown));
|
||||
allowSyscall(ctx, SCMP_SYS(lchown32));
|
||||
allowSyscall(ctx, SCMP_SYS(lgetxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(link));
|
||||
allowSyscall(ctx, SCMP_SYS(linkat));
|
||||
allowSyscall(ctx, SCMP_SYS(listen));
|
||||
allowSyscall(ctx, SCMP_SYS(listxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(llistxattr));
|
||||
allowSyscall(ctx, SCMP_SYS(_llseek));
|
||||
allowSyscall(ctx, SCMP_SYS(lock));
|
||||
allowSyscall(ctx, SCMP_SYS(lookup_dcookie));
|
||||
allowSyscall(ctx, SCMP_SYS(lremovexattr));
|
||||
allowSyscall(ctx, SCMP_SYS(lseek));
|
||||
// skip lsetxattr (dangerous)
|
||||
allowSyscall(ctx, SCMP_SYS(lstat));
|
||||
allowSyscall(ctx, SCMP_SYS(lstat64));
|
||||
allowSyscall(ctx, SCMP_SYS(madvise));
|
||||
// skip map_shadow_stack (requires glibc 2.39)
|
||||
allowSyscall(ctx, SCMP_SYS(mbind));
|
||||
allowSyscall(ctx, SCMP_SYS(membarrier));
|
||||
allowSyscall(ctx, SCMP_SYS(memfd_create));
|
||||
allowSyscall(ctx, SCMP_SYS(memfd_secret));
|
||||
allowSyscall(ctx, SCMP_SYS(migrate_pages));
|
||||
allowSyscall(ctx, SCMP_SYS(mincore));
|
||||
allowSyscall(ctx, SCMP_SYS(mkdir));
|
||||
allowSyscall(ctx, SCMP_SYS(mkdirat));
|
||||
allowSyscall(ctx, SCMP_SYS(mknod));
|
||||
allowSyscall(ctx, SCMP_SYS(mknodat));
|
||||
allowSyscall(ctx, SCMP_SYS(mlock));
|
||||
allowSyscall(ctx, SCMP_SYS(mlock2));
|
||||
allowSyscall(ctx, SCMP_SYS(mlockall));
|
||||
allowSyscall(ctx, SCMP_SYS(mmap));
|
||||
allowSyscall(ctx, SCMP_SYS(mmap2));
|
||||
allowSyscall(ctx, SCMP_SYS(modify_ldt));
|
||||
allowSyscall(ctx, SCMP_SYS(mount));
|
||||
allowSyscall(ctx, SCMP_SYS(mount_setattr));
|
||||
allowSyscall(ctx, SCMP_SYS(move_mount));
|
||||
allowSyscall(ctx, SCMP_SYS(move_pages));
|
||||
allowSyscall(ctx, SCMP_SYS(mprotect));
|
||||
allowSyscall(ctx, SCMP_SYS(mpx));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_getsetattr));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_notify));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_open));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_timedreceive));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_timedreceive_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_timedsend));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_timedsend_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(mq_unlink));
|
||||
allowSyscall(ctx, SCMP_SYS(mremap));
|
||||
allowSyscall(ctx, SCMP_SYS(msgctl));
|
||||
allowSyscall(ctx, SCMP_SYS(msgget));
|
||||
allowSyscall(ctx, SCMP_SYS(msgrcv));
|
||||
allowSyscall(ctx, SCMP_SYS(msgsnd));
|
||||
allowSyscall(ctx, SCMP_SYS(msync));
|
||||
allowSyscall(ctx, SCMP_SYS(multiplexer));
|
||||
allowSyscall(ctx, SCMP_SYS(munlock));
|
||||
allowSyscall(ctx, SCMP_SYS(munlockall));
|
||||
allowSyscall(ctx, SCMP_SYS(munmap));
|
||||
allowSyscall(ctx, SCMP_SYS(name_to_handle_at));
|
||||
allowSyscall(ctx, SCMP_SYS(nanosleep));
|
||||
allowSyscall(ctx, SCMP_SYS(newfstatat));
|
||||
allowSyscall(ctx, SCMP_SYS(_newselect));
|
||||
allowSyscall(ctx, SCMP_SYS(nfsservctl));
|
||||
allowSyscall(ctx, SCMP_SYS(nice));
|
||||
allowSyscall(ctx, SCMP_SYS(oldfstat));
|
||||
allowSyscall(ctx, SCMP_SYS(oldlstat));
|
||||
allowSyscall(ctx, SCMP_SYS(oldolduname));
|
||||
allowSyscall(ctx, SCMP_SYS(oldstat));
|
||||
allowSyscall(ctx, SCMP_SYS(olduname));
|
||||
allowSyscall(ctx, SCMP_SYS(open));
|
||||
allowSyscall(ctx, SCMP_SYS(openat));
|
||||
allowSyscall(ctx, SCMP_SYS(openat2));
|
||||
allowSyscall(ctx, SCMP_SYS(open_by_handle_at));
|
||||
allowSyscall(ctx, SCMP_SYS(open_tree));
|
||||
allowSyscall(ctx, SCMP_SYS(pause));
|
||||
allowSyscall(ctx, SCMP_SYS(pciconfig_iobase));
|
||||
allowSyscall(ctx, SCMP_SYS(pciconfig_read));
|
||||
allowSyscall(ctx, SCMP_SYS(pciconfig_write));
|
||||
allowSyscall(ctx, SCMP_SYS(perf_event_open));
|
||||
allowSyscall(ctx, SCMP_SYS(personality));
|
||||
allowSyscall(ctx, SCMP_SYS(pidfd_getfd));
|
||||
allowSyscall(ctx, SCMP_SYS(pidfd_open));
|
||||
allowSyscall(ctx, SCMP_SYS(pidfd_send_signal));
|
||||
allowSyscall(ctx, SCMP_SYS(pipe));
|
||||
allowSyscall(ctx, SCMP_SYS(pipe2));
|
||||
allowSyscall(ctx, SCMP_SYS(pivot_root));
|
||||
allowSyscall(ctx, SCMP_SYS(pkey_alloc));
|
||||
allowSyscall(ctx, SCMP_SYS(pkey_free));
|
||||
allowSyscall(ctx, SCMP_SYS(pkey_mprotect));
|
||||
allowSyscall(ctx, SCMP_SYS(poll));
|
||||
allowSyscall(ctx, SCMP_SYS(ppoll));
|
||||
allowSyscall(ctx, SCMP_SYS(ppoll_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(prctl));
|
||||
allowSyscall(ctx, SCMP_SYS(pread64));
|
||||
allowSyscall(ctx, SCMP_SYS(preadv));
|
||||
allowSyscall(ctx, SCMP_SYS(preadv2));
|
||||
allowSyscall(ctx, SCMP_SYS(prlimit64));
|
||||
allowSyscall(ctx, SCMP_SYS(process_madvise));
|
||||
allowSyscall(ctx, SCMP_SYS(process_mrelease));
|
||||
allowSyscall(ctx, SCMP_SYS(process_vm_readv));
|
||||
allowSyscall(ctx, SCMP_SYS(process_vm_writev));
|
||||
allowSyscall(ctx, SCMP_SYS(prof));
|
||||
allowSyscall(ctx, SCMP_SYS(profil));
|
||||
allowSyscall(ctx, SCMP_SYS(pselect6));
|
||||
allowSyscall(ctx, SCMP_SYS(pselect6_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(ptrace));
|
||||
allowSyscall(ctx, SCMP_SYS(putpmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(pwrite64));
|
||||
allowSyscall(ctx, SCMP_SYS(pwritev));
|
||||
allowSyscall(ctx, SCMP_SYS(pwritev2));
|
||||
allowSyscall(ctx, SCMP_SYS(query_module));
|
||||
allowSyscall(ctx, SCMP_SYS(quotactl));
|
||||
allowSyscall(ctx, SCMP_SYS(quotactl_fd));
|
||||
allowSyscall(ctx, SCMP_SYS(read));
|
||||
allowSyscall(ctx, SCMP_SYS(readahead));
|
||||
allowSyscall(ctx, SCMP_SYS(readdir));
|
||||
allowSyscall(ctx, SCMP_SYS(readlink));
|
||||
allowSyscall(ctx, SCMP_SYS(readlinkat));
|
||||
allowSyscall(ctx, SCMP_SYS(readv));
|
||||
allowSyscall(ctx, SCMP_SYS(reboot));
|
||||
allowSyscall(ctx, SCMP_SYS(recv));
|
||||
allowSyscall(ctx, SCMP_SYS(recvfrom));
|
||||
allowSyscall(ctx, SCMP_SYS(recvmmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(recvmmsg_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(recvmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(remap_file_pages));
|
||||
allowSyscall(ctx, SCMP_SYS(removexattr));
|
||||
allowSyscall(ctx, SCMP_SYS(rename));
|
||||
allowSyscall(ctx, SCMP_SYS(renameat));
|
||||
allowSyscall(ctx, SCMP_SYS(renameat2));
|
||||
allowSyscall(ctx, SCMP_SYS(request_key));
|
||||
allowSyscall(ctx, SCMP_SYS(restart_syscall));
|
||||
allowSyscall(ctx, SCMP_SYS(riscv_flush_icache));
|
||||
allowSyscall(ctx, SCMP_SYS(rmdir));
|
||||
allowSyscall(ctx, SCMP_SYS(rseq));
|
||||
allowSyscall(ctx, SCMP_SYS(rtas));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigaction));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigpending));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigprocmask));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigqueueinfo));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigreturn));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigsuspend));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigtimedwait));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_sigtimedwait_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(rt_tgsigqueueinfo));
|
||||
allowSyscall(ctx, SCMP_SYS(s390_guarded_storage));
|
||||
allowSyscall(ctx, SCMP_SYS(s390_pci_mmio_read));
|
||||
allowSyscall(ctx, SCMP_SYS(s390_pci_mmio_write));
|
||||
allowSyscall(ctx, SCMP_SYS(s390_runtime_instr));
|
||||
allowSyscall(ctx, SCMP_SYS(s390_sthyi));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_getaffinity));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_getattr));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_getparam));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_get_priority_max));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_get_priority_min));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_getscheduler));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_rr_get_interval));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_rr_get_interval_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_setaffinity));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_setattr));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_setparam));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_setscheduler));
|
||||
allowSyscall(ctx, SCMP_SYS(sched_yield));
|
||||
allowSyscall(ctx, SCMP_SYS(seccomp));
|
||||
allowSyscall(ctx, SCMP_SYS(security));
|
||||
allowSyscall(ctx, SCMP_SYS(select));
|
||||
allowSyscall(ctx, SCMP_SYS(semctl));
|
||||
allowSyscall(ctx, SCMP_SYS(semget));
|
||||
allowSyscall(ctx, SCMP_SYS(semop));
|
||||
allowSyscall(ctx, SCMP_SYS(semtimedop));
|
||||
allowSyscall(ctx, SCMP_SYS(semtimedop_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(send));
|
||||
allowSyscall(ctx, SCMP_SYS(sendfile));
|
||||
allowSyscall(ctx, SCMP_SYS(sendfile64));
|
||||
allowSyscall(ctx, SCMP_SYS(sendmmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(sendmsg));
|
||||
allowSyscall(ctx, SCMP_SYS(sendto));
|
||||
allowSyscall(ctx, SCMP_SYS(setdomainname));
|
||||
allowSyscall(ctx, SCMP_SYS(setfsgid));
|
||||
allowSyscall(ctx, SCMP_SYS(setfsgid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setfsuid));
|
||||
allowSyscall(ctx, SCMP_SYS(setfsuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setgid));
|
||||
allowSyscall(ctx, SCMP_SYS(setgid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setgroups));
|
||||
allowSyscall(ctx, SCMP_SYS(setgroups32));
|
||||
allowSyscall(ctx, SCMP_SYS(sethostname));
|
||||
allowSyscall(ctx, SCMP_SYS(setitimer));
|
||||
allowSyscall(ctx, SCMP_SYS(set_mempolicy));
|
||||
allowSyscall(ctx, SCMP_SYS(set_mempolicy_home_node));
|
||||
allowSyscall(ctx, SCMP_SYS(setns));
|
||||
allowSyscall(ctx, SCMP_SYS(setpgid));
|
||||
allowSyscall(ctx, SCMP_SYS(setpriority));
|
||||
allowSyscall(ctx, SCMP_SYS(setregid));
|
||||
allowSyscall(ctx, SCMP_SYS(setregid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setresgid));
|
||||
allowSyscall(ctx, SCMP_SYS(setresgid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setresuid));
|
||||
allowSyscall(ctx, SCMP_SYS(setresuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setreuid));
|
||||
allowSyscall(ctx, SCMP_SYS(setreuid32));
|
||||
allowSyscall(ctx, SCMP_SYS(setrlimit));
|
||||
allowSyscall(ctx, SCMP_SYS(set_robust_list));
|
||||
allowSyscall(ctx, SCMP_SYS(setsid));
|
||||
allowSyscall(ctx, SCMP_SYS(setsockopt));
|
||||
allowSyscall(ctx, SCMP_SYS(set_thread_area));
|
||||
allowSyscall(ctx, SCMP_SYS(set_tid_address));
|
||||
allowSyscall(ctx, SCMP_SYS(settimeofday));
|
||||
allowSyscall(ctx, SCMP_SYS(set_tls));
|
||||
allowSyscall(ctx, SCMP_SYS(setuid));
|
||||
allowSyscall(ctx, SCMP_SYS(setuid32));
|
||||
// skip setxattr (dangerous)
|
||||
allowSyscall(ctx, SCMP_SYS(sgetmask));
|
||||
allowSyscall(ctx, SCMP_SYS(shmat));
|
||||
allowSyscall(ctx, SCMP_SYS(shmctl));
|
||||
allowSyscall(ctx, SCMP_SYS(shmdt));
|
||||
allowSyscall(ctx, SCMP_SYS(shmget));
|
||||
allowSyscall(ctx, SCMP_SYS(shutdown));
|
||||
allowSyscall(ctx, SCMP_SYS(sigaction));
|
||||
allowSyscall(ctx, SCMP_SYS(sigaltstack));
|
||||
allowSyscall(ctx, SCMP_SYS(signal));
|
||||
allowSyscall(ctx, SCMP_SYS(signalfd));
|
||||
allowSyscall(ctx, SCMP_SYS(signalfd4));
|
||||
allowSyscall(ctx, SCMP_SYS(sigpending));
|
||||
allowSyscall(ctx, SCMP_SYS(sigprocmask));
|
||||
allowSyscall(ctx, SCMP_SYS(sigreturn));
|
||||
allowSyscall(ctx, SCMP_SYS(sigsuspend));
|
||||
allowSyscall(ctx, SCMP_SYS(socket));
|
||||
allowSyscall(ctx, SCMP_SYS(socketcall));
|
||||
allowSyscall(ctx, SCMP_SYS(socketpair));
|
||||
allowSyscall(ctx, SCMP_SYS(splice));
|
||||
allowSyscall(ctx, SCMP_SYS(spu_create));
|
||||
allowSyscall(ctx, SCMP_SYS(spu_run));
|
||||
allowSyscall(ctx, SCMP_SYS(ssetmask));
|
||||
allowSyscall(ctx, SCMP_SYS(stat));
|
||||
allowSyscall(ctx, SCMP_SYS(stat64));
|
||||
allowSyscall(ctx, SCMP_SYS(statfs));
|
||||
allowSyscall(ctx, SCMP_SYS(statfs64));
|
||||
allowSyscall(ctx, SCMP_SYS(statx));
|
||||
allowSyscall(ctx, SCMP_SYS(stime));
|
||||
allowSyscall(ctx, SCMP_SYS(stty));
|
||||
allowSyscall(ctx, SCMP_SYS(subpage_prot));
|
||||
allowSyscall(ctx, SCMP_SYS(swapcontext));
|
||||
allowSyscall(ctx, SCMP_SYS(swapoff));
|
||||
allowSyscall(ctx, SCMP_SYS(swapon));
|
||||
allowSyscall(ctx, SCMP_SYS(switch_endian));
|
||||
allowSyscall(ctx, SCMP_SYS(symlink));
|
||||
allowSyscall(ctx, SCMP_SYS(symlinkat));
|
||||
allowSyscall(ctx, SCMP_SYS(sync));
|
||||
allowSyscall(ctx, SCMP_SYS(sync_file_range));
|
||||
allowSyscall(ctx, SCMP_SYS(sync_file_range2));
|
||||
allowSyscall(ctx, SCMP_SYS(syncfs));
|
||||
allowSyscall(ctx, SCMP_SYS(syscall));
|
||||
allowSyscall(ctx, SCMP_SYS(_sysctl));
|
||||
allowSyscall(ctx, SCMP_SYS(sys_debug_setcontext));
|
||||
allowSyscall(ctx, SCMP_SYS(sysfs));
|
||||
allowSyscall(ctx, SCMP_SYS(sysinfo));
|
||||
allowSyscall(ctx, SCMP_SYS(syslog));
|
||||
allowSyscall(ctx, SCMP_SYS(sysmips));
|
||||
allowSyscall(ctx, SCMP_SYS(tee));
|
||||
allowSyscall(ctx, SCMP_SYS(tgkill));
|
||||
allowSyscall(ctx, SCMP_SYS(time));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_create));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_delete));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd_create));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd_gettime));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd_gettime64));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd_settime));
|
||||
allowSyscall(ctx, SCMP_SYS(timerfd_settime64));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_getoverrun));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_gettime));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_gettime64));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_settime));
|
||||
allowSyscall(ctx, SCMP_SYS(timer_settime64));
|
||||
allowSyscall(ctx, SCMP_SYS(times));
|
||||
allowSyscall(ctx, SCMP_SYS(tkill));
|
||||
allowSyscall(ctx, SCMP_SYS(truncate));
|
||||
allowSyscall(ctx, SCMP_SYS(truncate64));
|
||||
allowSyscall(ctx, SCMP_SYS(tuxcall));
|
||||
allowSyscall(ctx, SCMP_SYS(ugetrlimit));
|
||||
allowSyscall(ctx, SCMP_SYS(ulimit));
|
||||
allowSyscall(ctx, SCMP_SYS(umask));
|
||||
allowSyscall(ctx, SCMP_SYS(umount));
|
||||
allowSyscall(ctx, SCMP_SYS(umount2));
|
||||
allowSyscall(ctx, SCMP_SYS(uname));
|
||||
allowSyscall(ctx, SCMP_SYS(unlink));
|
||||
allowSyscall(ctx, SCMP_SYS(unlinkat));
|
||||
allowSyscall(ctx, SCMP_SYS(unshare));
|
||||
allowSyscall(ctx, SCMP_SYS(uselib));
|
||||
allowSyscall(ctx, SCMP_SYS(userfaultfd));
|
||||
allowSyscall(ctx, SCMP_SYS(usr26));
|
||||
allowSyscall(ctx, SCMP_SYS(usr32));
|
||||
allowSyscall(ctx, SCMP_SYS(ustat));
|
||||
allowSyscall(ctx, SCMP_SYS(utime));
|
||||
allowSyscall(ctx, SCMP_SYS(utimensat));
|
||||
allowSyscall(ctx, SCMP_SYS(utimensat_time64));
|
||||
allowSyscall(ctx, SCMP_SYS(utimes));
|
||||
allowSyscall(ctx, SCMP_SYS(vfork));
|
||||
allowSyscall(ctx, SCMP_SYS(vhangup));
|
||||
allowSyscall(ctx, SCMP_SYS(vm86));
|
||||
allowSyscall(ctx, SCMP_SYS(vm86old));
|
||||
allowSyscall(ctx, SCMP_SYS(vmsplice));
|
||||
allowSyscall(ctx, SCMP_SYS(vserver));
|
||||
allowSyscall(ctx, SCMP_SYS(wait4));
|
||||
allowSyscall(ctx, SCMP_SYS(waitid));
|
||||
allowSyscall(ctx, SCMP_SYS(waitpid));
|
||||
allowSyscall(ctx, SCMP_SYS(write));
|
||||
allowSyscall(ctx, SCMP_SYS(writev));
|
||||
// END extract-syscalls
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
// chmod family: prevent adding setuid/setgid bits to existing files.
|
||||
// The Nix store does not support setuid/setgid, and even their temporary creation can weaken the security of the sandbox.
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISUID | S_ISGID, 0)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISUID, S_ISUID)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISGID, S_ISGID)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISUID | S_ISGID, 0)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISUID, S_ISUID)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, S_ISGID, S_ISGID)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, S_ISUID | S_ISGID, 0)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, S_ISUID, S_ISUID)) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, S_ISGID, S_ISGID)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), NIX_SYSCALL_FCHMODAT2, 1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
}
|
||||
|
||||
/* Prevent builders from creating EAs or ACLs. Not all filesystems
|
||||
support these, and they're not allowed in the Nix store because
|
||||
they're not representable in the NAR serialisation. */
|
||||
// setxattr family: prevent creation of extended attributes or ACLs.
|
||||
// Not all filesystems support them, and they're incompatible with the NAR format.
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(setxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lsetxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
||||
|
@ -1705,11 +2210,7 @@ void LocalDerivationGoal::runChild()
|
|||
|
||||
commonChildInit();
|
||||
|
||||
try {
|
||||
setupSeccomp();
|
||||
} catch (...) {
|
||||
if (buildUser) throw;
|
||||
}
|
||||
setupSeccomp();
|
||||
|
||||
bool setUser = true;
|
||||
|
||||
|
@ -1838,8 +2339,12 @@ void LocalDerivationGoal::runChild()
|
|||
copyFile(path, chrootRootDir + path, { .followSymlinks = true });
|
||||
}
|
||||
|
||||
if (settings.caFile != "")
|
||||
pathsInChroot.try_emplace("/etc/ssl/certs/ca-certificates.crt", settings.caFile, true);
|
||||
if (settings.caFile != "" && pathExists(settings.caFile)) {
|
||||
// For the same reasons as above, copy the CA certificates file too.
|
||||
// It should be even less likely to change during the build than resolv.conf.
|
||||
createDirs(chrootRootDir + "/etc/ssl/certs");
|
||||
copyFile(settings.caFile, chrootRootDir + "/etc/ssl/certs/ca-certificates.crt", { .followSymlinks = true });
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & i : ss) pathsInChroot.emplace(i, i);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "derivation-goal.hh"
|
||||
#include "local-store.hh"
|
||||
#include "processes.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#include "serialise.hh"
|
||||
#include "util.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
#include "common-protocol.hh"
|
||||
#include "common-protocol-impl.hh"
|
||||
#include "archive.hh"
|
||||
#include "derivations.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "crypto.hh"
|
||||
#include "util.hh"
|
||||
#include "file-system.hh"
|
||||
#include "globals.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include <sodium.h>
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "store-api.hh"
|
||||
#include "globals.hh"
|
||||
#include "types.hh"
|
||||
#include "util.hh"
|
||||
#include "split.hh"
|
||||
#include "common-protocol.hh"
|
||||
#include "common-protocol-impl.hh"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "config.hh"
|
||||
#include "path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "comparator.hh"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "filetransfer.hh"
|
||||
#include "util.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "s3.hh"
|
||||
|
@ -19,7 +19,6 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
@ -51,7 +50,6 @@ struct curlFileTransfer : public FileTransfer
|
|||
std::function<void(TransferItem &, std::string_view data)> dataCallback;
|
||||
CURL * req = 0;
|
||||
bool active = false; // whether the handle has been added to the multi object
|
||||
bool headersProcessed = false;
|
||||
std::string statusMsg;
|
||||
|
||||
unsigned int attempt = 0;
|
||||
|
@ -136,35 +134,11 @@ struct curlFileTransfer : public FileTransfer
|
|||
|
||||
std::exception_ptr writeException;
|
||||
|
||||
std::optional<std::string> getHeader(const char * name)
|
||||
{
|
||||
curl_header * result;
|
||||
auto e = curl_easy_header(req, name, 0, CURLH_HEADER, -1, &result);
|
||||
if (e == CURLHE_OK) {
|
||||
return result->value;
|
||||
} else if (e == CURLHE_MISSING || e == CURLHE_NOHEADERS) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
throw nix::Error("unexpected error from curl_easy_header(): %i", e);
|
||||
}
|
||||
}
|
||||
|
||||
size_t writeCallback(void * contents, size_t size, size_t nmemb)
|
||||
{
|
||||
const size_t realSize = size * nmemb;
|
||||
|
||||
try {
|
||||
if (!headersProcessed) {
|
||||
if (auto h = getHeader("content-encoding")) {
|
||||
encoding = std::move(*h);
|
||||
}
|
||||
if (auto h = getHeader("accept-ranges"); h && *h == "bytes") {
|
||||
acceptRanges = true;
|
||||
}
|
||||
|
||||
headersProcessed = true;
|
||||
}
|
||||
|
||||
result.bodySize += realSize;
|
||||
|
||||
if (successfulStatuses.count(getHTTPStatus()) && this->dataCallback) {
|
||||
|
@ -200,7 +174,31 @@ struct curlFileTransfer : public FileTransfer
|
|||
statusMsg = trim(match.str(1));
|
||||
acceptRanges = false;
|
||||
encoding = "";
|
||||
headersProcessed = false;
|
||||
} else {
|
||||
auto i = line.find(':');
|
||||
if (i != std::string::npos) {
|
||||
std::string name = toLower(trim(line.substr(0, i)));
|
||||
|
||||
if (name == "etag") {
|
||||
result.etag = trim(line.substr(i + 1));
|
||||
}
|
||||
|
||||
else if (name == "content-encoding")
|
||||
encoding = trim(line.substr(i + 1));
|
||||
|
||||
else if (name == "accept-ranges" && toLower(trim(line.substr(i + 1))) == "bytes")
|
||||
acceptRanges = true;
|
||||
|
||||
else if (name == "link" || name == "x-amz-meta-link") {
|
||||
auto value = trim(line.substr(i + 1));
|
||||
static std::regex linkRegex("<([^>]*)>; rel=\"immutable\"", std::regex::extended | std::regex::icase);
|
||||
if (std::smatch match; std::regex_match(value, match, linkRegex))
|
||||
result.immutableUrl = match.str(1);
|
||||
else
|
||||
debug("got invalid link header '%s'", value);
|
||||
warn("foo %s", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return realSize;
|
||||
}
|
||||
|
@ -336,25 +334,6 @@ struct curlFileTransfer : public FileTransfer
|
|||
debug("finished %s of '%s'; curl status = %d, HTTP status = %d, body = %d bytes",
|
||||
request.verb(), request.uri, code, httpStatus, result.bodySize);
|
||||
|
||||
auto link = getHeader("link");
|
||||
if (!link) {
|
||||
link = getHeader("x-amz-meta-link");
|
||||
}
|
||||
if (link) {
|
||||
static std::regex linkRegex(
|
||||
"<([^>]*)>; rel=\"immutable\"", std::regex::extended | std::regex::icase
|
||||
);
|
||||
if (std::smatch match; std::regex_match(*link, match, linkRegex)) {
|
||||
result.immutableUrl = match.str(1);
|
||||
} else {
|
||||
debug("got invalid link header '%s'", *link);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto etag = getHeader("etag")) {
|
||||
result.etag = std::move(*etag);
|
||||
}
|
||||
|
||||
// this has to happen here until we can return an actual future.
|
||||
// wrapping user `callback`s instead is not possible because the
|
||||
// Callback api expects std::functions, and copying Callbacks is
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "logging.hh"
|
||||
#include "serialise.hh"
|
||||
#include "types.hh"
|
||||
#include "hash.hh"
|
||||
#include "config.hh"
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#include "derivations.hh"
|
||||
#include "globals.hh"
|
||||
#include "local-store.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "processes.hh"
|
||||
#include "signals.hh"
|
||||
#include "finally.hh"
|
||||
#include "unix-domain-socket.hh"
|
||||
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <random>
|
||||
|
||||
#include <climits>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#include "environment-variables.hh"
|
||||
#include "globals.hh"
|
||||
#include "util.hh"
|
||||
#include "archive.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include "strings.hh"
|
||||
#include "users.hh"
|
||||
#include "args.hh"
|
||||
#include "abstract-setting-to-json.hh"
|
||||
#include "compute-levels.hh"
|
||||
#include "current-process.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <dlfcn.h>
|
||||
|
@ -25,6 +28,7 @@
|
|||
#include "config-impl.hh"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "processes.hh"
|
||||
#include <curl/curl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "environment-variables.hh"
|
||||
#include "types.hh"
|
||||
#include "config.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <map>
|
||||
#include <limits>
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Determine the syscall number for `fchmodat2`.
|
||||
*
|
||||
* On most platforms this is 452. Exceptions can be found on
|
||||
* a glibc git checkout via `rg --pcre2 'define __NR_fchmodat2 (?!452)'`.
|
||||
*
|
||||
* The problem is that glibc 2.39 and libseccomp 2.5.5 are needed to
|
||||
* get the syscall number. However, a Nix built against nixpkgs 23.11
|
||||
* (glibc 2.38) should still have the issue fixed without depending
|
||||
* on the build environment.
|
||||
*
|
||||
* To achieve that, the macros below try to determine the platform and
|
||||
* set the syscall number which is platform-specific, but
|
||||
* in most cases 452.
|
||||
*
|
||||
* TODO: remove this when 23.11 is EOL and the entire (supported) ecosystem
|
||||
* is on glibc 2.39.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#if defined(__alpha__)
|
||||
# define NIX_SYSCALL_FCHMODAT2 562
|
||||
#elif defined(__x86_64__) && SIZE_MAX == 0xFFFFFFFF // x32
|
||||
# define NIX_SYSCALL_FCHMODAT2 1073742276
|
||||
#elif defined(__mips__) && defined(__mips64) && defined(_ABIN64) // mips64/n64
|
||||
# define NIX_SYSCALL_FCHMODAT2 5452
|
||||
#elif defined(__mips__) && defined(__mips64) && defined(_ABIN32) // mips64/n32
|
||||
# define NIX_SYSCALL_FCHMODAT2 6452
|
||||
#elif defined(__mips__) && defined(_ABIO32) // mips32
|
||||
# define NIX_SYSCALL_FCHMODAT2 4452
|
||||
#else
|
||||
# define NIX_SYSCALL_FCHMODAT2 452
|
||||
#endif
|
|
@ -3,11 +3,9 @@
|
|||
|
||||
#include "sqlite.hh"
|
||||
|
||||
#include "pathlocks.hh"
|
||||
#include "store-api.hh"
|
||||
#include "indirect-root-store.hh"
|
||||
#include "sync.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "lock.hh"
|
||||
#include "logging.hh"
|
||||
#include "file-system.hh"
|
||||
#include "globals.hh"
|
||||
#include "pathlocks.hh"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "machines.hh"
|
||||
#include "util.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ libstore_sources = files(
|
|||
'store-api.cc',
|
||||
'uds-remote-store.cc',
|
||||
'worker-protocol.cc',
|
||||
'build/child.cc',
|
||||
'build/derivation-goal.cc',
|
||||
'build/drv-output-substitution-goal.cc',
|
||||
'build/entry-points.cc',
|
||||
|
@ -96,6 +97,7 @@ libstore_sources = files(
|
|||
|
||||
libstore_headers = files(
|
||||
'binary-cache-store.hh',
|
||||
'build/child.hh',
|
||||
'build/derivation-goal.hh',
|
||||
'build/drv-output-substitution-goal.hh',
|
||||
'build/goal.hh',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "names.hh"
|
||||
#include "util.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include <regex>
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "nar-info-disk-cache.hh"
|
||||
#include "logging.hh"
|
||||
#include "sync.hh"
|
||||
#include "sqlite.hh"
|
||||
#include "globals.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "util.hh"
|
||||
#include "local-store.hh"
|
||||
#include "globals.hh"
|
||||
#include "signals.hh"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <regex>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "util.hh"
|
||||
#include "regex-combinators.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "path-regex.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
#include "path-references.hh"
|
||||
#include "hash.hh"
|
||||
#include "util.hh"
|
||||
#include "archive.hh"
|
||||
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#include "pathlocks.hh"
|
||||
#include "util.hh"
|
||||
#include "logging.hh"
|
||||
#include "signals.hh"
|
||||
#include "sync.hh"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "file-descriptor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "profiles.hh"
|
||||
#include "store-api.hh"
|
||||
#include "local-fs-store.hh"
|
||||
#include "util.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "serialise.hh"
|
||||
#include "util.hh"
|
||||
#include "signals.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
#include "gc-store.hh"
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#include "serialise.hh"
|
||||
#include "util.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
#include "serve-protocol.hh"
|
||||
#include "serve-protocol-impl.hh"
|
||||
#include "archive.hh"
|
||||
#include "path-info.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#include "sqlite.hh"
|
||||
#include "globals.hh"
|
||||
#include "util.hh"
|
||||
#include "logging.hh"
|
||||
#include "signals.hh"
|
||||
#include "url.hh"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "current-process.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "ssh.hh"
|
||||
#include "finally.hh"
|
||||
#include "logging.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "util.hh"
|
||||
#include "file-system.hh"
|
||||
#include "processes.hh"
|
||||
#include "sync.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#include "crypto.hh"
|
||||
#include "fs-accessor.hh"
|
||||
#include "globals.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "nar-info-disk-cache.hh"
|
||||
#include "thread-pool.hh"
|
||||
#include "url.hh"
|
||||
|
@ -14,6 +12,7 @@
|
|||
// FIXME this should not be here, see TODO below on
|
||||
// `addMultipleToStore`.
|
||||
#include "worker-protocol.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <regex>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "logging.hh"
|
||||
#include "nar-info.hh"
|
||||
#include "realisation.hh"
|
||||
#include "path.hh"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "uds-remote-store.hh"
|
||||
#include "unix-domain-socket.hh"
|
||||
#include "worker-protocol.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "serialise.hh"
|
||||
#include "util.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include "archive.hh"
|
||||
#include "util.hh"
|
||||
#include "file-system.hh"
|
||||
#include "config.hh"
|
||||
#include "logging.hh"
|
||||
#include "signals.hh"
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "types.hh"
|
||||
#include "serialise.hh"
|
||||
#include "file-system.hh"
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
#include "args/root.hh"
|
||||
#include "hash.hh"
|
||||
#include "json-utils.hh"
|
||||
#include "environment-variables.hh"
|
||||
|
||||
#include "experimental-features-json.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <iostream>
|
||||
#include "experimental-features.hh"
|
||||
#include "types.hh"
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include "util.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "canon-path.hh"
|
||||
#include "util.hh"
|
||||
#include "file-system.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
#include "logging.hh"
|
||||
#if __linux__
|
||||
|
||||
#include "cgroup.hh"
|
||||
#include "util.hh"
|
||||
#include "file-system.hh"
|
||||
#include "finally.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <regex>
|
||||
#include <unordered_set>
|
||||
#include <thread>
|
||||
#include <signal.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <mntent.h>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#define DECLARE_ONE_CMP(PRE, QUAL, COMPARATOR, MY_TYPE) \
|
||||
PRE bool QUAL operator COMPARATOR(const MY_TYPE & other) const;
|
||||
#define DECLARE_EQUAL(prefix, qualification, my_type) \
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "compression.hh"
|
||||
#include "tarfile.hh"
|
||||
#include "util.hh"
|
||||
#include "finally.hh"
|
||||
#include "signals.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
|
@ -13,7 +11,6 @@
|
|||
#include <brotli/decode.h>
|
||||
#include <brotli/encode.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
* instantiation.
|
||||
*/
|
||||
|
||||
#include "args.hh"
|
||||
#include "config.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include "args.hh"
|
||||
#include "abstract-setting-to-json.hh"
|
||||
#include "experimental-features.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include "config-impl.hh"
|
||||
|
||||
|
|
111
src/libutil/current-process.cc
Normal file
111
src/libutil/current-process.cc
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include "current-process.hh"
|
||||
#include "error.hh"
|
||||
#include "file-system.hh"
|
||||
#include "logging.hh"
|
||||
#include "namespaces.hh"
|
||||
#include "signals.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <cgroup.hh>
|
||||
|
||||
namespace nix {
|
||||
|
||||
unsigned int getMaxCPU()
|
||||
{
|
||||
#if __linux__
|
||||
try {
|
||||
auto cgroupFS = getCgroupFS();
|
||||
if (!cgroupFS) return 0;
|
||||
|
||||
auto cgroups = getCgroups("/proc/self/cgroup");
|
||||
auto cgroup = cgroups[""];
|
||||
if (cgroup == "") return 0;
|
||||
|
||||
auto cpuFile = *cgroupFS + "/" + cgroup + "/cpu.max";
|
||||
|
||||
auto cpuMax = readFile(cpuFile);
|
||||
auto cpuMaxParts = tokenizeString<std::vector<std::string>>(cpuMax, " \n");
|
||||
|
||||
if (cpuMaxParts.size() != 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto quota = cpuMaxParts[0];
|
||||
auto period = cpuMaxParts[1];
|
||||
if (quota != "max")
|
||||
return std::ceil(std::stoi(quota) / std::stof(period));
|
||||
} catch (Error &) { ignoreException(lvlDebug); }
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rlim_t savedStackSize = 0;
|
||||
|
||||
void setStackSize(rlim_t stackSize)
|
||||
{
|
||||
struct rlimit limit;
|
||||
if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) {
|
||||
savedStackSize = limit.rlim_cur;
|
||||
limit.rlim_cur = std::min(stackSize, limit.rlim_max);
|
||||
if (setrlimit(RLIMIT_STACK, &limit) != 0) {
|
||||
logger->log(
|
||||
lvlError,
|
||||
HintFmt(
|
||||
"Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%",
|
||||
savedStackSize,
|
||||
stackSize,
|
||||
limit.rlim_max,
|
||||
std::strerror(errno)
|
||||
).str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void restoreProcessContext(bool restoreMounts)
|
||||
{
|
||||
restoreSignals();
|
||||
if (restoreMounts) {
|
||||
restoreMountNamespace();
|
||||
}
|
||||
|
||||
if (savedStackSize) {
|
||||
struct rlimit limit;
|
||||
if (getrlimit(RLIMIT_STACK, &limit) == 0) {
|
||||
limit.rlim_cur = savedStackSize;
|
||||
setrlimit(RLIMIT_STACK, &limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Path> getSelfExe()
|
||||
{
|
||||
static auto cached = []() -> std::optional<Path>
|
||||
{
|
||||
#if __linux__
|
||||
return readLink("/proc/self/exe");
|
||||
#elif __APPLE__
|
||||
char buf[1024];
|
||||
uint32_t size = sizeof(buf);
|
||||
if (_NSGetExecutablePath(buf, &size) == 0)
|
||||
return buf;
|
||||
else
|
||||
return std::nullopt;
|
||||
#else
|
||||
return std::nullopt;
|
||||
#endif
|
||||
}();
|
||||
return cached;
|
||||
}
|
||||
|
||||
}
|
37
src/libutil/current-process.hh
Normal file
37
src/libutil/current-process.hh
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <optional>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* If cgroups are active, attempt to calculate the number of CPUs available.
|
||||
* If cgroups are unavailable or if cpu.max is set to "max", return 0.
|
||||
*/
|
||||
unsigned int getMaxCPU();
|
||||
|
||||
|
||||
/**
|
||||
* Change the stack size.
|
||||
*/
|
||||
void setStackSize(rlim_t stackSize);
|
||||
|
||||
|
||||
/**
|
||||
* Restore the original inherited Unix process context (such as signal
|
||||
* masks, stack size).
|
||||
|
||||
* See startSignalHandlerThread(), saveSignalMask().
|
||||
*/
|
||||
void restoreProcessContext(bool restoreMounts = true);
|
||||
|
||||
/**
|
||||
* @return the path of the current executable.
|
||||
*/
|
||||
std::optional<Path> getSelfExe();
|
||||
|
||||
}
|
51
src/libutil/environment-variables.cc
Normal file
51
src/libutil/environment-variables.cc
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <cstring>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
extern char * * environ __attribute__((weak));
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::optional<std::string> getEnv(const std::string & key)
|
||||
{
|
||||
char * value = getenv(key.c_str());
|
||||
if (!value) return {};
|
||||
return std::string(value);
|
||||
}
|
||||
|
||||
std::optional<std::string> getEnvNonEmpty(const std::string & key) {
|
||||
auto value = getEnv(key);
|
||||
if (value == "") return {};
|
||||
return value;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getEnv()
|
||||
{
|
||||
std::map<std::string, std::string> env;
|
||||
for (size_t i = 0; environ[i]; ++i) {
|
||||
auto s = environ[i];
|
||||
auto eq = strchr(s, '=');
|
||||
if (!eq)
|
||||
// invalid env, just keep going
|
||||
continue;
|
||||
env.emplace(std::string(s, eq), std::string(eq + 1));
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
void clearEnv()
|
||||
{
|
||||
for (auto & name : getEnv())
|
||||
unsetenv(name.first.c_str());
|
||||
}
|
||||
|
||||
void replaceEnv(const std::map<std::string, std::string> & newEnv)
|
||||
{
|
||||
clearEnv();
|
||||
for (auto & newEnvVar : newEnv)
|
||||
setenv(newEnvVar.first.c_str(), newEnvVar.second.c_str(), 1);
|
||||
}
|
||||
|
||||
}
|
42
src/libutil/environment-variables.hh
Normal file
42
src/libutil/environment-variables.hh
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Utilities for working with the current process's environment
|
||||
* variables.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* @return an environment variable.
|
||||
*/
|
||||
std::optional<std::string> getEnv(const std::string & key);
|
||||
|
||||
/**
|
||||
* @return a non empty environment variable. Returns nullopt if the env
|
||||
* variable is set to ""
|
||||
*/
|
||||
std::optional<std::string> getEnvNonEmpty(const std::string & key);
|
||||
|
||||
/**
|
||||
* Get the entire environment.
|
||||
*/
|
||||
std::map<std::string, std::string> getEnv();
|
||||
|
||||
/**
|
||||
* Clear the environment.
|
||||
*/
|
||||
void clearEnv();
|
||||
|
||||
/**
|
||||
* Replace the entire environment with the given one.
|
||||
*/
|
||||
void replaceEnv(const std::map<std::string, std::string> & newEnv);
|
||||
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
#include "environment-variables.hh"
|
||||
#include "error.hh"
|
||||
#include "logging.hh"
|
||||
#include "position.hh"
|
||||
#include "terminal.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include "serialise.hh"
|
||||
#include <sstream>
|
||||
|
||||
namespace nix {
|
||||
|
||||
const std::string nativeSystem = SYSTEM;
|
||||
|
||||
void BaseError::addTrace(std::shared_ptr<Pos> && e, HintFmt hint)
|
||||
{
|
||||
err.traces.push_front(Trace { .pos = std::move(e), .hint = hint });
|
||||
|
@ -415,4 +415,17 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
|
|||
return out;
|
||||
}
|
||||
|
||||
void ignoreException(Verbosity lvl)
|
||||
{
|
||||
/* Make sure no exceptions leave this function.
|
||||
printError() also throws when remote is closed. */
|
||||
try {
|
||||
try {
|
||||
throw;
|
||||
} catch (std::exception & e) {
|
||||
printMsg(lvl, "error (ignored): %1%", e.what());
|
||||
}
|
||||
} catch (...) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -202,4 +202,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception handling in destructors: print an error message, then
|
||||
* ignore the exception.
|
||||
*/
|
||||
void ignoreException(Verbosity lvl = lvlError);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "experimental-features.hh"
|
||||
// Required for instances of to_json and from_json for ExperimentalFeature
|
||||
#include "experimental-features-json.hh"
|
||||
#include "util.hh"
|
||||
#include "strings.hh"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
|
|
252
src/libutil/file-descriptor.cc
Normal file
252
src/libutil/file-descriptor.cc
Normal file
|
@ -0,0 +1,252 @@
|
|||
#include "file-system.hh"
|
||||
#include "finally.hh"
|
||||
#include "logging.hh"
|
||||
#include "serialise.hh"
|
||||
#include "signals.hh"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string readFile(int fd)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1)
|
||||
throw SysError("statting file");
|
||||
|
||||
return drainFD(fd, true, st.st_size);
|
||||
}
|
||||
|
||||
|
||||
std::string readLine(int fd)
|
||||
{
|
||||
std::string s;
|
||||
while (1) {
|
||||
checkInterrupt();
|
||||
char ch;
|
||||
// FIXME: inefficient
|
||||
ssize_t rd = read(fd, &ch, 1);
|
||||
if (rd == -1) {
|
||||
if (errno != EINTR)
|
||||
throw SysError("reading a line");
|
||||
} else if (rd == 0)
|
||||
throw EndOfFile("unexpected EOF reading a line");
|
||||
else {
|
||||
if (ch == '\n') return s;
|
||||
s += ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeLine(int fd, std::string s)
|
||||
{
|
||||
s += '\n';
|
||||
writeFull(fd, s);
|
||||
}
|
||||
|
||||
|
||||
void readFull(int fd, char * buf, size_t count)
|
||||
{
|
||||
while (count) {
|
||||
checkInterrupt();
|
||||
ssize_t res = read(fd, buf, count);
|
||||
if (res == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
throw SysError("reading from file");
|
||||
}
|
||||
if (res == 0) throw EndOfFile("unexpected end-of-file");
|
||||
count -= res;
|
||||
buf += res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeFull(int fd, std::string_view s, bool allowInterrupts)
|
||||
{
|
||||
while (!s.empty()) {
|
||||
if (allowInterrupts) checkInterrupt();
|
||||
ssize_t res = write(fd, s.data(), s.size());
|
||||
if (res == -1 && errno != EINTR)
|
||||
throw SysError("writing to file");
|
||||
if (res > 0)
|
||||
s.remove_prefix(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string drainFD(int fd, bool block, const size_t reserveSize)
|
||||
{
|
||||
// the parser needs two extra bytes to append terminating characters, other users will
|
||||
// not care very much about the extra memory.
|
||||
StringSink sink(reserveSize + 2);
|
||||
drainFD(fd, sink, block);
|
||||
return std::move(sink.s);
|
||||
}
|
||||
|
||||
|
||||
void drainFD(int fd, Sink & sink, bool block)
|
||||
{
|
||||
// silence GCC maybe-uninitialized warning in finally
|
||||
int saved = 0;
|
||||
|
||||
if (!block) {
|
||||
saved = fcntl(fd, F_GETFL);
|
||||
if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1)
|
||||
throw SysError("making file descriptor non-blocking");
|
||||
}
|
||||
|
||||
Finally finally([&]() {
|
||||
if (!block) {
|
||||
if (fcntl(fd, F_SETFL, saved) == -1)
|
||||
throw SysError("making file descriptor blocking");
|
||||
}
|
||||
});
|
||||
|
||||
std::array<unsigned char, 64 * 1024> buf;
|
||||
while (1) {
|
||||
checkInterrupt();
|
||||
ssize_t rd = read(fd, buf.data(), buf.size());
|
||||
if (rd == -1) {
|
||||
if (!block && (errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
break;
|
||||
if (errno != EINTR)
|
||||
throw SysError("reading from file");
|
||||
}
|
||||
else if (rd == 0) break;
|
||||
else sink({(char *) buf.data(), (size_t) rd});
|
||||
}
|
||||
}
|
||||
|
||||
AutoCloseFD::AutoCloseFD() : fd{-1} {}
|
||||
|
||||
|
||||
AutoCloseFD::AutoCloseFD(int fd) : fd{fd} {}
|
||||
|
||||
|
||||
AutoCloseFD::AutoCloseFD(AutoCloseFD && that) : fd{that.fd}
|
||||
{
|
||||
that.fd = -1;
|
||||
}
|
||||
|
||||
|
||||
AutoCloseFD & AutoCloseFD::operator =(AutoCloseFD && that)
|
||||
{
|
||||
close();
|
||||
fd = that.fd;
|
||||
that.fd = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AutoCloseFD::~AutoCloseFD()
|
||||
{
|
||||
try {
|
||||
close();
|
||||
} catch (...) {
|
||||
ignoreException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int AutoCloseFD::get() const
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void AutoCloseFD::close()
|
||||
{
|
||||
if (fd != -1) {
|
||||
if (::close(fd) == -1)
|
||||
/* This should never happen. */
|
||||
throw SysError("closing file descriptor %1%", fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoCloseFD::fsync()
|
||||
{
|
||||
if (fd != -1) {
|
||||
int result;
|
||||
#if __APPLE__
|
||||
result = ::fcntl(fd, F_FULLFSYNC);
|
||||
#else
|
||||
result = ::fsync(fd);
|
||||
#endif
|
||||
if (result == -1)
|
||||
throw SysError("fsync file descriptor %1%", fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AutoCloseFD::operator bool() const
|
||||
{
|
||||
return fd != -1;
|
||||
}
|
||||
|
||||
|
||||
int AutoCloseFD::release()
|
||||
{
|
||||
int oldFD = fd;
|
||||
fd = -1;
|
||||
return oldFD;
|
||||
}
|
||||
|
||||
|
||||
void Pipe::create()
|
||||
{
|
||||
int fds[2];
|
||||
#if HAVE_PIPE2
|
||||
if (pipe2(fds, O_CLOEXEC) != 0) throw SysError("creating pipe");
|
||||
#else
|
||||
if (pipe(fds) != 0) throw SysError("creating pipe");
|
||||
closeOnExec(fds[0]);
|
||||
closeOnExec(fds[1]);
|
||||
#endif
|
||||
readSide = AutoCloseFD{fds[0]};
|
||||
writeSide = AutoCloseFD{fds[1]};
|
||||
}
|
||||
|
||||
|
||||
void Pipe::close()
|
||||
{
|
||||
readSide.close();
|
||||
writeSide.close();
|
||||
}
|
||||
|
||||
|
||||
void closeMostFDs(const std::set<int> & exceptions)
|
||||
{
|
||||
#if __linux__
|
||||
try {
|
||||
for (auto & s : readDirectory("/proc/self/fd")) {
|
||||
auto fd = std::stoi(s.name);
|
||||
if (!exceptions.count(fd)) {
|
||||
debug("closing leaked FD %d", fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (SysError &) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int maxFD = 0;
|
||||
maxFD = sysconf(_SC_OPEN_MAX);
|
||||
for (int fd = 0; fd < maxFD; ++fd)
|
||||
if (!exceptions.count(fd))
|
||||
close(fd); /* ignore result */
|
||||
}
|
||||
|
||||
|
||||
void closeOnExec(int fd)
|
||||
{
|
||||
int prev;
|
||||
if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
|
||||
fcntl(fd, F_SETFD, prev | FD_CLOEXEC) == -1)
|
||||
throw SysError("setting close-on-exec flag");
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue