nixos/stage2-init: test nosuid and nodev mount options
We can make some evil files in the store within stage1, and verify that they don't work.
This commit is contained in:
parent
55f225049e
commit
1b18ff3669
@ -10,7 +10,24 @@ import ./make-test-python.nix (
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Prints the user's UID. Can't just do a shell script
|
||||
# because setuid is ignored for interpreted programs.
|
||||
uid = pkgs.writeCBin "uid" ''
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
int main(void) {
|
||||
printf("%d\n", geteuid());
|
||||
return 0;
|
||||
}
|
||||
'';
|
||||
in
|
||||
{
|
||||
users.users.alice = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
emptyDiskImages = [ 256 ];
|
||||
|
||||
@ -32,6 +49,10 @@ import ./make-test-python.nix (
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.xxd ];
|
||||
|
||||
system.extraDependencies = [ uid ];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
# Format the upper Nix store.
|
||||
@ -50,6 +71,19 @@ import ./make-test-python.nix (
|
||||
mount -t overlay overlay \
|
||||
-o lowerdir=/mnt-root/nix/store/ro,upperdir=/mnt-root/nix/store/rw,workdir=/mnt-root/nix/store/work \
|
||||
/mnt-root/nix/store
|
||||
|
||||
# Be very rude and try to put suid files and/or devices into the store.
|
||||
evil=/mnt-root/nix/store/evil
|
||||
mkdir -p $evil/bin $evil/dev
|
||||
|
||||
echo "making evil suid..." >&2
|
||||
cp /mnt-root/${builtins.unsafeDiscardStringContext "${uid}"}/bin/uid $evil/bin/suid
|
||||
chmod 4755 $evil/bin/suid
|
||||
[ -u $evil/bin/suid ] || exit 1
|
||||
|
||||
echo "making evil devzero..." >&2
|
||||
mknod -m 666 $evil/dev/zero c 1 5
|
||||
[ -c $evil/dev/zero ] || exit 1
|
||||
'';
|
||||
|
||||
kernelModules = [ "overlay" ];
|
||||
@ -70,6 +104,28 @@ import ./make-test-python.nix (
|
||||
for opt in ["ro", "nosuid", "nodev"]:
|
||||
with subtest(f"testing store mount option: {opt}"):
|
||||
machine.succeed(f'[[ "$(findmnt --direction backward --first-only --noheadings --output OPTIONS /nix/store)" =~ (^|,){opt}(,|$) ]]')
|
||||
|
||||
# should still be suid
|
||||
machine.succeed('[ -u /nix/store/evil/bin/suid ]')
|
||||
# runs as alice and is not root
|
||||
machine.succeed('[ "$(sudo -u alice /nix/store/evil/bin/suid)" == 1000 ]')
|
||||
# can be remounted and runs as root
|
||||
machine.succeed('mount -o remount,suid,bind /nix/store && mount >&2')
|
||||
machine.succeed('[ "$(sudo -u alice /nix/store/evil/bin/suid)" == 0 ]')
|
||||
# double checking we can undo it
|
||||
machine.succeed('mount -o remount,nosuid,bind /nix/store && mount >&2')
|
||||
machine.succeed('[ "$(sudo -u alice /nix/store/evil/bin/suid)" == 1000 ]')
|
||||
|
||||
# should still be a character device
|
||||
machine.succeed('[ -c /nix/store/evil/dev/zero ]')
|
||||
# should not work
|
||||
machine.fail('[ "$(dd if=/nix/store/evil/dev/zero bs=1 count=1 | xxd -pl1)" == 00 ]')
|
||||
# can be remounted and works
|
||||
machine.succeed('mount -o remount,dev,bind /nix/store && mount >&2')
|
||||
machine.succeed('[ "$(dd if=/nix/store/evil/dev/zero bs=1 count=1 | xxd -pl1)" == 00 ]')
|
||||
# double checking we can undo it
|
||||
machine.succeed('mount -o remount,nodev,bind /nix/store && mount >&2')
|
||||
machine.fail('[ "$(dd if=/nix/store/evil/dev/zero bs=1 count=1 | xxd -pl1)" == 00 ]')
|
||||
'';
|
||||
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ numinit ];
|
||||
|
Loading…
x
Reference in New Issue
Block a user