Skip to content

Add peer-scoped Linux read response mailbox - #725

Open
enaboapps wants to merge 3 commits into
linux-supportfrom
feat/linux-read-responses
Open

enaboapps wants to merge 3 commits into
linux-supportfrom
feat/linux-read-responses

Conversation

@enaboapps

Copy link
Copy Markdown
Contributor

Closes #724. Depends on #723. BlueZ 5.72 broadcasts AcquireNotify data; this defines a negotiated read-v1 transport with a peer-owned bounded mailbox instead. Preserves v1 framing and authentication, rejects competing reads and stale generations, supports ATT long-read offsets. Runtime integration follows.

Validation: frontend lint, 114+5 tests and build passed; Rust fmt passed; actual mailbox and worker source passed 8 tests and strict Clippy in an isolated harness. Full native local checks remain blocked by missing GTK/GLib development libraries. CI and independent latest-head review pending. No Bluetooth or input activated.

@greptile-apps

greptile-apps Bot commented Sep 11, 2026

Copy link
Copy Markdown

Greptile Summary

Summary

A credential request can continue after invalidation if invalidation occurs immediately after the request reserves the worker slot. This must be fixed before merging because a stale credential load, save, or delete can complete and report success.

Confidence Score: 4/5

Not safe to merge until credential invalidation reliably cancels requests admitted before it.

A deterministic concurrent execution reproduced a request completing successfully after invalidation.

Files Needing Attention: src-tauri/src/linux_credential_worker.rs needs an atomic boundary around worker admission and generation capture.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding and linked it to the corresponding review comment.
  • T-Rex produced a second finding-proof for a different posted P1 finding.
  • T-Rex produced a general-contract-validation-proof that documents the pre-capture and post-capture states and identifies the changed code paths.
  • T-Rex prepared artifacts that support the contract validation, including pre- and post-capture logs and a Rust code snippet.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 Request can evade an invalidation issued immediately after admission

    • Bug
      • request() obtains the busy admission at lines 167-174, then separately loads state.generation at line 175. A concurrent invalidate() at lines 152-154 can increment the generation in that interval. The request then records the incremented value, so both the worker's generation equality check and the caller's post-reply equality check succeed; the operation proceeds and its successful reply is accepted despite the invalidation.
    • Cause
      • The admission CAS and generation snapshot are separate atomic operations with no synchronization that makes them one logical admission epoch. invalidate() independently increments the generation between them.
    • Fix
      • Capture/validate the generation as part of an admission protocol that cannot be interleaved with invalidation—for example, protect admission and generation snapshot with a shared mutex, or use a combined atomic state/CAS that atomically acquires busy and records the pre-invalidation generation.

    T-Rex Ran code and verified through T-Rex

Prompt To Fix All With AI
### Issue 1
src-tauri/src/linux_credential_worker.rs:175
**Make invalidation admission atomic**

The request reserves the worker slot at lines 167–174 but does not read the generation until this line. If `invalidate()` runs in between, this request captures the new generation, so the worker and caller checks both treat it as current. A credential load, save, or delete that should have been cancelled can therefore run and return success after invalidation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "Add peer-scoped Linux read response mail..." | Re-trigger Greptile

{
return Err(WorkerError::Busy);
}
let generation = self.state.generation.load(Ordering::SeqCst);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Make invalidation admission atomic

The request reserves the worker slot at lines 167–174 but does not read the generation until this line. If invalidate() runs in between, this request captures the new generation, so the worker and caller checks both treat it as current. A credential load, save, or delete that should have been cancelled can therefore run and return success after invalidation.

Artifacts

Command output from the check

  • The compiled harness captured generation before running invalidation and observed cancellation, establishing the comparison case.

Command output from the check

  • The compiled harness ran invalidation after admission but before generation capture and observed worker progress and successful caller completion, confirming the defect.

Evidence from the check

  • This is the complete authored Rust source compiled and run for both scheduling orders, with channels making the interleaving deterministic.

Command output from the check

  • The captured source locations show the worker checks, invalidation increment, admission CAS, generation capture, and caller completion check involved in the result.

Command output from the check

  • The native Cargo test attempt stopped because `gdk-sys` could not find `gdk-3.0.pc`, while the independently compiled focused harness still executed the requested ordering.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: src-tauri/src/linux_credential_worker.rs
Line: 175

Comment:
**Make invalidation admission atomic**

The request reserves the worker slot at lines 167–174 but does not read the generation until this line. If `invalidate()` runs in between, this request captures the new generation, so the worker and caller checks both treat it as current. A credential load, save, or delete that should have been cancelled can therefore run and return success after invalidation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant