Skip to content

fix(gateway): persist pairing tokens with atomic replace - #71

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/high-severity-issues-af8c
Draft

fix(gateway): persist pairing tokens with atomic replace#71
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/high-severity-issues-af8c

Conversation

@cursor

@cursor cursor Bot commented Aug 22, 2026

Copy link
Copy Markdown

Bug and impact

auth_pair opened auth_tokens.json with O_TRUNC and ignored fprintf/fclose errors. A disk-full write, crash after truncate, or fdopen failure after open() emptied (or partially wrote) the token store and still returned success with a bearer token that never landed on disk.

Concrete trigger: pairing is in progress, tokens already exist on disk (second device in the append window, or a prior successful pair), then the write hits ENOSPC/EFBIG. Existing devices stop authenticating. If the leftover file is non-empty invalid JSON, auth_get_or_create_pairing_code will not issue a new code, so the gateway stays locked until the file is deleted by hand.

Root cause

In-place truncate-then-write with unchecked stdio, plus clearing the pairing code after a write that may have failed.

Fix

Write JSON to auth_tokens.json.tmp, fsync, then rename over the live file (same pattern as dashboard config save). Check generate_random_hex. Keep the pending pairing code until the store commit succeeds so a failed pair can be retried.

Validation

CI=true make test_auth (includes -Werror). New regression test_auth_pair_write_failure_preserves_existing_tokens uses RLIMIT_FSIZE to fail the write, asserts the existing token still validates, then retries successfully after the limit is restored.

Open in WebView Automation

auth_pair truncated auth_tokens.json in place and ignored write errors,
so ENOSPC, a crash after O_TRUNC, or fdopen failure could wipe every
device token and still return success with a token that never landed
on disk.

Write to a sibling temp file, fsync, then rename. Keep the pairing
code until the store is committed so a failed pair can be retried.

Co-authored-by: esadrianno <[email protected]>
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