Files
stack/agents/darkwing/work/queue-86-review/r1/s2-uid-mapping.out
T
jason.woltjeandClaude Opus 5.5 459c4fc681 darkwing: row 86 round 1 review packet, approve (#1580)
Review notes and the rerun of S1, S2, S4, S8, S9 and S0 in a detached
worktree of ad0bdc20. Verdict comment 27986, rev 803 (swept in 85fd3286).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:32:48 -05:00

66 lines
5.2 KiB
Plaintext

# s2-uid-mapping 2026-10-12T22:29:06Z
endpoint unix:///run/user/1000/docker.sock: name=rootless
scratch /home/jwoltje/darkwing-scratch/rv86/tmp/i1spike-s2-uid-mapping.UtDZ7H
## the mapping
host uid/gid: 1000/1000; /etc/subuid line count for this user: 1
0 1000 1
1 100000 65536
0 1000 1
1 100000 65536
host fixture: -rw------- jwoltje:jwoltje <scratch>/d/file;srw------- jwoltje:jwoltje <scratch>/d/sock;
## 0600 file and 0600 socket owned by the host user
uid 0 (user: 0:0) -> {"uid":0,"gid":0,"groups":[0],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 1"}}
ok uid 0 reads the file
ok uid 0 connects to the socket
uid 1000 (user: 1000:1000) -> {"uid":1000,"gid":1000,"groups":[1000],"file":{"ok":false,"err":"EACCES"},"sock":{"ok":false,"err":"EACCES"}}
ok uid 1000 cannot read the file
ok uid 1000 cannot connect to the socket
uid 2000 (user: 2000:2000) -> {"uid":2000,"gid":2000,"groups":[2000],"file":{"ok":false,"err":"EACCES"},"sock":{"ok":false,"err":"EACCES"}}
ok uid 2000 cannot read the file
ok uid 2000 cannot connect to the socket
uid 0 with the hardening set (--cap-drop ALL, no-new-privileges, --read-only) -> {"uid":0,"gid":0,"groups":[0],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 2"}}
ok uid 0 with cap-drop ALL still reads the host user's 0600 file
ok uid 0 with cap-drop ALL still connects to the host user's 0600 socket
## 0660 and the host group, non-root container uid with the group added
host fixture: -rw-rw---- jwoltje:jwoltje;srw-rw---- jwoltje:jwoltje;
uid 1000, no extra group -> {"uid":1000,"gid":1000,"groups":[1000],"file":{"ok":false,"err":"EACCES"},"sock":{"ok":false,"err":"EACCES"}}
ok uid 1000 without the group is still refused (file)
uid 1000 + --group-add 0 -> {"uid":1000,"gid":1000,"groups":[0,1000],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 3"}}
ok uid 1000 + group 0 reads the file
ok uid 1000 + group 0 connects to the socket
uid 2000:2000 + --group-add 0 -> {"uid":2000,"gid":2000,"groups":[0,2000],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 4"}}
ok uid 2000 + group 0 connects (two roles would share it)
## world-accessible (0666) for comparison
uid 2000, no group -> {"uid":2000,"gid":2000,"groups":[2000],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 5"}}
ok uid 2000 connects when the socket is 0666
## a file chowned to a container uid, seen from the host
host sees: -rw------- 100999:100999
ok the host user can no longer read a file owned by container uid 1000 (mode 0600)
uid 1000 owner -> {"uid":1000,"gid":1000,"groups":[1000],"file":{"ok":true,"head":"not-a-secret\n"},"sock":{"ok":true,"reply":"pong host 6"}}
ok container uid 1000 reads its own file
chowned back, host sees: -rw------- 1000:1000
## the reverse: a socket created by container uid 1000 in a mounted directory
host sees: srw------- 100999:100999 (host user is 1000:1000)
host connect, mode 0600 -> {"uid":1000,"gid":1000,"groups":[3,90,108,955,956,979,982,983,985,989,995,998,1000,3009],"sock":{"ok":false,"err":"EACCES"}}
ok host user cannot connect to a 0600 socket owned by container uid 1000
after the container root chmods it 0660 (group is the container's gid 1000): host sees srw-rw---- 100999:100999
host connect, mode 0660 -> {"uid":1000,"gid":1000,"groups":[3,90,108,955,956,979,982,983,985,989,995,998,1000,3009],"sock":{"ok":false,"err":"EACCES"}}
ok host user is still refused at 0660 (not in the owning group)
host connect, mode 0666 -> {"uid":1000,"gid":1000,"groups":[3,90,108,955,956,979,982,983,985,989,995,998,1000,3009],"sock":{"ok":true,"reply":"pong container 1"}}
ok host user connects at 0666
## container to container: a socket made by one container uid, reached from another container
host sees the socket: srw-rw---- 101000:101999 (made by container 1001:2000, mode 0660)
client 1000:1000 + --group-add 2000 -> {"uid":1000,"gid":1000,"groups":[1000,2000],"sock":{"ok":true,"reply":"pong broker 1"}}
ok a different uid in the socket's group connects (mode 0660, :ro directory mount, cap-drop ALL)
client 1000:1000, no group -> {"uid":1000,"gid":1000,"groups":[1000],"sock":{"ok":false,"err":"EACCES"}}
ok a different uid outside the group is refused
client 0:0, default capabilities -> {"uid":0,"gid":0,"groups":[0],"sock":{"ok":true,"reply":"pong broker 2"}}
(container root is the host user, who owns nothing here; default capabilities include CAP_DAC_OVERRIDE over inodes mapped into the container)
ok container root with default capabilities connects: CAP_DAC_OVERRIDE overrides the mode
client 0:0, --cap-drop ALL -> {"uid":0,"gid":0,"groups":[0],"sock":{"ok":false,"err":"EACCES"}}
ok container root with cap-drop ALL is refused: it is neither owner nor group
client 0:0, --cap-drop ALL, --group-add 2000 -> {"uid":0,"gid":0,"groups":[0,2000],"sock":{"ok":true,"reply":"pong broker 3"}}
ok container root with cap-drop ALL and the group connects
cleanup: no container, network, image or scratch directory labelled s2-uid-mapping is left
result: pass