sandbox: write uid/gid map as init
This avoids PR_SET_DUMPABLE in the parent process. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
94895bbacb
commit
f41fd94628
@ -58,10 +58,6 @@ type (
|
|||||||
InitParams
|
InitParams
|
||||||
// Custom [exec.Cmd] initialisation function.
|
// Custom [exec.Cmd] initialisation function.
|
||||||
CommandContext func(ctx context.Context) (cmd *exec.Cmd)
|
CommandContext func(ctx context.Context) (cmd *exec.Cmd)
|
||||||
// mapped uid in user namespace
|
|
||||||
Uid int
|
|
||||||
// mapped gid in user namespace
|
|
||||||
Gid int
|
|
||||||
|
|
||||||
// param encoder for shim and init
|
// param encoder for shim and init
|
||||||
setup *gob.Encoder
|
setup *gob.Encoder
|
||||||
@ -86,6 +82,10 @@ type (
|
|||||||
// Initial process argv.
|
// Initial process argv.
|
||||||
Args []string
|
Args []string
|
||||||
|
|
||||||
|
// Mapped Uid in user namespace.
|
||||||
|
Uid int
|
||||||
|
// Mapped Gid in user namespace.
|
||||||
|
Gid int
|
||||||
// Hostname value in UTS namespace.
|
// Hostname value in UTS namespace.
|
||||||
Hostname string
|
Hostname string
|
||||||
// Sequential container setup ops.
|
// Sequential container setup ops.
|
||||||
@ -140,8 +140,6 @@ func (p *Container) Start() error {
|
|||||||
syscall.CLONE_NEWPID |
|
syscall.CLONE_NEWPID |
|
||||||
syscall.CLONE_NEWNS,
|
syscall.CLONE_NEWNS,
|
||||||
|
|
||||||
UidMappings: []syscall.SysProcIDMap{{p.Uid, syscall.Getuid(), 1}},
|
|
||||||
GidMappings: []syscall.SysProcIDMap{{p.Gid, syscall.Getgid(), 1}},
|
|
||||||
// remain privileged for setup
|
// remain privileged for setup
|
||||||
AmbientCaps: []uintptr{CAP_SYS_ADMIN},
|
AmbientCaps: []uintptr{CAP_SYS_ADMIN},
|
||||||
|
|
||||||
@ -200,6 +198,8 @@ func (p *Container) Serve() error {
|
|||||||
return setup.Encode(
|
return setup.Encode(
|
||||||
&initParams{
|
&initParams{
|
||||||
p.InitParams,
|
p.InitParams,
|
||||||
|
syscall.Getuid(),
|
||||||
|
syscall.Getgid(),
|
||||||
len(p.ExtraFiles),
|
len(p.ExtraFiles),
|
||||||
fmsg.Load(),
|
fmsg.Load(),
|
||||||
},
|
},
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -65,6 +66,8 @@ func TestContainer(t *testing.T) {
|
|||||||
|
|
||||||
container := sandbox.New(ctx, os.Args[0], "-test.v",
|
container := sandbox.New(ctx, os.Args[0], "-test.v",
|
||||||
"-test.run=TestHelperCheckContainer", "--", "check", tc.host)
|
"-test.run=TestHelperCheckContainer", "--", "check", tc.host)
|
||||||
|
container.Uid = 1000
|
||||||
|
container.Gid = 100
|
||||||
container.Hostname = tc.host
|
container.Hostname = tc.host
|
||||||
container.CommandContext = func(ctx context.Context) *exec.Cmd {
|
container.CommandContext = func(ctx context.Context) *exec.Cmd {
|
||||||
return exec.CommandContext(ctx, os.Args[0], "-test.v",
|
return exec.CommandContext(ctx, os.Args[0], "-test.v",
|
||||||
@ -154,6 +157,14 @@ func TestHelperCheckContainer(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Run("user", func(t *testing.T) {
|
||||||
|
if uid := syscall.Getuid(); uid != 1000 {
|
||||||
|
t.Errorf("Getuid: %d, want 1000", uid)
|
||||||
|
}
|
||||||
|
if gid := syscall.Getgid(); gid != 100 {
|
||||||
|
t.Errorf("Getgid: %d, want 100", gid)
|
||||||
|
}
|
||||||
|
})
|
||||||
t.Run("hostname", func(t *testing.T) {
|
t.Run("hostname", func(t *testing.T) {
|
||||||
if name, err := os.Hostname(); err != nil {
|
if name, err := os.Hostname(); err != nil {
|
||||||
t.Fatalf("cannot get hostname: %v", err)
|
t.Fatalf("cannot get hostname: %v", err)
|
||||||
|
@ -33,6 +33,7 @@ const (
|
|||||||
type initParams struct {
|
type initParams struct {
|
||||||
InitParams
|
InitParams
|
||||||
|
|
||||||
|
HostUid, HostGid int
|
||||||
// extra files count
|
// extra files count
|
||||||
Count int
|
Count int
|
||||||
// verbosity pass through
|
// verbosity pass through
|
||||||
@ -43,10 +44,6 @@ func Init(exit func(code int)) {
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
fmsg.Prepare("init")
|
fmsg.Prepare("init")
|
||||||
|
|
||||||
if err := internal.SetDumpable(internal.SUID_DUMP_DISABLE); err != nil {
|
|
||||||
log.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if os.Getpid() != 1 {
|
if os.Getpid() != 1 {
|
||||||
log.Fatal("this process must run as pid 1")
|
log.Fatal("this process must run as pid 1")
|
||||||
}
|
}
|
||||||
@ -80,6 +77,29 @@ func Init(exit func(code int)) {
|
|||||||
offsetSetup = int(setupFile.Fd() + 1)
|
offsetSetup = int(setupFile.Fd() + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write uid/gid map here so parent does not need to set dumpable
|
||||||
|
if err := internal.SetDumpable(internal.SUID_DUMP_USER); err != nil {
|
||||||
|
log.Fatalf("cannot set SUID_DUMP_USER: %s", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile("/proc/self/uid_map",
|
||||||
|
append([]byte{}, strconv.Itoa(params.Uid)+" "+strconv.Itoa(params.HostUid)+" 1\n"...),
|
||||||
|
0); err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile("/proc/self/setgroups",
|
||||||
|
[]byte("deny\n"),
|
||||||
|
0); err != nil && !os.IsNotExist(err) {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile("/proc/self/gid_map",
|
||||||
|
append([]byte{}, strconv.Itoa(params.Gid)+" "+strconv.Itoa(params.HostGid)+" 1\n"...),
|
||||||
|
0); err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
if err := internal.SetDumpable(internal.SUID_DUMP_DISABLE); err != nil {
|
||||||
|
log.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
if params.Hostname != "" {
|
if params.Hostname != "" {
|
||||||
if err := syscall.Sethostname([]byte(params.Hostname)); err != nil {
|
if err := syscall.Sethostname([]byte(params.Hostname)); err != nil {
|
||||||
log.Fatalf("cannot set hostname: %v", err)
|
log.Fatalf("cannot set hostname: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user