1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
with import ./config.nix;
let
setXattrLinux = inodeTgt: name: value: "setfattr -n ${name} -v \"${value}\" ${inodeTgt}";
setExtendedAttribute = if isDarwin then setXattrDarwin else setXattrLinux;
setAndCheckACLLinux = inodeTgt: perm: ''
setfacl -m ${perm} ${inodeTgt}
getfacl -an ${inodeTgt} | grep -i "mask::rw." || { echo no mask in the ACL, setfacl ineffective?; exit 1; }
'';
setAndCheckACL = if isDarwin then setAndCheckACLDarwin else setAndCheckACLLinux;
wellKnownLinuxNames = {
"user.mime_type" = "text/html5";
"user.deriver" = "yue";
# On Linux, inside of the sandbox, you cannot write to these because CAP_SYS_ADMIN is required.
# Those are protected xattrs.
# Root inside the root namespace can set those.
# "trusted.md5sum" = "...";
# "security.selinux" = "...";
};
wellKnownACLs = [
# sets xattr system.posix_acl_access on Linux.
"u:1000:rwX"
];
mapAttrsToList = fn: attrs: map (k: fn k attrs.${k}) (builtins.attrNames attrs);
linuxScenariosForAnInode = withACL: inodeTgt:
builtins.concatStringsSep "\n" (
(mapAttrsToList (name: value: setExtendedAttribute inodeTgt name value) wellKnownLinuxNames)
++ (if withACL then map (setAndCheckACL inodeTgt) wellKnownACLs else [ ])
);
setXattrDarwin = inodeTgt: name: value: "xattr -w ${name} \"${value}\" ${inodeTgt}";
setAndCheckACLDarwin = inodeTgt: perm: ''
chmod +a "${perm}" "${inodeTgt}"
ls -el "${inodeTgt}"
ls -el "${inodeTgt}" | grep -Ei '${perm}'
'';
# NOTE(Qyriad): Darwin ACLs have some kind of sorting order, so ideally we should parse them to check them.
# However: fuck that, for now. So we've just written them in The Order here so the text-match.
wellKnownACLsDarwin = [
"group:everyone allow read,write"
"group:staff allow read,delete,writesecurity,chown"
];
darwinScenariosForAnInode = withACL: inodeTgt:
builtins.concatStringsSep "\n" (
(mapAttrsToList (name: value: setXattrDarwin inodeTgt name value) wellKnownLinuxNames)
++ (if withACL then map (setAndCheckACLDarwin inodeTgt) wellKnownACLsDarwin else [ ])
);
scenariosForAnInode = if isDarwin then darwinScenariosForAnInode else linuxScenariosForAnInode;
in
{
during-build = mkDerivation {
name = "xattrs-during-build";
buildCommand = ''
touch work
${scenariosForAnInode true "./work"}
echo meow > $out
'';
};
in-root-outputs-file = mkDerivation {
name = "xattrs-on-root-output-file";
buildCommand = ''
touch $out
${
# We are not allowed to set ACLs on the root of the output directory.
# There's an explicit suspicious permission check that will cause this build to be rejected.
scenariosForAnInode false "$out"
}
'';
};
in-root-outputs-dir = mkDerivation {
name = "xattrs-on-root-output-dir";
buildCommand = ''
touch $out
${
# We are not allowed to set ACLs on the root of the output directory.
# There's an explicit suspicious permission check that will cause this build to be rejected.
scenariosForAnInode false "$out"
}
'';
};
in-output-content = mkDerivation {
name = "xattrs-under-directory-output";
buildCommand = ''
mkdir -p $out
touch $out/test
mkdir -p $out/test2 $out/test3
touch $out/test3/test4
${scenariosForAnInode true "$out/test"}
${scenariosForAnInode true "$out/test2"}
${scenariosForAnInode true "$out/test3/test4"}
'';
};
}
|