go-unix-socket-default-permissions-group-writable
Diagnosed and verified. Solution written to ~/solution.md.
There was no toolsd repo in this environment — it's an isolated problem class. I built a faithful minimal toolsd serve (bind + ping verb) and reproduced the bug and fix live:
probe (under umask 002) |
buggy | fixed |
|---|---|---|
stat mode |
srwxrwxr-x 0775 |
srw------- 0600 |
| ping round-trip | "pong" |
"pong" |
| second-instance refusal | works | works (exit 2) |
| Go tests | RED | GREEN |
net.Listen("unix", path) creates the socket node with 0777 &^ umask. Go applies no mode of its own. With umask 002 the endpoint becomes 0775 — any same-group user passes the kernel's connect(2) permission check and can drive every privileged verb as the socket owner.
os.Chmod(sockPath, 0o600) immediately after Listen, fail-closed, before the accept loop; create the socket inside a 0700 parent directory to close the bind→chmod race. Full diff, tests-first RED pin (TestSocketModeLockedDown + rebind-refusal), verbatim console verification, and generalization notes are in the document.
Note: the earlier failing test I hit was my own inverted assertion (dialing a live listener should succeed — that's how the single-instance guard detects it), which I corrected; the final suite passes.
# Evidence - Problem class: go-unix-socket-default-permissions-group-writable - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-28T01:40:24.487Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "toolsd serve bound its unix socket via net.Listen without setting mode; Go leaves the socket 0777&^umask, which on a shared host (umask 002) is 0775 group-writable \u2014 any same-group user can invoke every verb as the socket owner. Diagnosis: stat the socket (srwxrwxr-x). Fix shape: tests-first RED pin (assert mode 0600 + rebind-refusal intact), then os.Chmod(path, 0600) immediately after Listen before serving; live probe the delivered socket with stat + a ping round-trip. Generalize: any tool that creates a privileged IPC endpoint must pin its permissions explicitly after bind, never inherit umask.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-unix-socket-default-permissions-group-writable", "provider": "openrouter", "solved_at": "2026-09-28T01:40:24.488Z", "version": ""}Diagnosed and verified. Solution written to ~/solution.md.
There was no toolsd repo in this environment — it's an isolated problem class. I built a faithful minimal toolsd serve (bind + ping verb) and reproduced the bug and fix live:
probe (under umask 002) |
buggy | fixed |
|---|---|---|
stat mode |
srwxrwxr-x 0775 |
srw------- 0600 |
| ping round-trip | "pong" |
"pong" |
| second-instance refusal | works | works (exit 2) |
| Go tests | RED | GREEN |
net.Listen("unix", path) creates the socket node with 0777 &^ umask. Go applies no mode of its own. With umask 002 the endpoint becomes 0775 — any same-group user passes the kernel's connect(2) permission check and can drive every privileged verb as the socket owner.
os.Chmod(sockPath, 0o600) immediately after Listen, fail-closed, before the accept loop; create the socket inside a 0700 parent directory to close the bind→chmod race. Full diff, tests-first RED pin (TestSocketModeLockedDown + rebind-refusal), verbatim console verification, and generalization notes are in the document.
Note: the earlier failing test I hit was my own inverted assertion (dialing a live listener should succeed — that's how the single-instance guard detects it), which I corrected; the final suite passes.
# Evidence - Problem class: go-unix-socket-default-permissions-group-writable - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-28T01:40:24.487Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "toolsd serve bound its unix socket via net.Listen without setting mode; Go leaves the socket 0777&^umask, which on a shared host (umask 002) is 0775 group-writable \u2014 any same-group user can invoke every verb as the socket owner. Diagnosis: stat the socket (srwxrwxr-x). Fix shape: tests-first RED pin (assert mode 0600 + rebind-refusal intact), then os.Chmod(path, 0600) immediately after Listen before serving; live probe the delivered socket with stat + a ping round-trip. Generalize: any tool that creates a privileged IPC endpoint must pin its permissions explicitly after bind, never inherit umask.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-unix-socket-default-permissions-group-writable", "provider": "openrouter", "solved_at": "2026-09-28T01:40:24.488Z", "version": ""}