state: store config in separate gob stream
This enables early serialisation of config. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -3,7 +3,6 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"git.gensokyo.uk/security/fortify/fst"
|
||||
"git.gensokyo.uk/security/fortify/internal/linux"
|
||||
@@ -30,9 +29,6 @@ type RunState struct {
|
||||
}
|
||||
|
||||
type app struct {
|
||||
// single-use config reference
|
||||
ct *appCt
|
||||
|
||||
// application unique identifier
|
||||
id *fst.ID
|
||||
// operating system interface
|
||||
@@ -74,24 +70,3 @@ func New(os linux.System) (App, error) {
|
||||
a.os = os
|
||||
return a, fst.NewAppID(a.id)
|
||||
}
|
||||
|
||||
// appCt ensures its wrapped val is only accessed once
|
||||
type appCt struct {
|
||||
val *fst.Config
|
||||
done *atomic.Bool
|
||||
}
|
||||
|
||||
func (a *appCt) Unwrap() *fst.Config {
|
||||
if !a.done.Load() {
|
||||
defer a.done.Store(true)
|
||||
return a.val
|
||||
}
|
||||
panic("attempted to access config reference twice")
|
||||
}
|
||||
|
||||
func newAppCt(config *fst.Config) (ct *appCt) {
|
||||
ct = new(appCt)
|
||||
ct.done = new(atomic.Bool)
|
||||
ct.val = config
|
||||
return ct
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -47,6 +50,8 @@ type appSeal struct {
|
||||
|
||||
// pass-through enablement tracking from config
|
||||
et system.Enablements
|
||||
// initial config gob encoding buffer
|
||||
ct io.WriterTo
|
||||
// pass-through seccomp config from config
|
||||
scmp *fst.SyscallConfig
|
||||
// wayland socket direct access
|
||||
@@ -87,6 +92,14 @@ func (a *app) Seal(config *fst.Config) error {
|
||||
// create seal
|
||||
seal := new(appSeal)
|
||||
|
||||
// encode initial configuration for state tracking
|
||||
ct := new(bytes.Buffer)
|
||||
if err := gob.NewEncoder(ct).Encode(config); err != nil {
|
||||
return fmsg.WrapErrorSuffix(err,
|
||||
"cannot encode initial config:")
|
||||
}
|
||||
seal.ct = ct
|
||||
|
||||
// fetch system constants
|
||||
seal.Paths = a.os.Paths()
|
||||
|
||||
@@ -261,6 +274,5 @@ func (a *app) Seal(config *fst.Config) error {
|
||||
|
||||
// seal app and release lock
|
||||
a.seal = seal
|
||||
a.ct = newAppCt(config)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -89,16 +89,15 @@ func (a *app) Run(ctx context.Context, rs *RunState) error {
|
||||
|
||||
// shim accepted setup payload, create process state
|
||||
sd := state.State{
|
||||
ID: *a.id,
|
||||
PID: a.shim.Unwrap().Process.Pid,
|
||||
Config: a.ct.Unwrap(),
|
||||
Time: *startTime,
|
||||
ID: *a.id,
|
||||
PID: a.shim.Unwrap().Process.Pid,
|
||||
Time: *startTime,
|
||||
}
|
||||
|
||||
// register process state
|
||||
var err0 = new(StateStoreError)
|
||||
err0.Inner, err0.DoErr = a.seal.store.Do(a.seal.sys.user.aid, func(c state.Cursor) {
|
||||
err0.InnerErr = c.Save(&sd)
|
||||
err0.InnerErr = c.Save(&sd, a.seal.ct)
|
||||
})
|
||||
a.seal.sys.saveState = true
|
||||
if err = err0.equiv("cannot save process state:"); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user