111 lines
2.7 KiB
Go
111 lines
2.7 KiB
Go
|
|
//go:build linux
|
||
|
|
// +build linux
|
||
|
|
|
||
|
|
package staros
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"reflect"
|
||
|
|
"syscall"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestStarCmdSetKeepCapsConfiguresAmbientCaps(t *testing.T) {
|
||
|
|
command, args := testCommandArgs("exit 0")
|
||
|
|
cmd, err := Command(command, args...)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
original := loadCurrentKeepCaps
|
||
|
|
loadCurrentKeepCaps = func() ([]uintptr, error) {
|
||
|
|
return []uintptr{7, 1, 7}, nil
|
||
|
|
}
|
||
|
|
t.Cleanup(func() {
|
||
|
|
loadCurrentKeepCaps = original
|
||
|
|
})
|
||
|
|
|
||
|
|
cmd.CMD.SysProcAttr = &syscall.SysProcAttr{
|
||
|
|
AmbientCaps: []uintptr{9, 1},
|
||
|
|
}
|
||
|
|
if err := cmd.SetKeepCaps(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
want := []uintptr{1, 7, 9}
|
||
|
|
if got := cmd.CMD.SysProcAttr.AmbientCaps; !reflect.DeepEqual(got, want) {
|
||
|
|
t.Fatalf("unexpected ambient caps: got=%v want=%v", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestStarCmdSetKeepCapsPropagatesCapabilityReadError(t *testing.T) {
|
||
|
|
command, args := testCommandArgs("exit 0")
|
||
|
|
cmd, err := Command(command, args...)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
wantErr := errors.New("capget failed")
|
||
|
|
original := loadCurrentKeepCaps
|
||
|
|
loadCurrentKeepCaps = func() ([]uintptr, error) {
|
||
|
|
return nil, wantErr
|
||
|
|
}
|
||
|
|
t.Cleanup(func() {
|
||
|
|
loadCurrentKeepCaps = original
|
||
|
|
})
|
||
|
|
|
||
|
|
if err := cmd.SetKeepCaps(); !errors.Is(err, wantErr) {
|
||
|
|
t.Fatalf("expected keepcaps read error, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestStarCmdSetRunUserPreservesExistingSysProcAttr(t *testing.T) {
|
||
|
|
command, args := testCommandArgs("exit 0")
|
||
|
|
cmd, err := Command(command, args...)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
original := loadCurrentKeepCaps
|
||
|
|
loadCurrentKeepCaps = func() ([]uintptr, error) {
|
||
|
|
return []uintptr{7, 1, 7}, nil
|
||
|
|
}
|
||
|
|
t.Cleanup(func() {
|
||
|
|
loadCurrentKeepCaps = original
|
||
|
|
})
|
||
|
|
|
||
|
|
cmd.CMD.SysProcAttr = &syscall.SysProcAttr{
|
||
|
|
Pdeathsig: syscall.SIGTERM,
|
||
|
|
AmbientCaps: []uintptr{9},
|
||
|
|
}
|
||
|
|
if err := cmd.SetKeepCaps(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
groups := []uint32{3, 4}
|
||
|
|
if err := cmd.SetRunUserE(1, 2, groups); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
groups[0] = 99
|
||
|
|
|
||
|
|
if got, want := cmd.CMD.SysProcAttr.AmbientCaps, []uintptr{1, 7, 9}; !reflect.DeepEqual(got, want) {
|
||
|
|
t.Fatalf("ambient caps lost after SetRunUserE: got=%v want=%v", got, want)
|
||
|
|
}
|
||
|
|
if got := cmd.CMD.SysProcAttr.Pdeathsig; got != syscall.SIGTERM {
|
||
|
|
t.Fatalf("expected Pdeathsig to be preserved, got %v", got)
|
||
|
|
}
|
||
|
|
if !cmd.CMD.SysProcAttr.Setsid {
|
||
|
|
t.Fatal("expected Setsid to be enabled")
|
||
|
|
}
|
||
|
|
cred := cmd.CMD.SysProcAttr.Credential
|
||
|
|
if cred == nil {
|
||
|
|
t.Fatal("expected credential to be configured")
|
||
|
|
}
|
||
|
|
if cred.Uid != 1 || cred.Gid != 2 {
|
||
|
|
t.Fatalf("unexpected credential ids: uid=%d gid=%d", cred.Uid, cred.Gid)
|
||
|
|
}
|
||
|
|
if got, want := cred.Groups, []uint32{3, 4}; !reflect.DeepEqual(got, want) {
|
||
|
|
t.Fatalf("unexpected credential groups: got=%v want=%v", got, want)
|
||
|
|
}
|
||
|
|
}
|