diff --git a/container/autoetc.go b/container/autoetc.go index 65ab9a2..3fd9727 100644 --- a/container/autoetc.go +++ b/container/autoetc.go @@ -59,6 +59,7 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error { return nil } +func (e *AutoEtcOp) late(*setupState, syscallDispatcher) error { return nil } func (e *AutoEtcOp) hostPath() *check.Absolute { return fhs.AbsEtc.Append(e.hostRel()) } func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix } diff --git a/container/autoroot.go b/container/autoroot.go index f555aca..09e059d 100644 --- a/container/autoroot.go +++ b/container/autoroot.go @@ -69,6 +69,7 @@ func (r *AutoRootOp) apply(state *setupState, k syscallDispatcher) error { } return nil } +func (r *AutoRootOp) late(*setupState, syscallDispatcher) error { return nil } func (r *AutoRootOp) Is(op Op) bool { vr, ok := op.(*AutoRootOp) diff --git a/container/init.go b/container/init.go index fa220f2..e5ca171 100644 --- a/container/init.go +++ b/container/init.go @@ -49,6 +49,8 @@ type ( early(state *setupState, k syscallDispatcher) error // apply is called in intermediate root. apply(state *setupState, k syscallDispatcher) error + // late is called right before starting the initial process. + late(state *setupState, k syscallDispatcher) error // prefix returns a log message prefix, and whether this Op prints no identifying message on its own. prefix() (string, bool) @@ -330,6 +332,19 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) { } k.umask(oldmask) + // called right before startup of initial process, all state changes to the + // current process is prohibited during late + for i, op := range *params.Ops { + // ops already checked during early setup + if err := op.late(state, k); err != nil { + if m, ok := messageFromError(err); ok { + k.fatal(msg, m) + } else { + k.fatalf(msg, "cannot complete op at index %d: %v", i, err) + } + } + } + if err := closeSetup(); err != nil { k.fatalf(msg, "cannot close setup pipe: %v", err) } diff --git a/container/initbind.go b/container/initbind.go index 2e63219..f91d508 100644 --- a/container/initbind.go +++ b/container/initbind.go @@ -90,6 +90,7 @@ func (b *BindMountOp) apply(state *setupState, k syscallDispatcher) error { } return k.bindMount(state, source, target, flags) } +func (b *BindMountOp) late(*setupState, syscallDispatcher) error { return nil } func (b *BindMountOp) Is(op Op) bool { vb, ok := op.(*BindMountOp) diff --git a/container/initdev.go b/container/initdev.go index 89a6613..50df680 100644 --- a/container/initdev.go +++ b/container/initdev.go @@ -126,6 +126,7 @@ func (d *MountDevOp) apply(state *setupState, k syscallDispatcher) error { } return k.mountTmpfs(SourceTmpfs, devShmPath, MS_NOSUID|MS_NODEV, 0, 01777) } +func (d *MountDevOp) late(*setupState, syscallDispatcher) error { return nil } func (d *MountDevOp) Is(op Op) bool { vd, ok := op.(*MountDevOp) diff --git a/container/initmkdir.go b/container/initmkdir.go index 218d634..d3c4bbb 100644 --- a/container/initmkdir.go +++ b/container/initmkdir.go @@ -27,6 +27,7 @@ func (m *MkdirOp) early(*setupState, syscallDispatcher) error { return nil } func (m *MkdirOp) apply(_ *setupState, k syscallDispatcher) error { return k.mkdirAll(toSysroot(m.Path.String()), m.Perm) } +func (m *MkdirOp) late(*setupState, syscallDispatcher) error { return nil } func (m *MkdirOp) Is(op Op) bool { vm, ok := op.(*MkdirOp) diff --git a/container/initoverlay.go b/container/initoverlay.go index 5692af4..0c31f8f 100644 --- a/container/initoverlay.go +++ b/container/initoverlay.go @@ -205,6 +205,8 @@ func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error { return k.mount(SourceOverlay, target, FstypeOverlay, 0, strings.Join(options, check.SpecialOverlayOption)) } +func (o *MountOverlayOp) late(*setupState, syscallDispatcher) error { return nil } + func (o *MountOverlayOp) Is(op Op) bool { vo, ok := op.(*MountOverlayOp) return ok && o.Valid() && vo.Valid() && diff --git a/container/initplace.go b/container/initplace.go index fe4b60a..9974c58 100644 --- a/container/initplace.go +++ b/container/initplace.go @@ -57,6 +57,7 @@ func (t *TmpfileOp) apply(state *setupState, k syscallDispatcher) error { } return nil } +func (t *TmpfileOp) late(*setupState, syscallDispatcher) error { return nil } func (t *TmpfileOp) Is(op Op) bool { vt, ok := op.(*TmpfileOp) diff --git a/container/initproc.go b/container/initproc.go index d0df854..3ecb270 100644 --- a/container/initproc.go +++ b/container/initproc.go @@ -28,6 +28,7 @@ func (p *MountProcOp) apply(state *setupState, k syscallDispatcher) error { } return k.mount(SourceProc, target, FstypeProc, MS_NOSUID|MS_NOEXEC|MS_NODEV, zeroString) } +func (p *MountProcOp) late(*setupState, syscallDispatcher) error { return nil } func (p *MountProcOp) Is(op Op) bool { vp, ok := op.(*MountProcOp) diff --git a/container/initremount.go b/container/initremount.go index 9a3217a..b6d1697 100644 --- a/container/initremount.go +++ b/container/initremount.go @@ -26,6 +26,7 @@ func (*RemountOp) early(*setupState, syscallDispatcher) error { return nil } func (r *RemountOp) apply(state *setupState, k syscallDispatcher) error { return k.remount(state, toSysroot(r.Target.String()), r.Flags) } +func (r *RemountOp) late(*setupState, syscallDispatcher) error { return nil } func (r *RemountOp) Is(op Op) bool { vr, ok := op.(*RemountOp) diff --git a/container/initsymlink.go b/container/initsymlink.go index 7d722d5..be0ce2a 100644 --- a/container/initsymlink.go +++ b/container/initsymlink.go @@ -50,6 +50,8 @@ func (l *SymlinkOp) apply(state *setupState, k syscallDispatcher) error { return k.symlink(l.LinkName, target) } +func (l *SymlinkOp) late(*setupState, syscallDispatcher) error { return nil } + func (l *SymlinkOp) Is(op Op) bool { vl, ok := op.(*SymlinkOp) return ok && l.Valid() && vl.Valid() && diff --git a/container/inittmpfs.go b/container/inittmpfs.go index 23e2a83..fb47723 100644 --- a/container/inittmpfs.go +++ b/container/inittmpfs.go @@ -48,6 +48,7 @@ func (t *MountTmpfsOp) apply(_ *setupState, k syscallDispatcher) error { } return k.mountTmpfs(t.FSName, toSysroot(t.Path.String()), t.Flags, t.Size, t.Perm) } +func (t *MountTmpfsOp) late(*setupState, syscallDispatcher) error { return nil } func (t *MountTmpfsOp) Is(op Op) bool { vt, ok := op.(*MountTmpfsOp)