Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ check-compiler:
"$$gate_tools/fs-sandbox" \
--dir / \
--ro /usr \
--ro /proc \
--ro /proc/1 \
--ro /proc/sysvipc \
--ro "$$gate_tools" \
--ro "$$gate_tools/toolchain" \
--rw /dev/null \
Expand Down Expand Up @@ -167,7 +168,7 @@ check-compiler:
/usr/bin/env -i LANG=C LC_ALL=C PATH=/usr/bin:/bin /usr/bin/cc -std=c17 -O2 -D_FORTIFY_SOURCE=3 -fPIE -pie -Wall -Wextra -Werror -pedantic -Wl,-z,relro,-z,now "$$cargo_home/check-src/tools/fs_sandbox.c" -o "$$gate_tools/fs-sandbox"; \
[[ -f "$$gate_tools/fs-sandbox" && ! -L "$$gate_tools/fs-sandbox" && -x "$$gate_tools/fs-sandbox" ]] || { printf '%s\n' 'filesystem sandbox build is invalid' >&2; exit 1; }; \
manifest="$$cargo_home/check-src/compiler/Cargo.toml"; \
run_cargo /bin/bash --norc -p -c 'for capability_set in CapInh CapPrm CapEff CapBnd CapAmb; do [[ "$$(/usr/bin/sed -n "s/^$${capability_set}:[[:space:]]*//p" /proc/self/status)" == 0000000000000000 ]] || exit 1; done; for descriptor in /proc/self/fd/*; do [[ ! -e "$$descriptor" || "$${descriptor##*/}" =~ ^[012]$$ ]] || exit 1; done; standard_output="$$(/usr/bin/readlink -- /proc/$$$$/fd/1)"; [[ "$$(/usr/bin/readlink -- /proc/$$$$/fd/0)" == /dev/null && "$$standard_output" =~ ^pipe:\[[0-9]+\]$$ && "$$(/usr/bin/readlink -- /proc/$$$$/fd/2)" == "$$standard_output" ]] || exit 1; for descriptor in 0 1 2; do descriptor_flags="$$(/usr/bin/sed -n "s/^flags:[[:space:]]*//p" "/proc/$$$$/fdinfo/$$descriptor")"; expected_access="$$((descriptor == 0 ? 0 : 1))"; [[ "$$((8#$$descriptor_flags & 3))" == "$$expected_access" ]] || exit 1; done; for ipc_table in msg sem shm; do [[ -z "$$(/usr/bin/sed -n "2p" "/proc/sysvipc/$$ipc_table")" ]] || exit 1; done; ! /usr/bin/head -c 1 -- "$$3/Makefile" >/dev/null 2>&1 || exit 1; ! /usr/bin/head -c 1 -- /etc/passwd >/dev/null 2>&1 || exit 1; ! /usr/bin/head -c 1 -- /sys/devices/system/cpu/online >/dev/null 2>&1 || exit 1; [[ $$$$ == 1 && $$PPID == 0 && "$$(/usr/bin/id -u)" == "$$1" && "$$(/usr/bin/id -g)" == "$$2" && "$$(/usr/bin/hostname)" == orange-gate && "$$(/usr/bin/readlink -- /proc/self/ns/ipc)" != "$$6" && "$$(/usr/bin/readlink -- /proc/self/ns/uts)" != "$$7" && "$$HOME" == "$$4" && "$$PATH" == "$$5/toolchain/bin:/usr/bin:/bin" && "$$(/usr/bin/sed -n "s/^NoNewPrivs:[[:space:]]*//p" /proc/self/status)" == 1 && -z "$$(/usr/bin/sed -n "2p" /proc/net/route)" ]]' gate-isolation "$$gate_uid" "$$gate_gid" "$$repository_root" "$$cargo_home/home" "$$gate_tools" "$$gate_ipc_namespace" "$$gate_uts_namespace"; \
run_cargo /bin/bash --norc -p -c 'gate_process_root=/proc/1; for capability_set in CapInh CapPrm CapEff CapBnd CapAmb; do [[ "$$(/usr/bin/sed -n "s/^$${capability_set}:[[:space:]]*//p" "$$gate_process_root/status")" == 0000000000000000 ]] || exit 1; done; for descriptor in "$$gate_process_root"/fd/*; do [[ ! -e "$$descriptor" || "$${descriptor##*/}" =~ ^[012]$$ ]] || exit 1; done; standard_output="$$(/usr/bin/readlink -- "$$gate_process_root/fd/1")"; [[ "$$(/usr/bin/readlink -- "$$gate_process_root/fd/0")" == /dev/null && "$$standard_output" =~ ^pipe:\[[0-9]+\]$$ && "$$(/usr/bin/readlink -- "$$gate_process_root/fd/2")" == "$$standard_output" ]] || exit 1; for descriptor in 0 1 2; do descriptor_flags="$$(/usr/bin/sed -n "s/^flags:[[:space:]]*//p" "$$gate_process_root/fdinfo/$$descriptor")"; expected_access="$$((descriptor == 0 ? 0 : 1))"; [[ "$$((8#$$descriptor_flags & 3))" == "$$expected_access" ]] || exit 1; done; for ipc_table in msg sem shm; do [[ -z "$$(/usr/bin/sed -n "2p" "/proc/sysvipc/$$ipc_table")" ]] || exit 1; done; for hidden_proc_path in /proc/cpuinfo /proc/meminfo /proc/self/status /proc/version; do ! /usr/bin/head -c 1 -- "$$hidden_proc_path" >/dev/null 2>&1 || exit 1; done; ! /usr/bin/head -c 1 -- "$$3/Makefile" >/dev/null 2>&1 || exit 1; ! /usr/bin/head -c 1 -- /etc/passwd >/dev/null 2>&1 || exit 1; ! /usr/bin/head -c 1 -- /sys/devices/system/cpu/online >/dev/null 2>&1 || exit 1; [[ $$$$ == 1 && $$PPID == 0 && "$$(/usr/bin/id -u)" == "$$1" && "$$(/usr/bin/id -g)" == "$$2" && "$$(/usr/bin/hostname)" == orange-gate && "$$(/usr/bin/readlink -- "$$gate_process_root/ns/ipc")" != "$$6" && "$$(/usr/bin/readlink -- "$$gate_process_root/ns/uts")" != "$$7" && "$$HOME" == "$$4" && "$$PATH" == "$$5/toolchain/bin:/usr/bin:/bin" && "$$(/usr/bin/sed -n "s/^NoNewPrivs:[[:space:]]*//p" "$$gate_process_root/status")" == 1 && -z "$$(/usr/bin/sed -n "2p" "$$gate_process_root/net/route")" ]]' gate-isolation "$$gate_uid" "$$gate_gid" "$$repository_root" "$$cargo_home/home" "$$gate_tools" "$$gate_ipc_namespace" "$$gate_uts_namespace"; \
run_cargo /usr/bin/env PYTHONHASHSEED=0 /usr/bin/python3 -S -P -B -X utf8 -W error::ResourceWarning "$$cargo_home/check-src/tools/validate_foundation.py"; \
run_cargo /usr/bin/env PYTHONHASHSEED=0 PYTHONPYCACHEPREFIX="$$cargo_home/snapshot-python-cache" /usr/bin/python3 -S -P -B -X utf8 -W error::ResourceWarning -c 'import sys, unittest; sys.path.insert(0, sys.argv.pop(1)); unittest.main(module=None)' "$$cargo_home/check-src" discover -s "$$cargo_home/check-src/tools/tests" -p 'test_*.py'; \
run_cargo /usr/bin/env PYTHONHASHSEED=0 /usr/bin/python3 -S -P -B -X utf8 -W error::ResourceWarning "$$cargo_home/check-src/tools/validate_foundation.py"; \
Expand Down
8 changes: 5 additions & 3 deletions compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ Before the drop, the namespace supervisor bind-mounts the selected toolchain
read-only and covers `/home` with a private non-executable `tmpfs`. A protected C
launcher built from the captured tree requires Landlock ABI 3 or newer, permits
directory-name traversal but grants file reads and execution only to `/usr`, the
private `/proc`, the gate tool roots, and the selected toolchain, and grants
gate launcher's private `/proc/1`, the private `/proc/sysvipc` tables, the gate
tool roots, and the selected toolchain, and grants
writes only to the two gate roots and four admitted character devices. Host
account/configuration files under `/etc` and kernel/device state under `/sys`
remain unreadable, with representative runtime assertions. The launcher also
Expand Down Expand Up @@ -115,8 +116,9 @@ trusted outer `/usr/bin/cat` relays that merged stream to the caller's final
output sink. The caller can still close or truncate that final sink, and the two
copied output channels are intentionally indistinguishable. The system C
compiler, launcher source, relay, kernel, mount implementation, and allowlisted
system roots remain trusted boundaries. Private `/proc` still exposes kernel,
CPU, and process metadata. Resource ceilings are not aggregate
system roots remain trusted boundaries. The gate launcher's PID-1 metadata and
private System V IPC tables remain readable; representative global kernel/CPU
and dynamic `/proc/self` content is asserted unreadable. Resource ceilings are not aggregate
cgroup budgets: virtual address space and CPU time are limited per process,
file size is limited per file, aggregate resident memory is not capped, and the
process ceiling includes other processes with the same real user ID.
Expand Down
2 changes: 1 addition & 1 deletion docs/operations/CI_DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ recorded identities and digests.

