A directory a module mounts into its container belongs to whoever runs inside — grafana's 472, redis's 999, www-data's 33 — and none of those has a row in the machine's passwd. Owner-by-name refused them all, which looked principled and meant every module whose container drops privileges could not own its own data. The lab showed both coats of it in one run: the store's config file was unreadable to the store, restarting forever on permission denied, and the forge could not traverse into the 0700 root-owned directory that held its files — a directory that had only become root-owned when declaring it fixed 04-ISSUES/026, because Docker used to create it 0755. A fix that tightens ownership without a way to say whose it should be moves the fault, not removes it. "uid:gid" and bare "uid" are numeric and chowned as given; a name still resolves as before, and a name with a colon is refused rather than half-read.
35 lines
1.2 KiB
Go
35 lines
1.2 KiB
Go
package apply
|
|
|
|
import "testing"
|
|
|
|
// A container's user is a number the machine has never heard of — grafana's 472, redis's 999 —
|
|
// so an owner must be expressible without a passwd row. Refusing numerics looked principled and
|
|
// meant every module whose container drops privileges could not own its own data.
|
|
func TestAnOwnerMayBeANumberTheMachineDoesNotKnow(t *testing.T) {
|
|
for owner, want := range map[string][2]int{
|
|
"472:472": {472, 472},
|
|
"1000:1000": {1000, 1000},
|
|
"999": {999, 999},
|
|
"10001:10001": {10001, 10001},
|
|
"33:0": {33, 0},
|
|
} {
|
|
uid, gid, err := idsOf(owner)
|
|
if err != nil {
|
|
t.Errorf("%q refused: %v", owner, err)
|
|
continue
|
|
}
|
|
if uid != want[0] || gid != want[1] {
|
|
t.Errorf("%q resolved to %d:%d, wanted %d:%d", owner, uid, gid, want[0], want[1])
|
|
}
|
|
}
|
|
if _, _, err := idsOf("no-such-user-exists-here"); err == nil {
|
|
t.Error("a name this machine does not know was accepted")
|
|
}
|
|
if _, _, err := idsOf("root:something"); err == nil {
|
|
t.Error("a name with a colon was accepted; a name stands alone")
|
|
}
|
|
if uid, gid, err := idsOf("root"); err != nil || uid != 0 || gid != 0 {
|
|
t.Errorf("root resolved to %d:%d (%v); names must still work", uid, gid, err)
|
|
}
|
|
}
|