Rationale
PR #708 (#707) closed a stack buffer overflow in copyctopstring by clamping the payload to 255 bytes before the memmove. The overflow class is gone. However, the security review of #708 flagged a defense-in-depth gap: several db_format.c callsites pass user-supplied paths (from --migrate <db>.root, runtime compactdatabase verbs, programmatic ODB compaction) to copyctopstring and discard the new boolean return.
Post-#708 a >255-byte path no longer overflows — but it silently truncates. The truncated path is then passed to pathtofilespec → openfile / opennewfile_exclusive. A truncated path could resolve to a different file than the user intended (path-confusion → wrong-file open / wrong-file write). The existing pathtofilespec failure path catches most cases (the truncated path probably doesn't exist), but it's not a guarantee — if the truncation point happens to land on a real path, the operation succeeds at the wrong location.
The fix shape matches the frontier-cli/window_registry.c:116 pattern PR #708 already established: check the boolean return, log+fail on truncation.
Current State
Common/source/db_format.c callsites at:
- Line 2151 (
copyctopstring(dst_path, bsdst))
- Line 2378 (
copyctopstring(db_path, bspath))
- Line 2493 (and possibly other migration paths in the same function — audit the surrounding
migrate_* helpers)
discard the boolean return from the post-#707 copyctopstring. A >255-byte input still results in the truncated 255-byte prefix being used as if it were the full path.
Desired Outcome
Each affected callsite checks the return value and either:
if (!copyctopstring(dst_path, bsdst)) {
fail_step = "dst_path > 255 bytes (truncated)";
goto cleanup;
}
or surfaces the truncation through whatever error-reporting channel the surrounding function uses. Mirror frontier-cli/window_registry.c:116's pattern.
Exit Criteria
Context
Rationale
PR #708 (#707) closed a stack buffer overflow in
copyctopstringby clamping the payload to 255 bytes before the memmove. The overflow class is gone. However, the security review of #708 flagged a defense-in-depth gap: severaldb_format.ccallsites pass user-supplied paths (from--migrate <db>.root, runtimecompactdatabaseverbs, programmatic ODB compaction) tocopyctopstringand discard the new boolean return.Post-#708 a >255-byte path no longer overflows — but it silently truncates. The truncated path is then passed to
pathtofilespec→openfile/opennewfile_exclusive. A truncated path could resolve to a different file than the user intended (path-confusion → wrong-file open / wrong-file write). The existingpathtofilespecfailure path catches most cases (the truncated path probably doesn't exist), but it's not a guarantee — if the truncation point happens to land on a real path, the operation succeeds at the wrong location.The fix shape matches the
frontier-cli/window_registry.c:116pattern PR #708 already established: check the boolean return, log+fail on truncation.Current State
Common/source/db_format.ccallsites at:copyctopstring(dst_path, bsdst))copyctopstring(db_path, bspath))migrate_*helpers)discard the boolean return from the post-#707
copyctopstring. A >255-byte input still results in the truncated 255-byte prefix being used as if it were the full path.Desired Outcome
Each affected callsite checks the return value and either:
or surfaces the truncation through whatever error-reporting channel the surrounding function uses. Mirror
frontier-cli/window_registry.c:116's pattern.Exit Criteria
copyctopstringcallsite that accepts user-supplied or filesystem-derived paths (the 338 calls grep, filtered to non-literal first args)--migrateand confirms the truncation is surfaced as an error rather than silently using the prefixContext
Common/source/strings.c:1241(post-copyctopstring: silent truncation + buffer overflow risk on >255-byte input #707copyctopstringwith boolean return)frontier-cli/window_registry.c:116(log_warn + early-return on truncation)portable/fileverbs_portable.ccallsites likely need the same audit (mostly hardcoded error strings, but a few like the line 520errbufaccept dynamic content)