Prototype FreeBSD build user isolation

This commit is contained in:
2026-04-01 11:43:56 +02:00
parent 7621798ef5
commit d65b2afb27
4 changed files with 724 additions and 0 deletions

View File

@@ -896,3 +896,79 @@ Next recommended step:
2. then establish a `/frx/store`-based store-management prototype covering permissions, package readability, and garbage-collection behavior
3. continue carrying the separate Guix checkout runtime blocker:
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
## 2026-04-01 — Phase 2.2 completed: privilege dropping and concurrent build-user isolation validated
Completed work:
- added a C helper implementing the core daemon-side privilege drop mechanics:
- `tests/daemon/freebsd-build-user-helper.c`
- added a harness that combines that helper with the new jail model and runs two jobs concurrently:
- `tests/daemon/run-freebsd-privilege-drop-prototype.sh`
- wrote the Phase 2.2 report:
- `docs/reports/phase2-freebsd-privilege-drop.md`
- ran the concurrent build-user prototype successfully and captured metadata under:
- `/tmp/freebsd-privdrop-metadata.txt`
Important findings:
- a root-launched FreeBSD helper can successfully perform the expected daemon-side transition:
- `setgroups`
- `setgid`
- `setuid`
into a dedicated build identity
- once dropped, the helper cannot regain root with `setuid(0)`:
- `Operation not permitted`
- each build job can create files in its own writable directory and those files end up owned by the dropped build UID/GID rather than by root
- two concurrent jobs using distinct numeric build identities succeeded with:
- job 1 UID/GID `35001:35001`
- job 2 UID/GID `35002:35002`
- host-side result files were observed with the matching ownership and restrictive permissions:
- `0600`
- the two jobs were deliberately held for two seconds each and the measured wall-clock elapsed time was also about two seconds, demonstrating actual concurrent execution rather than serialized execution
- two complementary denial modes were validated at the same time:
- peer build files mounted but blocked by permissions: `Permission denied`
- host path not mounted into the jail at all: `No such file or directory`
- the dropped build user also could not:
- create files in a protected root-owned directory
- `chown` its own output back to root
Current assessment:
- Phase 2.2 is now satisfied on the current FreeBSD prototype track
- the combined jail + build-user model now has practical validation for the most important security properties required by a future FreeBSD Guix daemon:
- root-controlled setup
- permanent drop to build credentials
- per-build writable areas
- cross-build isolation
- concurrent execution under distinct identities
- the remaining Phase 2 work is now centered on the store itself: permissions, readability, content-addressed layout, and garbage-collection behavior under `/frx/store`
Recent commits:
- `e380e88``Add FreeBSD Guile verification harness`
- `cd721b1``Update progress after Guile verification`
- `27916cb``Diagnose Guile subprocess crash on FreeBSD`
- `02f7a7f``Validate local Guile fix on FreeBSD`
- `4aebea4``Add native GNU Hello FreeBSD build harness`
- `c944cdb``Validate Guix builder phases on FreeBSD`
- `0a2e48e``Validate GNU which builder phases on FreeBSD`
- `245a47d``Document gaps to real Guix FreeBSD builds`
- `d62e9b0``Investigate Guix derivation generation on FreeBSD`
- `c0a85ed``Build local Guile-GnuTLS on FreeBSD`
- `15b9037``Build local Guile-Git on FreeBSD`
- `47d31e8``Build local Guile-JSON on FreeBSD`
- `d82195b``Advance Guix checkout on FreeBSD`
- `9bf3d30``Document FreeBSD syscall mapping`
- `7621798``Prototype FreeBSD jail build isolation`
Next recommended step:
1. complete Phase 2.3 by establishing a `/frx/store`-based store prototype with:
- correct root/daemon write restrictions
- unprivileged read access
- content-addressed path naming
- garbage-collection behavior
2. if possible, use outputs or dependency relationships realistic enough to model how a future FreeBSD Guix daemon would retain referenced store items
3. continue carrying the separate Guix checkout runtime blocker:
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`