.be anchors — store-root redirect, TOML injection
dog/HOME.c's cwd-walk discovery is the git CVE-2022-24765 class: it probes every ancestor for .be and adopts the first hit with ZERO trust validation. For a secondary-worktree anchor (a .be regular file), home_anchor_resolve (HOME.c:637-682) takes row-0's URI path VERBATIM and makes it h->root — the store root — with no ownership check, no symlink rejection (FILEStat follows symlinks; FILELStat exists and is unused), and no containment/absolute-path requirement. Running any dog inside a hostile cloned/untarred directory then routes rw opens (home_ensure_markers, DOGPupCreate) to an attacker-chosen path. Separately home_bootstrap_config (HOME.c:110-125) writes git config user.name/email into .be/config as name = "<value>" with NO escaping, so a value containing " or \n injects arbitrary TOML (e.g. forging the HOMEHost ref-authority). Method: Issues.
home_walk_up (HOME.c:922-983) →
home_anchor_resolve (:637-682) → DOGRepoFromBe sets h->root from row-0 (home_peek_repo_uri :562-587); nothing bounds it to the worktree.
FILEStat (HOME.c:650, :997 home_is_exe) resolves
symlinks; a planted .be symlink or a symlinked sibling exe is followed, then the caller execvps it (TOCTOU between stat and exec).
getenv("PATH") scan (HOME.c:1056) picks the sibling binary to exec — anattacker-controlled PATH chooses the code that runs.
HOME.c:110-125, value slice {name_start,name[0]} fed raw;
also silent truncation (256-byte emailbuf, FILEEnsureSoft fills what fits).
DOGPupThinTail (DOG.c:714-733) unlinks a recomposed path decoupled from
the mmap it released — check/unlink race in a shared .be dir.
.. NOT rejected in project/branch segments: PATHu8sVerifySegment rejects
//NUL/CR/LF/TAB but not ./..; DOGProjectFromBe (DOG.h:227-251) rejects only .be; DPATHBranchNormFeed (DPATH.h:57-78) never rejects ... A row-0 path or ref containing .. composes <root>/.be/.. (= <root>) so shard mkdir -p/refs reads+writes ESCAPE the .be store. (DPATH already ships the correct rejecter DPATHu8sDrainSeg/DPATHVerify — applied to git tree names, not to these segments; reuse it here.)
FILECreate (abc/FILE.c) opens O_CREAT|O_RDWR|O_TRUNC with NO O_NOFOLLOW
(and no O_EXCL on the pup tmp): callers HOME.c:128 (.be/config), :154 (wtlog), DOG.c:674 (pup tmp). A planted symlink at <repo>/.be/config or the <seqno>.<ext>.tmp redirects create+truncate to an arbitrary victim-writable file — classic repo-dir symlink TOCTOU.
home_be_subdirs returns fail(OK) on the subdirs>1 break BEFORE setting
*out_count (HOME.c:786-796), so it stays 0; home_dir_shieldlike (:963) then misclassifies a populated MULTI-project store as shieldlike and adopts the wrong anchor instead of walking past it.
geteuid vs FILELStat owner) and
reject symlinked .be; make row-0 store roots resolve inside the discovered worktree (absolute + realpath containment) or fail.
", \, and control bytes in config values beforeemitting TOML; never silently truncate a value.
../. in project + branch segments (reuse DPATHVerify) so no
composed store path escapes .be; re-normalize before filesystem use.
O_NOFOLLOW on .be/config/wtlog creates and O_EXCL on the pup tmp.home_be_subdirs to set *out_count before the multi-shard break.dog/ libdog, ABC style; keep the ordinary single-user primary-worktree flow
(own .be/) working unchanged — the guard only bites foreign/planted anchors.
so that half is robustness-grade; the anchor adoption is the real remote vector (hostile repo on disk), rate it HIGH.
safe.directory intent: an anchor is trusted only if owned bythe invoking uid (or explicitly allow-listed); no ambient adoption.
.be file whose row-0 points the
store root outside the tree; assert be refuses instead of writing there.
FILELStat symlink checks on the discovered anchor...//relative/outside;
reject ../. project+branch segments (reuse DPATHVerify).
home_bootstrap_config; reject NUL/newline;
O_NOFOLLOW/O_EXCL on the marker + pup creates.
home_be_subdirs *out_count on the multi-shard break.DOGParseURI/DOGRepoFromBe/home_peek_repo_uri (attacker URIs).DOGRepoFromBe/DOGParseURI (DOG.h:186-280, DOG.c:238-284)is bounds-safe today but fragile; cleanup tracked under PTR-002.
79612854 — raw TOML value feed HOME.c:108-125, no FILELStat/geteuid/O_NOFOLLOW anywhere in HOME.c, home_be_subdirs multi-shard break still skips *out_count (the fail(__) with __==OK precedes the assignment). NOTHING landed; WIP fix UNLANDED in worktree ~/src/DOG-009 (HOME.c modified).