container/ops: expose remount as Op
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m2s
Test / Hakurei (push) Successful in 2m56s
Test / Hpkg (push) Successful in 3m53s
Test / Sandbox (race detector) (push) Successful in 3m56s
Test / Hakurei (race detector) (push) Successful in 4m34s
Test / Flake checks (push) Successful in 1m22s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m2s
Test / Hakurei (push) Successful in 2m56s
Test / Hpkg (push) Successful in 3m53s
Test / Sandbox (race detector) (push) Successful in 3m56s
Test / Hakurei (race detector) (push) Successful in 4m34s
Test / Flake checks (push) Successful in 1m22s
This is useful for building a filesystem hierarchy then remounting it readonly. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
1dc780bca7
commit
c5d24979f5
@ -38,6 +38,7 @@ var containerTestCases = []struct {
|
|||||||
filter bool
|
filter bool
|
||||||
session bool
|
session bool
|
||||||
net bool
|
net bool
|
||||||
|
ro bool
|
||||||
ops *container.Ops
|
ops *container.Ops
|
||||||
|
|
||||||
mnt []*vfs.MountInfoEntry
|
mnt []*vfs.MountInfoEntry
|
||||||
@ -48,26 +49,26 @@ var containerTestCases = []struct {
|
|||||||
flags seccomp.ExportFlag
|
flags seccomp.ExportFlag
|
||||||
presets seccomp.FilterPreset
|
presets seccomp.FilterPreset
|
||||||
}{
|
}{
|
||||||
{"minimal", true, false, false,
|
{"minimal", true, false, false, true,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetStrict},
|
1000, 100, nil, 0, seccomp.PresetStrict},
|
||||||
{"allow", true, true, true,
|
{"allow", true, true, true, false,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
1000, 100, nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
||||||
{"no filter", false, true, true,
|
{"no filter", false, true, true, true,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetExt},
|
1000, 100, nil, 0, seccomp.PresetExt},
|
||||||
{"custom rules", true, true, true,
|
{"custom rules", true, true, true, false,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1, 31, []seccomp.NativeRule{{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil}}, 0, seccomp.PresetExt},
|
1, 31, []seccomp.NativeRule{{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil}}, 0, seccomp.PresetExt},
|
||||||
{"tmpfs", true, false, false,
|
{"tmpfs", true, false, false, true,
|
||||||
new(container.Ops).
|
new(container.Ops).
|
||||||
Tmpfs(hst.Tmp, 0, 0755),
|
Tmpfs(hst.Tmp, 0, 0755),
|
||||||
[]*vfs.MountInfoEntry{
|
[]*vfs.MountInfoEntry{
|
||||||
ent("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore),
|
ent("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore),
|
||||||
},
|
},
|
||||||
9, 9, nil, 0, seccomp.PresetStrict},
|
9, 9, nil, 0, seccomp.PresetStrict},
|
||||||
{"dev", true, true /* go test output is not a tty */, false,
|
{"dev", true, true /* go test output is not a tty */, false, false,
|
||||||
new(container.Ops).
|
new(container.Ops).
|
||||||
Dev("/dev").
|
Dev("/dev").
|
||||||
Mqueue("/dev/mqueue"),
|
Mqueue("/dev/mqueue"),
|
||||||
@ -178,6 +179,10 @@ func TestContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
c.Place(pathWantMnt, want.Bytes())
|
c.Place(pathWantMnt, want.Bytes())
|
||||||
|
|
||||||
|
if tc.ro {
|
||||||
|
c.Remount("/", syscall.MS_RDONLY)
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.Start(); err != nil {
|
if err := c.Start(); err != nil {
|
||||||
hlog.PrintBaseError(err, "start:")
|
hlog.PrintBaseError(err, "start:")
|
||||||
t.Fatalf("cannot start container: %v", err)
|
t.Fatalf("cannot start container: %v", err)
|
||||||
@ -330,6 +335,11 @@ func init() {
|
|||||||
return fmt.Errorf("cannot close expected mount points: %v", err)
|
return fmt.Errorf("cannot close expected mount points: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tc.ro && len(mnt) > 0 {
|
||||||
|
// Remount("/", syscall.MS_RDONLY)
|
||||||
|
mnt[0].VfsOptstr = "ro,nosuid,nodev"
|
||||||
|
}
|
||||||
|
|
||||||
var d *vfs.MountInfoDecoder
|
var d *vfs.MountInfoDecoder
|
||||||
if f, err := os.Open("/proc/self/mountinfo"); err != nil {
|
if f, err := os.Open("/proc/self/mountinfo"); err != nil {
|
||||||
return fmt.Errorf("cannot open mountinfo: %v", err)
|
return fmt.Errorf("cannot open mountinfo: %v", err)
|
||||||
|
@ -33,6 +33,32 @@ type (
|
|||||||
// Grow grows the slice Ops points to using [slices.Grow].
|
// Grow grows the slice Ops points to using [slices.Grow].
|
||||||
func (f *Ops) Grow(n int) { *f = slices.Grow(*f, n) }
|
func (f *Ops) Grow(n int) { *f = slices.Grow(*f, n) }
|
||||||
|
|
||||||
|
func init() { gob.Register(new(RemountOp)) }
|
||||||
|
|
||||||
|
// Remount appends an [Op] that applies [RemountOp.Flags] on container path [RemountOp.Target].
|
||||||
|
func (f *Ops) Remount(target string, flags uintptr) *Ops {
|
||||||
|
*f = append(*f, &RemountOp{target, flags})
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemountOp struct {
|
||||||
|
Target string
|
||||||
|
Flags uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemountOp) early(*Params) error { return nil }
|
||||||
|
func (r *RemountOp) apply(*Params) error {
|
||||||
|
if !path.IsAbs(r.Target) {
|
||||||
|
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", r.Target))
|
||||||
|
}
|
||||||
|
return wrapErrSuffix(hostProc.remount(toSysroot(r.Target), r.Flags),
|
||||||
|
fmt.Sprintf("cannot remount %q:", r.Target))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemountOp) Is(op Op) bool { vr, ok := op.(*RemountOp); return ok && *r == *vr }
|
||||||
|
func (*RemountOp) prefix() string { return "remounting" }
|
||||||
|
func (r *RemountOp) String() string { return fmt.Sprintf("%q flags %#x", r.Target, r.Flags) }
|
||||||
|
|
||||||
func init() { gob.Register(new(BindMountOp)) }
|
func init() { gob.Register(new(BindMountOp)) }
|
||||||
|
|
||||||
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
||||||
|
Loading…
x
Reference in New Issue
Block a user