Skip to content

fix(claude): reject non-regular Desktop configuration reads - #7036

Merged
lidge-jun merged 3 commits into
lidge-jun:devfrom
luvs01:codex/upstream-desktop-regular-reads-20261013
Oct 13, 2026
Merged

lidge-jun merged 3 commits into
lidge-jun:devfrom
luvs01:codex/upstream-desktop-regular-reads-20261013

Conversation

@luvs01

@luvs01 luvs01 commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Read Desktop metadata, profiles and library snapshots through checked regular-file descriptors. POSIX opens use nonblocking/no-follow flags; descriptor type, bigint device/inode identity and change time must match the observed file before reading.
  • Preserve UTF-8 decoding and ordinary filesystem errors while refusing directories, links, special files and path replacements. Close descriptors on every read outcome.
  • Retain filtered phase/name/stack diagnostics when an isolated OAuth registration test child exits after its start barrier. No raw child output or exception message is printed, and exit/output assertions stay intact.

Verification

  • Candidate e8afb8bb41786ddd595fd8ab9f36cff46d403dab on current dev e6d7e561f566ab343fbf545a6fa3e1b63012f817. All nine changed files match reviewed source a3137becda4102bfcc2c1cda6cdfe75aedb08a87 byte for byte; the base movement only adds disjoint diagnostic restart isolation files.
  • Exact-source hosted Cross-platform CI run 38351074273 completed successfully on attempt 2. The AUTH-11 Windows shard passed in attempt 1; two other unchanged Windows jobs passed after one failed-job rerun. No additional CI rerun was started during this transfer.
  • Source recorded pinned Bun 1.4.3 OAuth multiprocess coverage: 2 pass, 0 fail, plus a negative control that surfaced filtered failure metadata without the injected message. This is reused source evidence, not a newly executed candidate test.
  • The existing Desktop suites cover directory/link/FIFO inputs and replacements during opening. Source CI supplied that execution coverage; local profile-path attempts had previously encountered configuration-mutation-lock stalls on the unchanged baseline and are not called passes.
  • bun run typecheck, bun run structure:check, bun run privacy:scan, and git diff --check passed on the integration candidate. Privacy scope is the materialized sparse checkout including all changed files.
  • The prior 20-second catalog-sync and 15-second CLI-resolve timeouts, and earlier OAuth child exit failure, have no established underlying cause. The diagnostic change improves observability and does not claim to fix those execution failures. No timeout, workflow or production auth policy was weakened.
  • A full local repository run was not repeated across shared active worktrees. New-head CI and maintainer review remain required; open in Draft. This focused change enforces regular-file identity; separate byte-limit work is not included.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

Read library metadata and profiles through checked regular-file descriptors and preserve open error identity. Retain filtered OAuth child failure diagnostics used during validation.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 13, 2026
@lidge-jun

Copy link
Copy Markdown
Owner

Maintainer integration (dev-only bypass per MAINTAINERS.md), not an independent approval.

Union fix pushed by the maintainer: with #7007 on dev, this PR pushed structure/clients/claude-desktop.md to 609 lines, over the 600-line structure budget. Each side passed alone, but the combination failed structure:check. Current dev was merged in with no force-push, and the verified-read contract moved unchanged into the new structure/clients/claude-desktop-config-reads.md (manifest entry, regenerated INDEX.md, one-line pointer). The original doc is now 599 lines.

Exact head 61adac5287efa4390898022a3a8acb9a6115d8c7: hosted Cross-platform CI passed all required jobs (Linux 4/4, Windows 9/9, gates, aggregate ci); path-filtered jobs skipped. Independent exact-head review (gpt-6.1-sol, read-only): MERGE-OK, no findings, including descriptor/error-path probes. The combined tree with #7038/#7039 on dev passed typecheck, structure, privacy, the file-size ratchet, layout and the core/Lab boundary. No outstanding review threads or change requests. The OAuth multiprocess diagnostic change is test-only and keeps the exit/output assertions.

@lidge-jun
lidge-jun marked this pull request as ready for review October 13, 2026 14:58
@lidge-jun
lidge-jun merged commit 0e2a86d into lidge-jun:dev Oct 13, 2026
43 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-13T15:09:16.810680Z 61adac5 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 61adac5287

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3 to +7
Every read of Desktop library configuration — selected-profile inspection, `_meta.json` parsing,
foreign-key preservation during writes, refresh mode re-resolution, the refresh fingerprint hash,
the picker profile's inspection and apply snapshots, and the connection-owned store's metadata and
profile reads — goes through the shared verified regular-file reader in
`src/claude/desktop-3p-library.ts` (`readDesktopLibraryBytes`/`readDesktopLibraryText`). The path

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include backup copies in the verified-read path

During a normal (non-refresh) rewrite of an existing profile, this “every read” claim is false: after readDesktopProfileForeignKeys(configPath) returns, atomicReplaceDesktopConfig reopens the same path via copyFileSync(path, backupPath), and the rollback similarly path-copies the backup. If another process renames a FIFO onto the profile in that gap, the unchecked synchronous source open blocks indefinitely rather than producing desktop_config_not_regular; retain the bytes from the verified descriptor for backup/rollback (or use the same checked open for those reads) before documenting the invariant.

AGENTS.md reference: structure/AGENTS.md:L9-L10

Useful? React with 👍 / 👎.

export function parseMetadata(path: string): Desktop3pMetadata {
if (!existsSync(path)) return { entries: [] };
const parsed = JSON.parse(readFileSync(path, "utf8")) as Partial<Desktop3pMetadata>;
const parsed = JSON.parse(readDesktopLibraryText(path)) as Partial<Desktop3pMetadata>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject dangling metadata links before treating them as absent

When _meta.json is a dangling symlink (for example, after a linked configuration target is moved), existsSync on the preceding line follows the missing target and returns false, so this checked read is skipped and parseMetadata returns an empty library. A normal apply then writes a newly allocated profile and fails only when atomicWriteFile reaches the dangling metadata link; because there was no backup, that new profile is left orphaned (and each retry can add another) instead of refusing before mutation. Use lstat/ENOENT handling for optional paths so an existing non-regular directory entry reaches desktop_config_not_regular.

Useful? React with 👍 / 👎.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants