diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-03-18 02:17:46 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-03-18 02:17:46 +0900 |
| commit | b74a08dda968a161e066c92c1bf5b4489e5a4fbd (patch) | |
| tree | e3a30c69f078544184dcb72fc266a25384bfec12 /sandbox/sequential.go | |
| parent | 1b9408864f7f575b83b8f822e7551772ccd37009 (diff) | |
sandbox: prepare ops early
Some setup code needs to run in host root. This change allows that to happen.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'sandbox/sequential.go')
| -rw-r--r-- | sandbox/sequential.go | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/sandbox/sequential.go b/sandbox/sequential.go index 153de0a0..bfcbb068 100644 --- a/sandbox/sequential.go +++ b/sandbox/sequential.go @@ -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, |
