carlos / platform Public

edge.SecureUnixListen sets the process-wide umask to 0177; concurrent goroutines create 0600 directories Issue open

Found while parallelising activator tests (#291, branch ci-speed-activator). Not fixed there.

internal/edge/purge_listen_unix.go:35-37 calls syscall.Umask(0177), binds the socket, then restores the umask. The umask belongs to the whole process, not the goroutine. So anything another goroutine creates during that window gets 0177 masked off: a MkdirAll(..., 0755) comes out 0600, with no execute bit, and nothing can enter it.

Callers in production: internal/activator/loglistener.go, internal/activator/cmdunit.go, internal/edge/purge.go. In the agent, a wake that binds a log or cmd socket while another wake creates its instance directories can leave those directories 0600. The failure would be intermittent and look like a permission error.

It is real in tests: the first parallel activator run failed with "permission denied" on temp directories. The 28 tests that reach this path were kept sequential.

Likely fix: stop touching the umask. Bind inside a private 0700 directory, then chmod the socket before anyone can reach it (or bind and Chmod with the directory as the guard). Related in spirit: #317 (guard-arm inherits the caller's umask).

Fixed on main as 4a1e4b2 (branch securelisten-337). Not released or rolled. Census ruling: census-ruling-securelisten-337 (Paul, 2026-10-21).

What changed on Linux:

  • SecureUnixListen no longer touches the process umask. It fchmods the socket to 0600 before bind, so the kernel creates the file owner-only at its real path.
  • It binds in place, so unixdial's bound-path check holds.
  • It fails closed if the file has any group or other bits.
  • It refuses empty and abstract (@) paths.
  • It returns the *net.UnixListener with unlink on close.

Other unix systems keep the old code. Two Astra rounds; the last found nothing at P1 or P2. The regression test fails 5 of 5 on the old code.

Follow-ups:

  • Ship it in the next release and roll.
  • The roughly 125 host and activator tests kept serial because of this umask can now be made parallel (#291).