Merge pull request #70874 from edolstra/no-world-writable-per-user

[WIP] Don't create /nix/var/nix/{gcroots,per-user}/per-user with 1777 permission
This commit is contained in:
Eelco Dolstra 2019-10-10 16:28:49 +02:00 committed by GitHub
commit e8bc181154
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 119 deletions

View File

@ -142,7 +142,6 @@
./programs/seahorse.nix
./programs/slock.nix
./programs/shadow.nix
./programs/shell.nix
./programs/spacefm.nix
./programs/singularity.nix
./programs/ssh.nix

View File

@ -1,54 +0,0 @@
# This module defines a standard configuration for NixOS shells.
{ config, lib, ... }:
with lib;
{
config = {
environment.shellInit =
''
# Set up the per-user profile.
mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR"
if [ "$(stat -c '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then
echo "WARNING: the per-user profile dir $NIX_USER_PROFILE_DIR should belong to user id $(id -u)" >&2
fi
if [ -w "$HOME" ]; then
if ! [ -L "$HOME/.nix-profile" ]; then
if [ "$USER" != root ]; then
ln -s "$NIX_USER_PROFILE_DIR/profile" "$HOME/.nix-profile"
else
# Root installs in the system-wide profile by default.
ln -s /nix/var/nix/profiles/default "$HOME/.nix-profile"
fi
fi
# Subscribe the root user to the NixOS channel by default.
if [ "$USER" = root -a ! -e "$HOME/.nix-channels" ]; then
echo "${config.system.defaultChannel} nixos" > "$HOME/.nix-channels"
fi
# Create the per-user garbage collector roots directory.
NIX_USER_GCROOTS_DIR="/nix/var/nix/gcroots/per-user/$USER"
mkdir -m 0755 -p "$NIX_USER_GCROOTS_DIR"
if [ "$(stat -c '%u' "$NIX_USER_GCROOTS_DIR")" != "$(id -u)" ]; then
echo "WARNING: the per-user gcroots dir $NIX_USER_GCROOTS_DIR should belong to user id $(id -u)" >&2
fi
# Set up a default Nix expression from which to install stuff.
if [ ! -e "$HOME/.nix-defexpr" -o -L "$HOME/.nix-defexpr" ]; then
rm -f "$HOME/.nix-defexpr"
mkdir -p "$HOME/.nix-defexpr"
if [ "$USER" != root ]; then
ln -s /nix/var/nix/profiles/per-user/root/channels "$HOME/.nix-defexpr/channels_root"
fi
fi
fi
'';
};
}

View File

@ -10,7 +10,6 @@ let
nixVersion = getVersion nix;
isNix20 = versionAtLeast nixVersion "2.0pre";
isNix23 = versionAtLeast nixVersion "2.3pre";
makeNixBuildUser = nr:
@ -28,39 +27,26 @@ let
nixbldUsers = map makeNixBuildUser (range 1 cfg.nrBuildUsers);
nixConf =
let
# In Nix < 2.0, If we're using sandbox for builds, then provide
# /bin/sh in the sandbox as a bind-mount to bash. This means we
# also need to include the entire closure of bash. Nix >= 2.0
# provides a /bin/sh by default.
sh = pkgs.runtimeShell;
binshDeps = pkgs.writeReferencesToFile sh;
in
pkgs.runCommand "nix.conf" { preferLocalBuild = true; extraOptions = cfg.extraOptions; } (''
${optionalString (!isNix20) ''
extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done)
''}
assert versionAtLeast nixVersion "2.2";
pkgs.runCommand "nix.conf" { preferLocalBuild = true; extraOptions = cfg.extraOptions; } (
''
cat > $out <<END
# WARNING: this file is generated from the nix.* options in
# your NixOS configuration, typically
# /etc/nixos/configuration.nix. Do not edit it!
build-users-group = nixbld
${if isNix20 then "max-jobs" else "build-max-jobs"} = ${toString (cfg.maxJobs)}
${if isNix20 then "cores" else "build-cores"} = ${toString (cfg.buildCores)}
${if isNix20 then "sandbox" else "build-use-sandbox"} = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox}
${if isNix20 then "extra-sandbox-paths" else "build-sandbox-paths"} = ${toString cfg.sandboxPaths} ${optionalString (!isNix20) "/bin/sh=${sh} $(echo $extraPaths)"}
${if isNix20 then "substituters" else "binary-caches"} = ${toString cfg.binaryCaches}
${if isNix20 then "trusted-substituters" else "trusted-binary-caches"} = ${toString cfg.trustedBinaryCaches}
${if isNix20 then "trusted-public-keys" else "binary-cache-public-keys"} = ${toString cfg.binaryCachePublicKeys}
max-jobs = ${toString (cfg.maxJobs)}
cores = ${toString (cfg.buildCores)}
sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox}
extra-sandbox-paths = ${toString cfg.sandboxPaths}
substituters = ${toString cfg.binaryCaches}
trusted-substituters = ${toString cfg.trustedBinaryCaches}
trusted-public-keys = ${toString cfg.binaryCachePublicKeys}
auto-optimise-store = ${boolToString cfg.autoOptimiseStore}
${if isNix20 then ''
require-sigs = ${if cfg.requireSignedBinaryCaches then "true" else "false"}
'' else ''
signed-binary-caches = ${if cfg.requireSignedBinaryCaches then "*" else ""}
''}
require-sigs = ${if cfg.requireSignedBinaryCaches then "true" else "false"}
trusted-users = ${toString cfg.trustedUsers}
allowed-users = ${toString cfg.allowedUsers}
${optionalString (isNix20 && !cfg.distributedBuilds) ''
${optionalString (!cfg.distributedBuilds) ''
builders =
''}
system-features = ${toString cfg.systemFeatures}
@ -422,8 +408,7 @@ in
systemd.services.nix-daemon =
{ path = [ nix pkgs.utillinux config.programs.ssh.package ]
++ optionals cfg.distributedBuilds [ pkgs.gzip ]
++ optionals (!isNix20) [ pkgs.openssl.bin ];
++ optionals cfg.distributedBuilds [ pkgs.gzip ];
environment = cfg.envVars
// { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
@ -440,34 +425,13 @@ in
restartTriggers = [ nixConf ];
};
nix.envVars =
optionalAttrs (!isNix20) {
NIX_CONF_DIR = "/etc/nix";
# Enable the copy-from-other-stores substituter, which allows
# builds to be sped up by copying build results from remote
# Nix stores. To do this, mount the remote file system on a
# subdirectory of /run/nix/remote-stores.
NIX_OTHER_STORES = "/run/nix/remote-stores/*/nix";
}
// optionalAttrs (cfg.distributedBuilds && !isNix20) {
NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl";
};
# Set up the environment variables for running Nix.
environment.sessionVariables = cfg.envVars //
{ NIX_PATH = cfg.nixPath;
};
environment.extraInit = optionalString (!isNix20)
environment.extraInit =
''
# Set up secure multi-user builds: non-root users build through the
# Nix daemon.
if [ "$USER" != root -o ! -w /nix/var/nix/db ]; then
export NIX_REMOTE=daemon
fi
'' + ''
if [ -e "$HOME/.nix-defexpr/channels" ]; then
export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
fi
@ -479,21 +443,15 @@ in
services.xserver.displayManager.hiddenUsers = map ({ name, ... }: name) nixbldUsers;
# FIXME: use systemd-tmpfiles to create Nix directories.
system.activationScripts.nix = stringAfter [ "etc" "users" ]
''
# Nix initialisation.
install -m 0755 -d \
/nix/var/nix/gcroots \
/nix/var/nix/temproots \
/nix/var/nix/userpool \
/nix/var/nix/profiles \
/nix/var/nix/db \
/nix/var/log/nix/drvs
install -m 1777 -d \
/nix/var/nix/gcroots/per-user \
/nix/var/nix/profiles/per-user \
/nix/var/nix/gcroots/tmp
# Create directories in /nix.
${nix}/bin/nix ping-store --no-net
# Subscribe the root user to the NixOS channel by default.
if [ ! -e "/root/.nix-channels" ]; then
echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
fi
'';
nix.systemFeatures = mkDefault (

View File

@ -142,7 +142,7 @@ fi
# Record the boot configuration.
ln -sfn "$systemConfig" /run/booted-system
# Prevent the booted system form being garbage-collected If it weren't
# Prevent the booted system from being garbage-collected. If it weren't
# a gcroot, if we were running a different kernel, switched system,
# and garbage collected all, we could not load kernel modules anymore.
ln -sfn /run/booted-system /nix/var/nix/gcroots/booted-system