| Result | What is currently fixed | What the result actually establishes | Why it is not reproducible evidence yet |
| --- | --- | --- | --- |
| `scripts/ci/check-repository` | Repository bytes, Cargo lock, selected Rust version, allowlisted Python and Cargo environments, fresh bytecode/build cache roots, disabled system Git configuration, global Git configuration fixed to `/dev/null`, private mount, PID, `/proc`, network, IPC, and UTS namespaces with asserted distinct identities, a fixed gate hostname, a read-only selected-toolchain bind, hidden `/home`, a protected Landlock allowlist that omits `/etc` and `/sys`, default ordinary catchable signal dispositions, an empty ordinary signal mask, read-only null standard input, a merged write-only copied-command output pipe with a trusted outer relay, and hard copied-command ceilings of 4 GiB of virtual address space and 600 CPU seconds per process, 512 MiB per file, 1,024 open files, 256 real-user processes, and zero core bytes; the gate uses an unprivileged user namespace where available or a privilege-dropping namespace supervisor otherwise, removes all five capability sets, closes nonstandard descriptors, and runs Cargo locked/offline | Rust formatting, lint, docs, debug and optimized unit/CLI tests, repository invariants, and synthetic/adversarial fixture expectations pass under the executing toolchain and OS without copied-code file contents outside admitted roots, host account/configuration file contents, sysfs kernel/device contents, caller-selected system/global Git configuration, trusted-parent process visibility, inherited host System V IPC objects, the host hostname, inherited blocked `SIGTERM` or ignored `SIGPIPE`, inherited nonstandard descriptors, caller-supplied standard-input bytes, direct access to caller output descriptors, unbounded single-process address-space reservation, unbounded single-process CPU time, unbounded single-file growth, Linux capabilities, privilege-reacquisition permission, or a new external network path | Rust archives, C compiler, Python, shell, Make, kernel, Landlock, namespace and privilege-drop implementations, filesystem, output relay, and host tools are not content-fixed; directory names, private-`/proc` kernel/CPU/process metadata, and unmediated metadata operations remain visible, libc-reserved signal state remains platform-dependent, copied commands can alter their own signal state after execution, the caller controls and can close or truncate the relay's final output sink, resource ceilings are not aggregate cgroup budgets and do not cap aggregate resident memory, and no signed execution manifest or independently replayable environment is emitted |
| `scripts/ci/check-repository` | Repository bytes, Cargo lock, selected Rust version, allowlisted Python and Cargo environments, fresh bytecode/build cache roots, disabled system Git configuration, global Git configuration fixed to `/dev/null`, private mount, PID, `/proc`, network, IPC, and UTS namespaces with asserted distinct identities, a fixed gate hostname, a read-only selected-toolchain bind, hidden `/home`, a protected Landlock allowlist that admits only `/proc/1` and `/proc/sysvipc` from private procfs and omits `/etc` and `/sys`, default ordinary catchable signal dispositions, an empty ordinary signal mask, read-only null standard input, a merged write-only copied-command output pipe with a trusted outer relay, and hard copied-command ceilings of 4 GiB of virtual address space and 600 CPU seconds per process, 512 MiB per file, 1,024 open files, 256 real-user processes, and zero core bytes; the gate uses an unprivileged user namespace where available or a privilege-dropping namespace supervisor otherwise, removes all five capability sets, closes nonstandard descriptors, and runs Cargo locked/offline | Rust formatting, lint, docs, debug and optimized unit/CLI tests, repository invariants, and synthetic/adversarial fixture expectations pass under the executing toolchain and OS without copied-code file contents outside admitted roots, host account/configuration file contents, sysfs kernel/device contents, global procfs kernel/CPU or dynamic self-process content, caller-selected system/global Git configuration, trusted-parent process visibility, inherited host System V IPC objects, the host hostname, inherited blocked `SIGTERM` or ignored `SIGPIPE`, inherited nonstandard descriptors, caller-supplied standard-input bytes, direct access to caller output descriptors, unbounded single-process address-space reservation, unbounded single-process CPU time, unbounded single-file growth, Linux capabilities, privilege-reacquisition permission, or a new external network path | Rust archives, C compiler, Python, shell, Make, kernel, Landlock, namespace and privilege-drop implementations, filesystem, output relay, and host tools are not content-fixed; directory names, gate-launcher PID-1 metadata, private System V IPC tables, and unmediated metadata operations remain visible, libc-reserved signal state remains platform-dependent, copied commands can alter their own signal state after execution, the caller controls and can close or truncate the relay's final output sink, resource ceilings are not aggregate cgroup budgets and do not cap aggregate resident memory, and no signed execution manifest or independently replayable environment is emitted |
| Required hosted CI | Repository revision, direct Action SHAs, actionlint archive digest, and zizmor image digest | The configured repository, Markdown, workflow, and workflow-security methods passed in one hosted run | Runner image, Node, Git, Docker host, Action bundles, and service behavior are not fully archived or fixed |
| Dependency Review | Event base/head identities and the selected Action revision | GitHub reported no configured dependency-policy violation for its then-current dependency data | Dependency graph/API state and service implementation are external, time-indexed inputs |
| External Links | lychee archive digest, link-check flags, and repository locators | The non-excluded endpoints produced accepted responses during the run | Remote content, DNS, TLS, routing, rate limits, and server policy change independently of repository bytes |
Expand Down
Loading