Skip to content

Keep Linux daemon identity stable across clock changes - #67

Merged
wesm merged 6 commits into
mainfrom
fix/linux-process-identity
Aug 12, 2026
Merged

Keep Linux daemon identity stable across clock changes#67
wesm merged 6 commits into
mainfrom
fix/linux-process-identity

Conversation

@wesm

@wesm wesm commented Aug 12, 2026

Copy link
Copy Markdown
Member
  • Prevents Linux wall-clock corrections from making a live daemon look like a different process, which could remove its runtime record while its lifetime owner lock remains held.
  • Defines the first Linux identity encoding from kernel boot identity, the target process's PID namespace inode, and monotonic start ticks. It remains available under hidepid and ProtectProc when the daemon can inspect itself but not PID 1, while distinguishing PID reuse and namespace restarts.
  • Stores the new Linux identity in the versioned runtime-record field and leaves the legacy wall-clock field empty, so clients built from current main treat records they cannot understand as unknown rather than destructive mismatches.
  • Validates the complete emitted identity format on every platform. Malformed, foreign, and unsupported versioned values fail closed; non-Linux behavior otherwise keeps its existing creation-time identity.

Process creation time derived from the wall clock is not a stable PID-reuse boundary on Linux. WSL can correct its clock while a daemon remains alive, causing clients to classify the same owner as a replacement and delete its runtime record while its lifetime lock remains held.

Use boot identity, PID 1 start ticks, and process start ticks for Linux. Store the new value in a versioned field while leaving the legacy field empty, so older clients fail closed instead of deleting records they cannot understand; legacy Linux timestamps also remain non-authoritative after upgrade.

Validation: the full Windows suite, vet, and build pass; the Linux daemon suite passes under the race detector.

Generated with Codex
Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (7dbc465)

Review verdict: One medium-severity reliability issue should be addressed.

Medium

  • daemon/process_identity_linux.go:42 — Every identity now depends on reading /proc/1/stat. Under hidepid or ProtectProc, an unprivileged daemon may inspect itself and same-user processes but not PID 1, causing ReadProcessIdentity to return false and NewRuntimeRecord to silently omit process identity. Derive the namespace component from an inspectable target-specific source such as /proc/<pid>/ns/pid, combined with the boot ID and target start ticks.

Reviewers: 2 done | Synthesis: codex, 10s | Total: 5m32s

Daemon identity must remain available under hidepid and ProtectProc, where the daemon can inspect itself but not PID 1. Bind identity to the target process namespace, boot, and start ticks so PID reuse and namespace restarts remain distinguishable without privileged proc access.\n\nVersion the encoding so earlier Linux identities fail closed rather than authorizing cleanup across schemes.

Generated with Codex\nCo-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (3418aee)

Potentially unsafe malformed process identities are not rejected fail-closed.

Medium

  • daemon/process_identity_linux.go:23 — Compatibility checks only the linux-v2: prefix, so malformed or truncated identities are classified as ProcessIdentityMismatch instead of ProcessIdentityUnknown. Callers could interpret a mismatch as authorization for destructive replacement, violating the fail-closed identity contract. Validate the complete versioned encoding—including boot ID, namespace inode, and start ticks—before comparison, and return unknown for malformed values. Update the mismatch test to use a structurally valid identity with a changed component.

Reviewers: 2 done | Synthesis: codex, 15s | Total: 5m15s

A version prefix alone cannot establish that a stored identity is safe to compare. A truncated or corrupt value must remain non-authoritative so callers never interpret it as permission to replace a live process or delete its record.

Require the complete Linux identity grammar before comparison. Valid identities can still report a mismatch when one authoritative component changes.

Generated with Codex
Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (fe577d9)

Medium-severity issue found: non-Linux identity validation may fail open during mixed-version operation.

Medium

  • daemon/process_identity_other.go:28 — Non-Linux platforms accept every identity encoding as compatible. Because CompareRuntimeProcessIdentity prioritizes ProcessIdentityV2, an unsupported future or foreign version is compared with the local decimal identity and reported as ProcessIdentityMismatch instead of ProcessIdentityUnknown, potentially authorizing destructive action. Validate identities as the currently emitted positive-decimal format and return unknown for unsupported ProcessIdentityV2 schemes.

Reviewers: 2 done | Synthesis: codex, 23s | Total: 7m13s

Versioned runtime identity takes precedence over the legacy field, so accepting arbitrary encodings can turn an unsupported or corrupt value into destructive mismatch authority. Every platform must first prove that an identity has the exact format it currently emits.

Treat this PR's namespace-based Linux identity as its first public encoding rather than carrying compatibility for an intermediate branch-only representation.

Generated with Codex
Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (6b8b8e3)

One medium-severity issue remains in Linux process identity validation.

Medium

  • daemon/process_identity_linux.go:36 — Validation accepts noncanonical identities, including numeric fields with leading zeros or + signs and uppercase boot-ID hex. Because these encodings cannot match the canonical live identity, malformed input yields ProcessIdentityMismatch instead of failing closed as ProcessIdentityUnknown, potentially allowing destructive replacement or cleanup. Require numeric fields to exactly equal strconv.FormatUint(value, 10), require the boot ID’s canonical lowercase form, and add tests for alternate encodings.

Reviewers: 2 done | Synthesis: codex, 20s | Total: 3m7s

Parseable alternate encodings can never equal the canonical live identity, so treating them as mismatches would grant destructive authority to malformed runtime records. Require the exact lowercase boot ID and positive decimal forms emitted by Kit before comparison.

Validation: cross-compiled the Linux daemon tests and executed them inside WSL.

Generated with Codex

Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (3068aca)

One medium-severity issue found in process identity validation.

Medium

  • daemon/process_identity_other.go:30 — Validation accepts unsigned values above math.MaxInt64, even though ReadProcessIdentity can only emit positive int64 values. An impossible identity such as 9223372036854775808 therefore yields ProcessIdentityMismatch instead of failing closed as ProcessIdentityUnknown.
    • Fix: Parse and canonicalize using strconv.ParseInt/strconv.FormatInt, and add a non-Linux test covering out-of-range values.

Reviewers: 2 done | Synthesis: codex, 10s | Total: 3m44s

Non-Linux process identity is emitted from a positive int64 creation time. Accepting the wider unsigned range lets impossible stored values become authoritative mismatches, which callers may interpret as permission for destructive replacement instead of failing closed.

Generated with Codex
Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

roborev: Combined Review (ce57250)

No issues found.


Reviewers: 2 done | Synthesis: codex | Total: 5m52s

@wesm
wesm merged commit aaaba85 into main Aug 12, 2026
11 checks passed
@wesm
wesm deleted the fix/linux-process-identity branch August 12, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant