Limit pidfs support to the Linux 6.9 platform floor

This commit is contained in:
ms2k 2026-07-14 21:29:25 +09:00
commit b34421efa1

View file

@ -196,24 +196,12 @@ independently of process liveness.
#### Host process identity and causal acquisition refinement
Lazaret supports host-process authority only on an exactly source/build-qualified
Linux x86-64 kernel at or above 6.9. Each supported upstream or vendor build
preserves the boot-monotonic 64-bit pidfs inode allocation used by the qualified
build and passes its qualification suite. A release string, version floor,
partial backport, or successful runtime smoke cannot substitute for exact build
qualification. Linux 32-bit, other architectures, kernels below 6.9, and
unqualified vendor builds refuse before a generation or external runtime
resource is created.
On every boot Lazaret runs the finite `PidfsHostSupportProbe` before the first
generation and caches success only under the current boot ID. The probe has the
repository-registered operation sequence and bounds. It checks pidfd operations
and pidfs magic, same-live-process concurrent and last-close/reopen identity,
distinct simultaneous processes, stale-handle non-action, and
exit/reap/drop-all/later-process non-reuse. Any missing operation, failed
observation, cleanup uncertainty, timeout, or unexpected equality refuses
support for that boot. This bounded smoke checks the running path; it does not
prove global inode non-reuse or qualify the kernel source/build.
Lazaret supports host-process authority on Linux x86-64 kernels at or above 6.9.
It checks the platform and kernel-version floor before a generation or external
runtime resource is created. Linux 32-bit, other architectures, and kernels
below 6.9 refuse. Required pidfd and pidfs operations fail closed at their point
of use; Lazaret does not attest, qualify, build, update, or roll back the running
kernel.
`PidfsProcessIdentityV1` separates three kinds of data:
@ -247,8 +235,10 @@ broker performs this sequence:
4. Capture the host-visible child PID, call `pidfd_open` exactly once, and call
`waitid(P_PIDFD, WEXITED | WNOHANG | WNOWAIT)` on that descriptor. `ECHILD`
or any other error refuses; `WNOWAIT` never reaps the child.
5. `fstat` the same pidfd, read the current boot ID and diagnostic start time,
and form `PidfsProcessIdentityV1`.
5. Call `fstatfs` on that exact pidfd and require `f_type == PID_FS_MAGIC`;
any error or wrong magic refuses. Call `fstat` on the same descriptor; any
error refuses. Read the current boot ID and diagnostic start time, and form
`PidfsProcessIdentityV1`.
6. Persist `Staged` ownership. An RS-launched child is sent as the exact
`StagedProcessOwnership` tuple to HC, and RS waits for an authenticated
`ProcessOwnershipCommitAck` that echoes the same Domain, generation,
@ -327,8 +317,11 @@ timing assumptions.
ambiguous mappings refuse before lookup.
4. Call `pidfd_open` exactly once for that locator. `ESRCH` or any other error
cannot authorize process action.
5. `fstat` the resulting pidfd and compare its device and inode exactly with the
durable authority. Either mismatch refuses and closes it without action.
5. Call `fstatfs` on that exact pidfd and require `f_type == PID_FS_MAGIC`;
any error or wrong magic refuses and closes it without action. `fstat` the
same descriptor and compare its device and inode exactly with the durable
authority. Any error or either mismatch likewise refuses and closes it
without action.
6. Apply start-time and expected namespace observations only as negative checks.
7. Use that same matched pidfd for every action. An action-time `ESRCH` or
observation failure refuses without numeric fallback.
@ -341,7 +334,7 @@ allows the ordinary recovery state machine to reconcile the surrounding record.
Boot mismatch fences all old pidfs authority before PID lookup.
The contract accepts two residual assumptions: Linux boot-ID collision is
operationally negligible but not mathematically impossible, and the qualified
operationally negligible but not mathematically impossible, and the Linux 6.9+
boot-monotonic 64-bit pidfs inode counter does not wrap during one boot. Codecs
and comparisons support `u64::MAX` and refuse every unequal authority tuple;
they do not claim to recognize a hypothetical equal tuple after wrap.