fix: brain_tunnel, brain_update and session_log confine caller-supplied paths (#169) (#170)
CI / Lint / Test / Vet (push) Successful in 1m2s
CI / Mirror to GitHub (push) Successful in 4s

brain_tunnel accepts only clean wiki/.../*.md paths and reads/rewrites both notes through brainfs; new brainfs.WriteRegular never creates, never writes through a final symlink (Lstat + O_NOFOLLOW|O_NONBLOCK + os.SameFile on the handle, since os.Root follows in-root final symlinks even with O_NOFOLLOW). brain_update resolves like brain_edit (knowledge/ and wiki/ notes only) and reads/rewrites through brainfs. session_log requires a plain-name session id and opens with O_NOFOLLOW|O_NONBLOCK.

Fixes #169. Adversarial review: BLOCKED, BLOCKED, PASS (round 3 by the estate session's reviewer). Follow-ups: #173, #174.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mathias <mthbqv@gmail.com>
This commit was merged in pull request #170.
This commit is contained in:
2026-10-05 18:47:07 +00:00
committed by mathias
co-authored by Claude Opus 5.5
parent bdc1e51a1a
commit febab3e45d
8 changed files with 526 additions and 27 deletions
+38
View File
@@ -249,3 +249,41 @@ func (b *Brain) WalkRegular(relDir string, fn func(rel string) error, onErr func
return fn(p)
})
}
// WriteRegular replaces the contents of an existing regular file at a
// brain-relative path. It never creates a file and never writes through a
// final symlink: os.Root.OpenFile follows an in-root final symlink even with
// O_NOFOLLOW (verified on go1.27), so the path is Lstat-ed through the root
// first and the opened handle must be that same file (os.SameFile), which
// also catches a swap between the two. O_NONBLOCK keeps a FIFO from blocking
// the open. Intermediate in-brain symlinks are still followed (os.Root keeps
// the write inside the brain; hyperguild#167).
func (b *Brain) WriteRegular(rel string, data []byte) error {
rel = filepath.ToSlash(rel)
lfi, err := b.root.Lstat(rel)
if err != nil {
return err
}
if !lfi.Mode().IsRegular() {
return fmt.Errorf("%s: %w", rel, ErrNotRegular)
}
f, err := b.root.OpenFile(rel, os.O_WRONLY|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0)
if err != nil {
return err
}
defer func() { _ = f.Close() }()
fi, err := f.Stat()
if err != nil {
return err
}
if !fi.Mode().IsRegular() || !os.SameFile(lfi, fi) {
return fmt.Errorf("%s: changed while opening: %w", rel, ErrNotRegular)
}
if err := f.Truncate(0); err != nil {
return err
}
if _, err := f.Write(data); err != nil {
return err
}
return f.Close()
}