sandbox: prepare ops early
All checks were successful
Test / Create distribution (push) Successful in 24s
Test / Fortify (push) Successful in 2m27s
Test / Fpkg (push) Successful in 3m33s
Test / Data race detector (push) Successful in 4m9s
Test / Flake checks (push) Successful in 53s

Some setup code needs to run in host root. This change allows that to happen.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-03-18 02:17:46 +09:00
parent 1b9408864f
commit b74a08dda9
5 changed files with 78 additions and 50 deletions

View File

@@ -6,6 +6,7 @@ import (
"math"
"os"
"path"
"path/filepath"
"slices"
"syscall"
"unsafe"
@@ -15,17 +16,48 @@ func init() { gob.Register(new(BindMount)) }
// BindMount bind mounts host path Source on container path Target.
type BindMount struct {
Source, Target string
Source, SourceFinal, Target string
Flags int
}
func (b *BindMount) early(*Params) error {
if !path.IsAbs(b.Source) {
return msg.WrapErr(syscall.EBADE,
fmt.Sprintf("path %q is not absolute", b.Source))
}
if b.Flags&BindSource != 0 {
b.SourceFinal = b.Source
return nil
}
if v, err := filepath.EvalSymlinks(b.Source); err != nil {
if os.IsNotExist(err) && b.Flags&BindOptional != 0 {
b.SourceFinal = "\x00"
return nil
}
return msg.WrapErr(err, err.Error())
} else {
b.SourceFinal = v
b.Flags |= bindResolved
return nil
}
}
func (b *BindMount) apply(*Params) error {
if !path.IsAbs(b.Source) || !path.IsAbs(b.Target) {
if b.SourceFinal == "\x00" {
if b.Flags&BindOptional == 0 {
// unreachable
return syscall.EBADE
}
return nil
}
if !path.IsAbs(b.SourceFinal) || !path.IsAbs(b.Target) {
return msg.WrapErr(syscall.EBADE,
"path is not absolute")
}
return bindMount(b.Source, b.Target, b.Flags)
return bindMount(b.SourceFinal, b.Target, b.Flags)
}
func (b *BindMount) Is(op Op) bool { vb, ok := op.(*BindMount); return ok && *b == *vb }
@@ -37,7 +69,7 @@ func (b *BindMount) String() string {
return fmt.Sprintf("%q on %q flags %#x", b.Source, b.Target, b.Flags&BindWritable)
}
func (f *Ops) Bind(source, target string, flags int) *Ops {
*f = append(*f, &BindMount{source, target, flags | bindRecursive})
*f = append(*f, &BindMount{source, "", target, flags | bindRecursive})
return f
}
@@ -46,6 +78,7 @@ func init() { gob.Register(new(MountProc)) }
// MountProc mounts a private instance of proc.
type MountProc string
func (p MountProc) early(*Params) error { return nil }
func (p MountProc) apply(*Params) error {
v := string(p)
@@ -76,6 +109,7 @@ func init() { gob.Register(new(MountDev)) }
// MountDev mounts part of host dev.
type MountDev string
func (d MountDev) early(*Params) error { return nil }
func (d MountDev) apply(params *Params) error {
v := string(d)
@@ -135,7 +169,7 @@ func (d MountDev) apply(params *Params) error {
syscall.SYS_IOCTL, 1, syscall.TIOCGWINSZ,
uintptr(unsafe.Pointer(&buf[0])),
); errno == 0 {
if err := bindMount("/proc/self/fd/1", path.Join(v, "console"), BindDevice); err != nil {
if err := bindMount("/proc/self/fd/1", path.Join(v, "console"), BindSource|BindDevice); err != nil {
return err
}
}
@@ -157,6 +191,7 @@ func init() { gob.Register(new(MountMqueue)) }
// MountMqueue mounts a private mqueue instance on container Path.
type MountMqueue string
func (m MountMqueue) early(*Params) error { return nil }
func (m MountMqueue) apply(*Params) error {
v := string(m)
@@ -191,6 +226,7 @@ type MountTmpfs struct {
Perm os.FileMode
}
func (t *MountTmpfs) early(*Params) error { return nil }
func (t *MountTmpfs) apply(*Params) error {
if !path.IsAbs(t.Path) {
return msg.WrapErr(syscall.EBADE,
@@ -216,6 +252,7 @@ func init() { gob.Register(new(Symlink)) }
// Symlink creates a symlink in the container filesystem.
type Symlink [2]string
func (l *Symlink) early(*Params) error { return nil }
func (l *Symlink) apply(*Params) error {
// symlink target is an arbitrary path value, so only validate link name here
if !path.IsAbs(l[1]) {
@@ -241,6 +278,7 @@ func init() { gob.Register(new(Mkdir)) }
// Mkdir creates a directory in the container filesystem.
type Mkdir string
func (m Mkdir) early(*Params) error { return nil }
func (m Mkdir) apply(*Params) error {
v := string(m)
@@ -272,6 +310,7 @@ type Tmpfile struct {
Data []byte
}
func (t *Tmpfile) early(*Params) error { return nil }
func (t *Tmpfile) apply(*Params) error {
if !path.IsAbs(t.Path) {
return msg.WrapErr(syscall.EBADE,