forked from lix-project/lix
Compare commits
4 commits
5e0383fa94
...
8543b3cc1a
Author | SHA1 | Date | |
---|---|---|---|
alois31 | 8543b3cc1a | ||
alois31 | cb79437c1c | ||
alois31 | 2eac435bc7 | ||
alois31 | 51708e7433 |
9
doc/manual/rl-next/reject-flake-config.md
Normal file
9
doc/manual/rl-next/reject-flake-config.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
synopsis: Allow automatic rejection of configuration options from flakes
|
||||||
|
cls: [1541]
|
||||||
|
credits: [alois31]
|
||||||
|
category: Improvements
|
||||||
|
---
|
||||||
|
|
||||||
|
Setting `accept-flake-config` to `false` now respects user choice by automatically rejecting configuration options set by flakes.
|
||||||
|
The old behaviour of asking each time is still available (and default) by setting it to the special value `ask`.
|
|
@ -166,6 +166,7 @@
|
||||||
nixUnstable = prev.nixUnstable;
|
nixUnstable = prev.nixUnstable;
|
||||||
|
|
||||||
check-headers = final.buildPackages.callPackage ./maintainers/check-headers.nix { };
|
check-headers = final.buildPackages.callPackage ./maintainers/check-headers.nix { };
|
||||||
|
check-syscalls = final.buildPackages.callPackage ./maintainers/check-syscalls.nix { };
|
||||||
|
|
||||||
default-busybox-sandbox-shell = final.busybox.override {
|
default-busybox-sandbox-shell = final.busybox.override {
|
||||||
useMusl = true;
|
useMusl = true;
|
||||||
|
|
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)
|
|
@ -412,6 +412,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
# Lix specific packages
|
# Lix specific packages
|
||||||
pre-commit-checks,
|
pre-commit-checks,
|
||||||
contribNotice,
|
contribNotice,
|
||||||
|
check-syscalls,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
glibcFix = lib.optionalAttrs (buildPlatform.isLinux && glibcLocales != null) {
|
glibcFix = lib.optionalAttrs (buildPlatform.isLinux && glibcLocales != null) {
|
||||||
|
@ -465,6 +466,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
pythonEnv
|
pythonEnv
|
||||||
# docker image tool
|
# docker image tool
|
||||||
skopeo
|
skopeo
|
||||||
|
check-syscalls
|
||||||
just
|
just
|
||||||
nixfmt
|
nixfmt
|
||||||
# Included above when internalApiDocs is true, but we set that to
|
# Included above when internalApiDocs is true, but we set that to
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "print.hh"
|
#include "print.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "gc-small-vector.hh"
|
#include "gc-small-vector.hh"
|
||||||
#include "users.hh"
|
#include "users.hh"
|
||||||
|
|
||||||
|
@ -300,7 +299,7 @@ ReplExitStatus NixRepl::mainLoop()
|
||||||
|
|
||||||
/* Stop the progress bar because it interferes with the display of
|
/* Stop the progress bar because it interferes with the display of
|
||||||
the repl. */
|
the repl. */
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
std::string input;
|
std::string input;
|
||||||
|
|
||||||
|
@ -684,9 +683,10 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
||||||
// TODO: this only shows a progress bar for explicitly initiated builds,
|
// TODO: this only shows a progress bar for explicitly initiated builds,
|
||||||
// not eval-time fetching or builds performed for IFD.
|
// not eval-time fetching or builds performed for IFD.
|
||||||
// But we can't just show it everywhere, since that would erase partial output from evaluation.
|
// But we can't just show it everywhere, since that would erase partial output from evaluation.
|
||||||
startProgressBar();
|
logger->resetProgress();
|
||||||
|
logger->resume();
|
||||||
Finally stopLogger([&]() {
|
Finally stopLogger([&]() {
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
});
|
});
|
||||||
|
|
||||||
state->store->buildPaths({
|
state->store->buildPaths({
|
||||||
|
|
|
@ -51,8 +51,14 @@ void ConfigFile::apply()
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
if (!whitelist.count(baseName) && !nix::fetchSettings.acceptFlakeConfig) {
|
bool trusted = whitelist.count(baseName);
|
||||||
bool trusted = false;
|
if (!trusted) {
|
||||||
|
switch (nix::fetchSettings.acceptFlakeConfig) {
|
||||||
|
case AcceptFlakeConfig::True: {
|
||||||
|
trusted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AcceptFlakeConfig::Ask: {
|
||||||
auto trustedList = readTrustedList();
|
auto trustedList = readTrustedList();
|
||||||
auto tlname = get(trustedList, name);
|
auto tlname = get(trustedList, name);
|
||||||
if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
|
if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
|
||||||
|
@ -60,7 +66,7 @@ void ConfigFile::apply()
|
||||||
printInfo("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name, valueS);
|
printInfo("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name, valueS);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: filter ANSI escapes, newlines, \r, etc.
|
// FIXME: filter ANSI escapes, newlines, \r, etc.
|
||||||
if (std::tolower(logger->ask(fmt("do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)?", name, valueS)).value_or('n')) == 'y') {
|
if (std::tolower(logger->ask(fmt("Do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)? This may allow the flake to gain root, see the nix.conf manual page.", name, valueS)).value_or('n')) == 'y') {
|
||||||
trusted = true;
|
trusted = true;
|
||||||
}
|
}
|
||||||
if (std::tolower(logger->ask(fmt("do you want to permanently mark this value as %s (y/N)?", trusted ? "trusted": "untrusted" )).value_or('n')) == 'y') {
|
if (std::tolower(logger->ask(fmt("do you want to permanently mark this value as %s (y/N)?", trusted ? "trusted": "untrusted" )).value_or('n')) == 'y') {
|
||||||
|
@ -68,13 +74,21 @@ void ConfigFile::apply()
|
||||||
writeTrustedList(trustedList);
|
writeTrustedList(trustedList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!trusted) {
|
break;
|
||||||
warn("ignoring untrusted flake configuration setting '%s'.\nPass '%s' to trust it", name, "--accept-flake-config");
|
}
|
||||||
continue;
|
case nix::AcceptFlakeConfig::False: {
|
||||||
|
trusted = false;
|
||||||
|
break;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trusted) {
|
||||||
|
debug("accepting trusted flake configuration setting '%s'", name);
|
||||||
globalConfig.set(name, valueS);
|
globalConfig.set(name, valueS);
|
||||||
|
} else {
|
||||||
|
warn("ignoring untrusted flake configuration setting '%s', pass '%s' to trust it (may allow the flake to gain root, see the nix.conf manual page)", name, "--accept-flake-config");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,50 @@
|
||||||
|
#include "abstract-setting-to-json.hh"
|
||||||
|
#include "args.hh"
|
||||||
|
#include "config-impl.hh"
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
template<> AcceptFlakeConfig BaseSetting<AcceptFlakeConfig>::parse(const std::string & str) const
|
||||||
|
{
|
||||||
|
if (str == "true") return AcceptFlakeConfig::True;
|
||||||
|
else if (str == "ask") return AcceptFlakeConfig::Ask;
|
||||||
|
else if (str == "false") return AcceptFlakeConfig::False;
|
||||||
|
else throw UsageError("option '%s' has invalid value '%s'", name, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> std::string BaseSetting<AcceptFlakeConfig>::to_string() const
|
||||||
|
{
|
||||||
|
if (value == AcceptFlakeConfig::True) return "true";
|
||||||
|
else if (value == AcceptFlakeConfig::Ask) return "ask";
|
||||||
|
else if (value == AcceptFlakeConfig::False) return "false";
|
||||||
|
else abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> void BaseSetting<AcceptFlakeConfig>::convertToArg(Args & args, const std::string & category)
|
||||||
|
{
|
||||||
|
args.addFlag({
|
||||||
|
.longName = name,
|
||||||
|
.description = "Accept Lix configuration options from flakes without confirmation. This allows flakes to gain root access to your machine if you are a trusted user; see the nix.conf manual page for more details.",
|
||||||
|
.category = category,
|
||||||
|
.handler = {[this]() { override(AcceptFlakeConfig::True); }}
|
||||||
|
});
|
||||||
|
args.addFlag({
|
||||||
|
.longName = "ask-" + name,
|
||||||
|
.description = "Ask whether to accept Lix configuration options from flakes.",
|
||||||
|
.category = category,
|
||||||
|
.handler = {[this]() { override(AcceptFlakeConfig::Ask); }}
|
||||||
|
});
|
||||||
|
args.addFlag({
|
||||||
|
.longName = "no-" + name,
|
||||||
|
.description = "Reject Lix configuration options from flakes.",
|
||||||
|
.category = category,
|
||||||
|
.handler = {[this]() { override(AcceptFlakeConfig::False); }}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
FetchSettings::FetchSettings()
|
FetchSettings::FetchSettings()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
enum class AcceptFlakeConfig { True, Ask, False };
|
||||||
|
|
||||||
struct FetchSettings : public Config
|
struct FetchSettings : public Config
|
||||||
{
|
{
|
||||||
FetchSettings();
|
FetchSettings();
|
||||||
|
@ -86,15 +88,21 @@ struct FetchSettings : public Config
|
||||||
"Whether to use flake registries to resolve flake references.",
|
"Whether to use flake registries to resolve flake references.",
|
||||||
{}, true, Xp::Flakes};
|
{}, true, Xp::Flakes};
|
||||||
|
|
||||||
Setting<bool> acceptFlakeConfig{this, false, "accept-flake-config",
|
Setting<AcceptFlakeConfig> acceptFlakeConfig{
|
||||||
|
this, AcceptFlakeConfig::Ask, "accept-flake-config",
|
||||||
R"(
|
R"(
|
||||||
Whether to accept Lix configuration from the `nixConfig` attribute of
|
Whether to accept Lix configuration from the `nixConfig` attribute of
|
||||||
a flake without prompting. This is almost always a very bad idea.
|
a flake. Doing so as a trusted user allows Nix flakes to gain root
|
||||||
|
|
||||||
Setting this setting as a trusted user allows Nix flakes to gain root
|
|
||||||
access on your machine if they set one of the several
|
access on your machine if they set one of the several
|
||||||
trusted-user-only settings that execute commands as root.
|
trusted-user-only settings that execute commands as root.
|
||||||
|
|
||||||
|
If set to `true`, such configuration will be accepted without asking;
|
||||||
|
this is almost always a very bad idea. Setting this to `ask` will
|
||||||
|
prompt the user each time whether to allow a certain configuration
|
||||||
|
option set this way, and offer to optionally remember their choice.
|
||||||
|
When set to `false`, the configuration will be automatically
|
||||||
|
declined.
|
||||||
|
|
||||||
See [multi-user installations](@docroot@/installation/multi-user.md)
|
See [multi-user installations](@docroot@/installation/multi-user.md)
|
||||||
for more details on the Lix security model.
|
for more details on the Lix security model.
|
||||||
)",
|
)",
|
||||||
|
|
|
@ -403,11 +403,8 @@ struct GitInputScheme : InputScheme
|
||||||
AutoDelete const _delete{msgPath};
|
AutoDelete const _delete{msgPath};
|
||||||
writeFile(msgPath, *commitMsg);
|
writeFile(msgPath, *commitMsg);
|
||||||
|
|
||||||
// Pause the logger to allow for user input (such as a gpg passphrase) in `git commit`
|
|
||||||
logger->pause();
|
|
||||||
Finally restoreLogger([]() { logger->resume(); });
|
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", *root, "--git-dir", gitDir, "commit", std::string(path.rel()), "-F", msgPath });
|
{ "-C", *root, "--git-dir", gitDir, "commit", std::string(path.rel()), "-F", msgPath }, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,50 +44,55 @@ static std::string_view storePathToName(std::string_view path)
|
||||||
ProgressBar::ProgressBar(bool isTTY)
|
ProgressBar::ProgressBar(bool isTTY)
|
||||||
: isTTY(isTTY)
|
: isTTY(isTTY)
|
||||||
{
|
{
|
||||||
state_.lock()->active = isTTY;
|
resume();
|
||||||
updateThread = std::thread([&]() {
|
|
||||||
auto state(state_.lock());
|
|
||||||
auto nextWakeup = A_LONG_TIME;
|
|
||||||
while (state->active) {
|
|
||||||
if (!state->haveUpdate)
|
|
||||||
state.wait_for(updateCV, nextWakeup);
|
|
||||||
nextWakeup = draw(*state, {});
|
|
||||||
state.wait_for(quitCV, std::chrono::milliseconds(50));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressBar::~ProgressBar()
|
ProgressBar::~ProgressBar()
|
||||||
{
|
{
|
||||||
stop();
|
pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by destructor, can't be overridden */
|
void ProgressBar::pause()
|
||||||
void ProgressBar::stop()
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto state(state_.lock());
|
auto state(state_.lock());
|
||||||
if (!state->active) return;
|
if (!state->active) return;
|
||||||
state->active = false;
|
state->active = false;
|
||||||
writeToStderr("\r\e[K");
|
|
||||||
updateCV.notify_one();
|
updateCV.notify_one();
|
||||||
quitCV.notify_one();
|
|
||||||
}
|
}
|
||||||
updateThread.join();
|
updateThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressBar::pause()
|
void ProgressBar::resetProgress()
|
||||||
{
|
{
|
||||||
state_.lock()->paused = true;
|
auto state(state_.lock());
|
||||||
writeToStderr("\r\e[K");
|
auto prevActive = state->active;
|
||||||
|
*state = ProgressBar::State {
|
||||||
|
.active = prevActive,
|
||||||
|
};
|
||||||
|
update(*state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressBar::resume()
|
void ProgressBar::resume()
|
||||||
{
|
{
|
||||||
state_.lock()->paused = false;
|
if (isTTY) {
|
||||||
|
auto state(state_.lock());
|
||||||
|
if (state->active) return;
|
||||||
|
state->active = true;
|
||||||
|
state->haveUpdate = true;
|
||||||
|
updateThread = std::thread([&]() {
|
||||||
|
auto state(state_.lock());
|
||||||
|
auto nextWakeup = A_LONG_TIME;
|
||||||
|
for (;;) {
|
||||||
|
if (!state->haveUpdate)
|
||||||
|
state.wait_for(updateCV, nextWakeup);
|
||||||
|
if (!state->active)
|
||||||
|
break;
|
||||||
|
nextWakeup = std::max(draw(*state, {}), std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
writeToStderr("\r\e[K");
|
writeToStderr("\r\e[K");
|
||||||
state_.lock()->haveUpdate = true;
|
});
|
||||||
updateCV.notify_one();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProgressBar::isVerbose()
|
bool ProgressBar::isVerbose()
|
||||||
|
@ -318,7 +323,7 @@ std::chrono::milliseconds ProgressBar::draw(State & state, const std::optional<s
|
||||||
auto nextWakeup = A_LONG_TIME;
|
auto nextWakeup = A_LONG_TIME;
|
||||||
|
|
||||||
state.haveUpdate = false;
|
state.haveUpdate = false;
|
||||||
if (state.paused || !state.active) return nextWakeup;
|
if (!state.active) return nextWakeup;
|
||||||
|
|
||||||
auto windowSize = getWindowSize();
|
auto windowSize = getWindowSize();
|
||||||
auto width = windowSize.second;
|
auto width = windowSize.second;
|
||||||
|
@ -559,16 +564,4 @@ Logger * makeProgressBar()
|
||||||
return new ProgressBar(shouldANSI());
|
return new ProgressBar(shouldANSI());
|
||||||
}
|
}
|
||||||
|
|
||||||
void startProgressBar()
|
|
||||||
{
|
|
||||||
logger = makeProgressBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopProgressBar()
|
|
||||||
{
|
|
||||||
auto progressBar = dynamic_cast<ProgressBar *>(logger);
|
|
||||||
if (progressBar) progressBar->stop();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,15 @@ struct ProgressBar : public Logger
|
||||||
|
|
||||||
uint64_t corruptedPaths = 0, untrustedPaths = 0;
|
uint64_t corruptedPaths = 0, untrustedPaths = 0;
|
||||||
|
|
||||||
bool active = true;
|
bool active = false;
|
||||||
bool paused = false;
|
bool haveUpdate = false;
|
||||||
bool haveUpdate = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
|
||||||
std::thread updateThread;
|
std::thread updateThread;
|
||||||
|
|
||||||
std::condition_variable quitCV, updateCV;
|
std::condition_variable updateCV;
|
||||||
|
|
||||||
bool printBuildLogs = false;
|
bool printBuildLogs = false;
|
||||||
bool printMultiline = false;
|
bool printMultiline = false;
|
||||||
|
@ -67,10 +66,10 @@ struct ProgressBar : public Logger
|
||||||
|
|
||||||
~ProgressBar();
|
~ProgressBar();
|
||||||
|
|
||||||
void stop() override final;
|
|
||||||
|
|
||||||
void pause() override;
|
void pause() override;
|
||||||
|
|
||||||
|
void resetProgress() override;
|
||||||
|
|
||||||
void resume() override;
|
void resume() override;
|
||||||
|
|
||||||
bool isVerbose() override;
|
bool isVerbose() override;
|
||||||
|
@ -113,8 +112,4 @@ struct ProgressBar : public Logger
|
||||||
|
|
||||||
Logger * makeProgressBar();
|
Logger * makeProgressBar();
|
||||||
|
|
||||||
void startProgressBar();
|
|
||||||
|
|
||||||
void stopProgressBar();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "gc-store.hh"
|
#include "gc-store.hh"
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "loggers.hh"
|
#include "loggers.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "current-process.hh"
|
#include "current-process.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -349,7 +348,7 @@ RunPager::RunPager()
|
||||||
if (!pager) pager = getenv("PAGER");
|
if (!pager) pager = getenv("PAGER");
|
||||||
if (pager && ((std::string) pager == "" || (std::string) pager == "cat")) return;
|
if (pager && ((std::string) pager == "" || (std::string) pager == "cat")) return;
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
Pipe toPager;
|
Pipe toPager;
|
||||||
toPager.create();
|
toPager.create();
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#if HAVE_SECCOMP
|
#if HAVE_SECCOMP
|
||||||
#include "linux/fchmodat2-compat.hh"
|
|
||||||
#include <seccomp.h>
|
#include <seccomp.h>
|
||||||
#endif
|
#endif
|
||||||
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
|
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
|
||||||
|
@ -1602,6 +1601,12 @@ void LocalDerivationGoal::chownToBuilder(const Path & path)
|
||||||
throw SysError("cannot change ownership of '%1%'", 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()
|
void setupSeccomp()
|
||||||
{
|
{
|
||||||
|
@ -1609,7 +1614,9 @@ void setupSeccomp()
|
||||||
#if HAVE_SECCOMP
|
#if HAVE_SECCOMP
|
||||||
scmp_filter_ctx ctx;
|
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");
|
throw SysError("unable to initialize seccomp mode 2");
|
||||||
|
|
||||||
Finally cleanup([&]() {
|
Finally cleanup([&]() {
|
||||||
|
@ -1644,28 +1651,520 @@ void setupSeccomp()
|
||||||
seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32) != 0)
|
seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32) != 0)
|
||||||
printError("unable to add mips64el-*abin32 seccomp architecture");
|
printError("unable to add mips64el-*abin32 seccomp architecture");
|
||||||
|
|
||||||
/* Prevent builders from creating setuid/setgid binaries. */
|
// This list is intended for machine consumption.
|
||||||
for (int perm : { S_ISUID, S_ISGID }) {
|
// Please keep its format, order and BEGIN/END markers.
|
||||||
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)
|
// 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
|
||||||
|
|
||||||
|
// 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");
|
throw SysError("unable to add seccomp rule");
|
||||||
|
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1,
|
// setxattr family: prevent creation of extended attributes or ACLs.
|
||||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
// Not all filesystems support them, and they're incompatible with the NAR format.
|
||||||
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. */
|
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(setxattr), 0) != 0 ||
|
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(lsetxattr), 0) != 0 ||
|
||||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
||||||
|
@ -1699,11 +2198,7 @@ void LocalDerivationGoal::runChild()
|
||||||
|
|
||||||
commonChildInit();
|
commonChildInit();
|
||||||
|
|
||||||
try {
|
|
||||||
setupSeccomp();
|
setupSeccomp();
|
||||||
} catch (...) {
|
|
||||||
if (buildUser) throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setUser = true;
|
bool setUser = true;
|
||||||
|
|
||||||
|
|
|
@ -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 Lix 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
|
|
|
@ -117,9 +117,8 @@ public:
|
||||||
|
|
||||||
virtual ~Logger() { }
|
virtual ~Logger() { }
|
||||||
|
|
||||||
virtual void stop() { };
|
|
||||||
|
|
||||||
virtual void pause() { };
|
virtual void pause() { };
|
||||||
|
virtual void resetProgress() { };
|
||||||
virtual void resume() { };
|
virtual void resume() { };
|
||||||
|
|
||||||
// Whether the logger prints the whole build log
|
// Whether the logger prints the whole build log
|
||||||
|
|
|
@ -543,7 +543,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
restoreProcessContext();
|
restoreProcessContext();
|
||||||
|
|
||||||
logger->stop();
|
logger->pause();
|
||||||
|
|
||||||
execvp(shell->c_str(), argPtrs.data());
|
execvp(shell->c_str(), argPtrs.data());
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
outPaths.push_back(outputPath);
|
outPaths.push_back(outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger->stop();
|
logger->pause();
|
||||||
|
|
||||||
for (auto & path : outPaths)
|
for (auto & path : outPaths)
|
||||||
std::cout << store->printStorePath(path) << '\n';
|
std::cout << store->printStorePath(path) << '\n';
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
||||||
createOutLinks(outLink, buildables, *store2);
|
createOutLinks(outLink, buildables, *store2);
|
||||||
|
|
||||||
if (printOutputPaths) {
|
if (printOutputPaths) {
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
for (auto & buildable : buildables) {
|
for (auto & buildable : buildables) {
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
[&](const BuiltPath::Opaque & bo) {
|
[&](const BuiltPath::Opaque & bo) {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include "nar-accessor.hh"
|
#include "nar-accessor.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ struct MixCat : virtual Args
|
||||||
|
|
||||||
auto file = accessor->readFile(path);
|
auto file = accessor->readFile(path);
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
writeFull(STDOUT_FILENO, file);
|
writeFull(STDOUT_FILENO, file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "outputs-spec.hh"
|
#include "outputs-spec.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "run.hh"
|
#include "run.hh"
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
@ -690,7 +689,7 @@ struct CmdPrintDevEnv : Common, MixJSON
|
||||||
{
|
{
|
||||||
auto buildEnvironment = getBuildEnvironment(store, installable).first;
|
auto buildEnvironment = getBuildEnvironment(store, installable).first;
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
logger->writeToStdout(buildEnvironment.toJSON());
|
logger->writeToStdout(buildEnvironment.toJSON());
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ struct CmdDumpPath : StorePathCommand
|
||||||
|
|
||||||
void run(ref<Store> store, const StorePath & storePath) override
|
void run(ref<Store> store, const StorePath & storePath) override
|
||||||
{
|
{
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
FdSink sink(STDOUT_FILENO);
|
FdSink sink(STDOUT_FILENO);
|
||||||
store->narFromPath(storePath, sink);
|
store->narFromPath(storePath, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
|
@ -57,7 +56,7 @@ struct CmdDumpPath2 : Command
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
FdSink sink(STDOUT_FILENO);
|
FdSink sink(STDOUT_FILENO);
|
||||||
dumpPath(path, sink);
|
dumpPath(path, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "attr-path.hh"
|
#include "attr-path.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "editor-for.hh"
|
#include "editor-for.hh"
|
||||||
#include "current-process.hh"
|
#include "current-process.hh"
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ struct CmdEdit : InstallableCommand
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
auto args = editorFor(file, line);
|
auto args = editorFor(file, line);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "eval-inline.hh"
|
#include "eval-inline.hh"
|
||||||
#include "value-to-json.hh"
|
#include "value-to-json.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeTo) {
|
if (writeTo) {
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
if (pathExists(*writeTo))
|
if (pathExists(*writeTo))
|
||||||
throw Error("path '%s' already exists", *writeTo);
|
throw Error("path '%s' already exists", *writeTo);
|
||||||
|
@ -114,7 +113,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (raw) {
|
else if (raw) {
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
writeFull(STDOUT_FILENO, *state->coerceToString(noPos, *v, context, "while generating the eval command output"));
|
writeFull(STDOUT_FILENO, *state->coerceToString(noPos, *v, context, "while generating the eval command output"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "log-store.hh"
|
#include "log-store.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ struct CmdLog : InstallableCommand
|
||||||
|
|
||||||
auto log = logSub.getBuildLog(path);
|
auto log = logSub.getBuildLog(path);
|
||||||
if (!log) continue;
|
if (!log) continue;
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
||||||
writeFull(STDOUT_FILENO, *log);
|
writeFull(STDOUT_FILENO, *log);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -346,8 +346,6 @@ void mainWrapped(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Finally f([] { logger->stop(); });
|
|
||||||
|
|
||||||
programPath = argv[0];
|
programPath = argv[0];
|
||||||
auto programName = std::string(baseNameOf(programPath));
|
auto programName = std::string(baseNameOf(programPath));
|
||||||
|
|
||||||
|
@ -363,7 +361,8 @@ void mainWrapped(int argc, char * * argv)
|
||||||
|
|
||||||
evalSettings.pureEval = true;
|
evalSettings.pureEval = true;
|
||||||
|
|
||||||
setLogFormat("bar");
|
setLogFormat(LogFormat::bar);
|
||||||
|
Finally f([] { logger->pause(); });
|
||||||
settings.verboseBuild = false;
|
settings.verboseBuild = false;
|
||||||
if (isatty(STDERR_FILENO)) {
|
if (isatty(STDERR_FILENO)) {
|
||||||
verbosity = lvlNotice;
|
verbosity = lvlNotice;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
#include "common-args.hh"
|
#include "common-args.hh"
|
||||||
|
#include "loggers.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "attr-path.hh"
|
#include "attr-path.hh"
|
||||||
#include "eval-inline.hh"
|
#include "eval-inline.hh"
|
||||||
|
@ -180,10 +180,8 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
||||||
if (args.size() > 2)
|
if (args.size() > 2)
|
||||||
throw UsageError("too many arguments");
|
throw UsageError("too many arguments");
|
||||||
|
|
||||||
Finally f([]() { stopProgressBar(); });
|
|
||||||
|
|
||||||
if (isatty(STDERR_FILENO))
|
if (isatty(STDERR_FILENO))
|
||||||
startProgressBar();
|
setLogFormat(LogFormat::bar);
|
||||||
|
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
|
auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
|
||||||
|
@ -237,7 +235,7 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
||||||
auto [storePath, hash] = prefetchFile(
|
auto [storePath, hash] = prefetchFile(
|
||||||
store, resolveMirrorUrl(*state, url), name, ht, expectedHash, unpack, executable);
|
store, resolveMirrorUrl(*state, url), name, ht, expectedHash, unpack, executable);
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
if (!printPath)
|
if (!printPath)
|
||||||
printInfo("path is '%s'", store->printStorePath(storePath));
|
printInfo("path is '%s'", store->printStorePath(storePath));
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "local-store.hh"
|
#include "local-store.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "build/personality.hh"
|
#include "build/personality.hh"
|
||||||
#include "current-process.hh"
|
#include "current-process.hh"
|
||||||
|
@ -31,7 +30,7 @@ void runProgramInStore(ref<Store> store,
|
||||||
const Strings & args,
|
const Strings & args,
|
||||||
std::optional<std::string_view> system)
|
std::optional<std::string_view> system)
|
||||||
{
|
{
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
restoreProcessContext();
|
restoreProcessContext();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
@ -222,7 +221,7 @@ struct CmdKey : NixMultiCommand
|
||||||
if (!command)
|
if (!command)
|
||||||
throw UsageError("'nix key' requires a sub-command.");
|
throw UsageError("'nix key' requires a sub-command.");
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
command->second->run();
|
command->second->run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
#include "attr-path.hh"
|
#include "attr-path.hh"
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ struct CmdUpgradeNix : MixDryRun, EvalCommand
|
||||||
auto version = DrvName(storePath.name()).version;
|
auto version = DrvName(storePath.name()).version;
|
||||||
|
|
||||||
if (dryRun) {
|
if (dryRun) {
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
warn("would upgrade to version %s", version);
|
warn("would upgrade to version %s", version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +105,7 @@ struct CmdUpgradeNix : MixDryRun, EvalCommand
|
||||||
throw Error("could not verify that '%s' works", program);
|
throw Error("could not verify that '%s' works", program);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopProgressBar();
|
logger->pause();
|
||||||
|
|
||||||
auto const fullStorePath = store->printStorePath(storePath);
|
auto const fullStorePath = store->printStorePath(storePath);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "progress-bar.hh"
|
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
|
||||||
auto dependencyPath = *optDependencyPath;
|
auto dependencyPath = *optDependencyPath;
|
||||||
auto dependencyPathHash = dependencyPath.hashPart();
|
auto dependencyPathHash = dependencyPath.hashPart();
|
||||||
|
|
||||||
stopProgressBar(); // FIXME
|
logger->pause(); // FIXME
|
||||||
|
|
||||||
auto accessor = store->getFSAccessor();
|
auto accessor = store->getFSAccessor();
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ NIX_CONFIG='
|
||||||
experimental-features = nix-command
|
experimental-features = nix-command
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||||
grepQuiet "false" $TEST_ROOT/stdout
|
grepQuiet "ask" $TEST_ROOT/stdout
|
||||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
||||||
|
|
||||||
# 'flakes' experimental-feature is disabled after, ignore and warn
|
# 'flakes' experimental-feature is disabled after, ignore and warn
|
||||||
|
@ -40,7 +40,7 @@ NIX_CONFIG='
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
experimental-features = nix-command
|
experimental-features = nix-command
|
||||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||||
grepQuiet "false" $TEST_ROOT/stdout
|
grepQuiet "ask" $TEST_ROOT/stdout
|
||||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
||||||
|
|
||||||
# 'flakes' experimental-feature is enabled before, process
|
# 'flakes' experimental-feature is enabled before, process
|
||||||
|
|
|
@ -28,6 +28,11 @@ nix build < /dev/null
|
||||||
(! [[ -f post-hook-ran ]])
|
(! [[ -f post-hook-ran ]])
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
|
# likewise with no-accept-flake-config
|
||||||
|
nix build --no-accept-flake-config
|
||||||
|
(! [[ -f post-hook-ran ]])
|
||||||
|
clearStore
|
||||||
|
|
||||||
nix build --accept-flake-config
|
nix build --accept-flake-config
|
||||||
test -f post-hook-ran || fail "The post hook should have ran"
|
test -f post-hook-ran || fail "The post hook should have ran"
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
char *name = getenv("out");
|
|
||||||
FILE *fd = fopen(name, "w");
|
|
||||||
fprintf(fd, "henlo :3");
|
|
||||||
fclose(fd);
|
|
||||||
|
|
||||||
// FIXME use something nicer here that's less
|
|
||||||
// platform-dependent as soon as we go to 24.05
|
|
||||||
// and the glibc is new enough to support fchmodat2
|
|
||||||
long rs = syscall(452, NULL, name, S_ISUID, 0);
|
|
||||||
assert(rs == -1);
|
|
||||||
assert(errno == EPERM);
|
|
||||||
}
|
|
|
@ -4,17 +4,6 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
pkgs = config.nodes.machine.nixpkgs.pkgs;
|
pkgs = config.nodes.machine.nixpkgs.pkgs;
|
||||||
|
|
||||||
fchmodat2-builder = pkgs.runCommandCC "fchmodat2-suid" {
|
|
||||||
passAsFile = [ "code" ];
|
|
||||||
code = builtins.readFile ./fchmodat2-suid.c;
|
|
||||||
# Doesn't work with -O0, shuts up the warning about that.
|
|
||||||
hardeningDisable = [ "fortify" ];
|
|
||||||
} ''
|
|
||||||
mkdir -p $out/bin/
|
|
||||||
$CC -x c "$codePath" -O0 -g -o $out/bin/fchmodat2-suid
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
name = "setuid";
|
name = "setuid";
|
||||||
|
@ -27,26 +16,13 @@ in
|
||||||
virtualisation.additionalPaths = [
|
virtualisation.additionalPaths = [
|
||||||
pkgs.stdenvNoCC
|
pkgs.stdenvNoCC
|
||||||
pkgs.pkgsi686Linux.stdenvNoCC
|
pkgs.pkgsi686Linux.stdenvNoCC
|
||||||
fchmodat2-builder
|
|
||||||
];
|
];
|
||||||
# need at least 6.6 to test for fchmodat2
|
|
||||||
boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_6;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes }: ''
|
testScript = { nodes }: ''
|
||||||
# fmt: off
|
# fmt: off
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
with subtest("fchmodat2 suid regression test"):
|
|
||||||
machine.succeed("""
|
|
||||||
nix-build -E '(with import <nixpkgs> {}; runCommand "fchmodat2-suid" {
|
|
||||||
BUILDER = builtins.storePath ${fchmodat2-builder};
|
|
||||||
} "
|
|
||||||
exec \\"$BUILDER\\"/bin/fchmodat2-suid
|
|
||||||
")'
|
|
||||||
""")
|
|
||||||
|
|
||||||
# Copying to /tmp should succeed.
|
# Copying to /tmp should succeed.
|
||||||
machine.succeed(r"""
|
machine.succeed(r"""
|
||||||
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" {} "
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" {} "
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "progress-bar.hh"
|
#include "progress-bar.hh"
|
||||||
|
#include "loggers.hh"
|
||||||
#include "logging.hh"
|
#include "logging.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ namespace nix
|
||||||
initNix();
|
initNix();
|
||||||
initGC();
|
initGC();
|
||||||
|
|
||||||
startProgressBar();
|
setLogFormat(LogFormat::bar);
|
||||||
ASSERT_NE(dynamic_cast<ProgressBar *>(logger), nullptr);
|
ASSERT_NE(dynamic_cast<ProgressBar *>(logger), nullptr);
|
||||||
ProgressBar & progressBar = dynamic_cast<ProgressBar &>(*logger);
|
ProgressBar & progressBar = dynamic_cast<ProgressBar &>(*logger);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue