Route all settings-package file reads through confined os.Root

main

Commit

Soph2mo ago

Follow-up to the checkpoints-loader TOCTOU fix: make the rest of the settings package consistent. Promote readConfined to settings.go and route every settings/preferences file read through it — loadFromFile (base settings), loadMergedSettings (local override), LoadProjectRaw, LoadLocalRaw, and loadClonePreferencesFromFile — instead of bare os.ReadFile of an absolute path.

Each read now opens an os.Root anchored at the file's parent directory, so a swapped or symlinked path can't redirect the open outside that directory. The helper wraps its errors, so callers classify "missing" with errors.Is(err, fs.ErrNotExist) rather than os.IsNotExist. This removes the earlier split-brain where a symlinked settings.json worked for Load but was refused only by the checkpoints loader.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com Entire-Checkpoint: 50640125952d

Checkpoints

Checkpoint Backend Registry and Settings-Driven Selection

Claude CodeOpus 4.8[1m]
View session
Checkpoint 1