···
} // removeAttrs config [ "confinement" "serviceConfig" ];
-
imports = lib.imap1 mkTestStep [
-
{ description = "chroot-only confinement";
-
config.confinement.mode = "chroot-only";
'bin': Accessibility.WRITABLE,
'nix': Accessibility.WRITABLE,
'run': Accessibility.WRITABLE,
-
assert os.getuid() == 0
-
os.chown('/bin', 65534, 0)
-
{ description = "full confinement with APIVFS";
'bin': Accessibility.WRITABLE,
'nix': Accessibility.WRITABLE,
-
'tmp': Accessibility.WRITABLE,
'run': Accessibility.WRITABLE,
'proc': Accessibility.SPECIAL,
'sys': Accessibility.SPECIAL,
'dev': Accessibility.WRITABLE,
-
bin_gid = Path('/bin').stat().st_gid
-
with pytest.raises(OSError) as excinfo:
-
os.chown('/bin', 65534, bin_gid)
-
assert excinfo.value.errno == errno.EINVAL
-
assert os.getuid() == 0
-
{ description = "check existence of bind-mounted /etc";
-
config.serviceConfig.BindReadOnlyPaths = [ "/etc" ];
-
assert Path('/etc/passwd').read_text()
-
{ description = "check if User/Group really runs as non-root";
-
config.serviceConfig.User = "chroot-testuser";
-
config.serviceConfig.Group = "chroot-testgroup";
-
assert list(Path('/dev').iterdir())
-
with pytest.raises(PermissionError):
-
Path('/bin/test').touch()
-
{ description = "check if DynamicUser is working in full-apivfs mode";
-
config.confinement.mode = "full-apivfs";
-
config.serviceConfig.DynamicUser = true;
'bin': Accessibility.READABLE,
'nix': Accessibility.READABLE,
-
'tmp': Accessibility.WRITABLE,
'run': Accessibility.STICKY,
'proc': Accessibility.SPECIAL,
···
'dev/shm': Accessibility.STICKY,
'dev/mqueue': Accessibility.STICKY,
-
'var': Accessibility.READABLE,
-
'var/tmp': Accessibility.WRITABLE,
-
assert os.getuid() != 0
-
assert os.getgid() != 0
-
with pytest.raises(OSError) as excinfo:
-
Path('/bin/test').touch()
-
assert excinfo.value.errno == errno.EROFS
-
with pytest.raises(OSError) as excinfo:
-
Path('/etc/test').touch()
-
assert excinfo.value.errno == errno.EROFS
-
{ description = "check if DynamicUser and PrivateTmp=false are working in full-apivfs mode";
-
config.confinement.mode = "full-apivfs";
-
config.serviceConfig.DynamicUser = true;
-
config.serviceConfig.PrivateTmp = false;
-
'bin': Accessibility.READABLE,
-
'nix': Accessibility.READABLE,
-
'run': Accessibility.STICKY,
-
'proc': Accessibility.SPECIAL,
-
'sys': Accessibility.SPECIAL,
-
'dev': Accessibility.SPECIAL,
-
'dev/shm': Accessibility.STICKY,
-
'dev/mqueue': Accessibility.STICKY,
-
assert os.getuid() != 0
-
assert os.getgid() != 0
-
with pytest.raises(OSError) as excinfo:
-
Path('/bin/test').touch()
-
assert excinfo.value.errno == errno.EROFS
-
with pytest.raises(OSError) as excinfo:
-
Path('/etc/test').touch()
-
assert excinfo.value.errno == errno.EROFS
-
{ description = "check if DynamicUser is working in chroot-only mode";
-
config.confinement.mode = "chroot-only";
-
config.serviceConfig.DynamicUser = true;
-
'bin': Accessibility.READABLE,
-
'nix': Accessibility.READABLE,
-
'run': Accessibility.READABLE,
-
assert os.getuid() != 0
-
assert os.getgid() != 0
-
with pytest.raises(OSError) as excinfo:
-
Path('/bin/test').touch()
-
assert excinfo.value.errno == errno.EROFS
-
{ description = "check if DynamicUser and PrivateTmp=true are working in chroot-only mode";
-
config.confinement.mode = "chroot-only";
-
config.serviceConfig.DynamicUser = true;
-
config.serviceConfig.PrivateTmp = true;
-
'bin': Accessibility.READABLE,
-
'nix': Accessibility.READABLE,
-
'run': Accessibility.READABLE,
-
'tmp': Accessibility.WRITABLE,
-
'var': Accessibility.READABLE,
-
'var/tmp': Accessibility.WRITABLE,
-
assert os.getuid() != 0
-
assert os.getgid() != 0
-
with pytest.raises(OSError) as excinfo:
-
Path('/bin/test').touch()
-
assert excinfo.value.errno == errno.EROFS
···
description = "check if symlinks are properly bind-mounted";
config.confinement.packages = lib.singleton symlink;
assert Path('${symlink}').read_text() == 'got me'
···
assert excinfo.value.errno == errno.ELOOP
config.users.groups.chroot-testgroup = {};
config.users.users.chroot-testuser = {