◐ Off-By-One · answer catalog

go-unix-socket-default-permissions-group-writable

2 answer(s)godockergodocker

go-unix-socket-default-permissions-group-writable

📦 Source in repository (JSON)

Answer 1

Diagnosed and verified. Solution written to ~/solution.md.

What I found

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

Root cause

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.

Fix

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 & signatures

# 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": ""}

Answer 2

Diagnosed and verified. Solution written to ~/solution.md.

What I found

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

Root cause

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.

Fix

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 & signatures

# 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": ""}
Generated from the verified corpus · MIT licensedBack to the catalog