mirror of
https://github.com/NixOS/nix
synced 2025-07-06 09:11:47 +02:00
libstore: Don't default build-dir to temp-dir, store setting
If a build directory is accessible to other users it is possible to smuggle data in and out of build directories. Usually this is only a build purity problem, but in combination with other issues it can be used to break out of a build sandbox. to prevent this we default to using a subdirectory of nixStateDir (which is more restrictive). (cherry picked from pennae Lix commit 55b416f6897fb0d8a9315a530a9b7f0914458ded) (store setting done by roberth)
This commit is contained in:
parent
9af4c267c6
commit
88b7db1ba4
11 changed files with 62 additions and 15 deletions
|
@ -6,6 +6,7 @@
|
|||
#include "nix/util/abstract-setting-to-json.hh"
|
||||
#include "nix/util/compute-levels.hh"
|
||||
#include "nix/util/signals.hh"
|
||||
#include "nix/util/types.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
|
|
@ -697,14 +697,7 @@ public:
|
|||
|
||||
Setting<std::optional<Path>> buildDir{this, std::nullopt, "build-dir",
|
||||
R"(
|
||||
The directory on the host, in which derivations' temporary build directories are created.
|
||||
|
||||
If not set, Nix uses the system temporary directory indicated by the `TMPDIR` environment variable.
|
||||
Note that builds are often performed by the Nix daemon, so its `TMPDIR` is used, and not that of the Nix command line interface.
|
||||
|
||||
This is also the location where [`--keep-failed`](@docroot@/command-ref/opt-common.md#opt-keep-failed) leaves its files.
|
||||
|
||||
If Nix runs without sandbox, or if the platform does not support sandboxing with bind mounts (e.g. macOS), then the [`builder`](@docroot@/language/derivations.md#attr-builder)'s environment contains this directory instead of the virtual location [`sandbox-build-dir`](#conf-sandbox-build-dir).
|
||||
Override the `build-dir` store setting for all stores that have this setting.
|
||||
)"};
|
||||
|
||||
Setting<PathSet> allowedImpureHostPrefixes{this, {}, "allowed-impure-host-deps",
|
||||
|
|
|
@ -34,7 +34,38 @@ struct OptimiseStats
|
|||
uint64_t bytesFreed = 0;
|
||||
};
|
||||
|
||||
struct LocalStoreConfig : std::enable_shared_from_this<LocalStoreConfig>, virtual LocalFSStoreConfig
|
||||
struct LocalBuildStoreConfig : virtual LocalFSStoreConfig {
|
||||
|
||||
private:
|
||||
/**
|
||||
Input for computing the build directory. See `getBuildDir()`.
|
||||
*/
|
||||
Setting<std::optional<Path>> buildDir{this, std::nullopt, "build-dir",
|
||||
R"(
|
||||
The directory on the host, in which derivations' temporary build directories are created.
|
||||
|
||||
If not set, Nix will use the `builds` subdirectory of its configured state directory.
|
||||
|
||||
Note that builds are often performed by the Nix daemon, so its `build-dir` applies.
|
||||
|
||||
Nix will create this directory automatically with suitable permissions if it does not exist.
|
||||
Otherwise its permissions must allow all users to traverse the directory (i.e. it must have `o+x` set, in unix parlance) for non-sandboxed builds to work correctly.
|
||||
|
||||
This is also the location where [`--keep-failed`](@docroot@/command-ref/opt-common.md#opt-keep-failed) leaves its files.
|
||||
|
||||
If Nix runs without sandbox, or if the platform does not support sandboxing with bind mounts (e.g. macOS), then the [`builder`](@docroot@/language/derivations.md#attr-builder)'s environment will contain this directory, instead of the virtual location [`sandbox-build-dir`](#conf-sandbox-build-dir).
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> `build-dir` must not be set to a world-writable directory.
|
||||
> Placing temporary build directories in a world-writable place allows other users to access or modify build data that is currently in use.
|
||||
> This alone is merely an impurity, but combined with another factor this has allowed malicious derivations to escape the build sandbox.
|
||||
)"};
|
||||
public:
|
||||
Path getBuildDir() const;
|
||||
};
|
||||
|
||||
struct LocalStoreConfig : std::enable_shared_from_this<LocalStoreConfig>, virtual LocalFSStoreConfig, virtual LocalBuildStoreConfig
|
||||
{
|
||||
using LocalFSStoreConfig::LocalFSStoreConfig;
|
||||
|
||||
|
|
|
@ -77,6 +77,18 @@ std::string LocalStoreConfig::doc()
|
|||
;
|
||||
}
|
||||
|
||||
Path LocalBuildStoreConfig::getBuildDir() const
|
||||
{
|
||||
if (settings.buildDir.get().has_value()) {
|
||||
return *settings.buildDir.get();
|
||||
}
|
||||
if (buildDir.get().has_value()) {
|
||||
return *buildDir.get();
|
||||
}
|
||||
|
||||
return stateDir.get() + "/builds";
|
||||
}
|
||||
|
||||
ref<Store> LocalStore::Config::openStore() const
|
||||
{
|
||||
return make_ref<LocalStore>(ref{shared_from_this()});
|
||||
|
|
|
@ -725,9 +725,13 @@ void DerivationBuilderImpl::startBuilder()
|
|||
throw BuildError(msg);
|
||||
}
|
||||
|
||||
auto buildDir = getLocalStore(store).config->getBuildDir();
|
||||
|
||||
createDirs(buildDir);
|
||||
|
||||
/* Create a temporary directory where the build will take
|
||||
place. */
|
||||
topTmpDir = createTempDir(settings.buildDir.get().value_or(""), "nix-build-" + std::string(drvPath.name()), 0700);
|
||||
topTmpDir = createTempDir(buildDir, "nix-build-" + std::string(drvPath.name()), 0700);
|
||||
setBuildTmpDir();
|
||||
assert(!tmpDir.empty());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue