Repository navigation
No product-build way to relocate the daemon runtime directory when %LOCALAPPDATA% has a capability-SID ACE #1574
Description
Activity
- addedbugSomething isn't workingSomething isn't workingsecuritySecurity vulnerabilities, hardeningSecurity vulnerabilities, hardeningeditor/integrationEditor compatibility and CLI integrationEditor compatibility and CLI integrationux/behaviorDisplay bugs, docs, adoption UXDisplay bugs, docs, adoption UXpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.Needs near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
on Aug 12, 2026 Thank you @tmonestudio. Confirmed on current
main:main_daemon_endpoint_new()reads onlyCBM_TEST_DAEMON_RUNTIME_PARENTunderCBM_ENABLE_TEST_SEAMS, while the other product endpoint paths callcbm_daemon_bootstrap_endpoint_new(NULL). A product binary therefore has no supported runtime-parent override, and relocatingCBM_CACHE_DIRdoes not move the daemon rendezvous.#1576 targets this gap without relaxing the private-directory validation. This is routed as a high-priority Windows/security compatibility bug. The PR itself first needs to be unstacked from #1561 so its runtime-only diff can be reviewed cleanly. Thank you for supplying both the failing security condition and a fail-closed design.
- added a commit that references this issue
on Aug 14, 2026 Thank you for this, @tmonestudio. Walking the ancestry with the same predicate as
win_private_directory_tree_secureand coming back with the exact capability SID andmask=0x000D0152removed all the guesswork, and your check thatC:\Users\Default\AppData\Localcarries no such ACE settled whether this was a Windows default or something an installed app left behind.Re-confirmed and unchanged: the daemon runtime-directory parent is not overridable in a product build. The only override,
CBM_TEST_DAEMON_RUNTIME_PARENT, is read inside#ifdef CBM_ENABLE_TEST_SEAMSinmain_daemon_endpoint_new(), so it is compiled out of shipped binaries — the test binary starts and yours cannot, exactly as you described.A binary that cannot even run
config liston an ordinary machine is an operability blocker, and this is a top item for tonight's v0.10.5, which is being prepared for precisely that class of issue. Sorry that you had to readsrc/daemon/ipc.cto learn why it refused; naming the offending path in the endpoint error is part of the same work.- added a commit that references this issue
on Aug 14, 2026 - added a commit that references this issue
on Aug 15, 2026 Fixed in v0.10.5 by #1623 (merged 076c8ae): ancestor directories now tolerate AppContainer/capability SIDs — exactly the
S-1-15-3-…mask=0x000D0152ACE you isolated — while the runtime directory itself stays strict (owned by you, no allow-ACL). Your ancestry walk with the same predicate aswin_private_directory_tree_secureis what made the tolerate-vs-refuse boundary decidable, thank you. Since #1645 there is also a product-buildCBM_RUNTIME_DIRoverride as a general lever when a host's profile tree is unusual. If v0.10.5+ still refuses on your machine, please reopen with the new refusal line (it now names the exact ancestor).
Summary
On Windows the daemon/CLI coordination endpoint is created under
%LOCALAPPDATA%, resolved bySHGetFolderPathW(CSIDL_LOCAL_APPDATA)with nooverride in a product build. If that ancestry carries a capability-SID ACE with
mutation rights — common on real machines once packaged apps are installed — the
binary cannot start at all, and there is no supported way to point it elsewhere.
The only relocation hook,
CBM_TEST_DAEMON_RUNTIME_PARENT, is compiled outunless
CBM_ENABLE_TEST_SEAMSis defined, so the test binary starts fine whilethe product binary does not.
Environment
main@7d6cdb23+ localcc56d509.main, built 2026-08-12.Observed
Every invocation path fails, including
config list, so the settings surface isunreachable. Independent of
CBM_CACHE_DIR: with the cache on a cleanvolume-root path the cache check passes and the endpoint failure remains.
Walking the ancestry with the same predicate as
win_private_directory_tree_secure, the only rejected entries under%LOCALAPPDATA%are a single capability SID:0x000D0152includesWRITE_DAC,WRITE_OWNERandDELETE. We are notasking you to trust that — we agree it is a real tamper vector. Note it is not a
Windows default:
C:\Users\Default\AppData\Localhas no such ACE. It arrivedwith an installed application, and it is present on
AppData,Local,RoamingandLocalLow.Requests, in order of preference
key or environment variable, validated by the same
win_private_directory_tree_secure. The operator picks a path with cleanancestry; the check keeps its full strength. This is the one that unblocks us
without weakening anything.
ipc_validation_detailand is immediately actionable; the endpoint failureprints neither the path nor the ACE, so diagnosing it took reading
src/daemon/ipc.c.so operators can provision one deliberately instead of discovering it from a
rejection.
Cache directory: works, with a caveat worth documenting
Our cache lives on a secondary data volume (46.5 GB; the system volume has 31.8
GB free, so relocating is not an option).
F:\IndexadorData\...is rejected foran inherited
Authenticated Users → Modifyfrom the volume root — correctly, wethink. Putting the cache directly under the volume root passes, since the
tool then owns the final directory's DACL and the only ancestor is the root
itself. That is a useful and non-obvious property; documenting it would save
others the same investigation.
Offer
We have the working and failing binaries side by side and an 823-project cache.
Happy to run any diagnostic build.