app: embed appSeal in app struct
All checks were successful
Test / Create distribution (push) Successful in 25s
Test / Run NixOS test (push) Successful in 3m22s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-02-19 01:10:37 +09:00
parent aa164081e1
commit 53571f030e
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
4 changed files with 45 additions and 46 deletions

View File

@ -11,7 +11,7 @@ import (
func New(os sys.State) (fst.App, error) { func New(os sys.State) (fst.App, error) {
a := new(app) a := new(app)
a.os = os a.sys = os
id := new(fst.ID) id := new(fst.ID)
err := fst.NewAppID(id) err := fst.NewAppID(id)
@ -24,13 +24,12 @@ type app struct {
// application unique identifier // application unique identifier
id *stringPair[fst.ID] id *stringPair[fst.ID]
// operating system interface // operating system interface
os sys.State sys sys.State
// shim process manager // shim process manager
shim *shim.Shim shim *shim.Shim
// child process related information
seal *appSeal
lock sync.RWMutex mu sync.RWMutex
*appSeal
} }
func (a *app) ID() fst.ID { return a.id.unwrap() } func (a *app) ID() fst.ID { return a.id.unwrap() }
@ -40,18 +39,18 @@ func (a *app) String() string {
return "(invalid app)" return "(invalid app)"
} }
a.lock.RLock() a.mu.RLock()
defer a.lock.RUnlock() defer a.mu.RUnlock()
if a.shim != nil { if a.shim != nil {
return a.shim.String() return a.shim.String()
} }
if a.seal != nil { if a.appSeal != nil {
if a.seal.sys.user.uid == nil { if a.appSeal.sys.user.uid == nil {
return fmt.Sprintf("(sealed app %s with invalid uid)", a.id) return fmt.Sprintf("(sealed app %s with invalid uid)", a.id)
} }
return fmt.Sprintf("(sealed app %s as uid %s)", a.id, a.seal.sys.user.uid) return fmt.Sprintf("(sealed app %s as uid %s)", a.id, a.appSeal.sys.user.uid)
} }
return fmt.Sprintf("(unsealed app %s)", a.id) return fmt.Sprintf("(unsealed app %s)", a.id)

View File

@ -10,11 +10,11 @@ import (
func NewWithID(id fst.ID, os sys.State) fst.App { func NewWithID(id fst.ID, os sys.State) fst.App {
a := new(app) a := new(app)
a.id = newID(&id) a.id = newID(&id)
a.os = os a.sys = os
return a return a
} }
func AppSystemBwrap(a fst.App) (*system.I, *bwrap.Config) { func AppSystemBwrap(a fst.App) (*system.I, *bwrap.Config) {
v := a.(*app) v := a.(*app)
return v.seal.sys.I, v.seal.sys.bwrap return v.appSeal.sys.I, v.appSeal.sys.bwrap
} }

View File

@ -79,10 +79,10 @@ type sealedExtraPerm struct {
// Seal seals the app launch context // Seal seals the app launch context
func (a *app) Seal(config *fst.Config) error { func (a *app) Seal(config *fst.Config) error {
a.lock.Lock() a.mu.Lock()
defer a.lock.Unlock() defer a.mu.Unlock()
if a.seal != nil { if a.appSeal != nil {
panic("app sealed twice") panic("app sealed twice")
} }
@ -103,7 +103,7 @@ func (a *app) Seal(config *fst.Config) error {
seal.ct = ct seal.ct = ct
// fetch system constants // fetch system constants
seal.Paths = a.os.Paths() seal.Paths = a.sys.Paths()
// pass through config values // pass through config values
seal.id = a.id.String() seal.id = a.id.String()
@ -119,7 +119,7 @@ func (a *app) Seal(config *fst.Config) error {
if config.Confinement.Sandbox != nil && config.Confinement.Sandbox.MapRealUID { if config.Confinement.Sandbox != nil && config.Confinement.Sandbox.MapRealUID {
// some programs fail to connect to dbus session running as a different uid, so a // some programs fail to connect to dbus session running as a different uid, so a
// separate workaround is introduced to map priv-side caller uid in namespace // separate workaround is introduced to map priv-side caller uid in namespace
mapuid = a.os.Geteuid() mapuid = a.sys.Geteuid()
} }
seal.sys.mapuid = newInt(mapuid) seal.sys.mapuid = newInt(mapuid)
seal.sys.runtime = path.Join("/run/user", seal.sys.mapuid.String()) seal.sys.runtime = path.Join("/run/user", seal.sys.mapuid.String())
@ -152,7 +152,7 @@ func (a *app) Seal(config *fst.Config) error {
} }
// invoke fsu for full uid // invoke fsu for full uid
if u, err := a.os.Uid(seal.sys.user.aid.unwrap()); err != nil { if u, err := a.sys.Uid(seal.sys.user.aid.unwrap()); err != nil {
return err return err
} else { } else {
seal.sys.user.uid = newInt(u) seal.sys.user.uid = newInt(u)
@ -161,7 +161,7 @@ func (a *app) Seal(config *fst.Config) error {
// resolve supplementary group ids from names // resolve supplementary group ids from names
seal.sys.user.supp = make([]string, len(config.Confinement.Groups)) seal.sys.user.supp = make([]string, len(config.Confinement.Groups))
for i, name := range config.Confinement.Groups { for i, name := range config.Confinement.Groups {
if g, err := a.os.LookupGroup(name); err != nil { if g, err := a.sys.LookupGroup(name); err != nil {
return fmsg.WrapError(err, return fmsg.WrapError(err,
fmt.Sprintf("unknown group %q", name)) fmt.Sprintf("unknown group %q", name))
} else { } else {
@ -204,7 +204,7 @@ func (a *app) Seal(config *fst.Config) error {
AutoEtc: true, AutoEtc: true,
} }
// bind entries in / // bind entries in /
if d, err := a.os.ReadDir("/"); err != nil { if d, err := a.sys.ReadDir("/"); err != nil {
return err return err
} else { } else {
b := make([]*fst.FilesystemConfig, 0, len(d)) b := make([]*fst.FilesystemConfig, 0, len(d))
@ -226,7 +226,7 @@ func (a *app) Seal(config *fst.Config) error {
// hide nscd from sandbox if present // hide nscd from sandbox if present
nscd := "/var/run/nscd" nscd := "/var/run/nscd"
if _, err := a.os.Stat(nscd); !errors.Is(err, fs.ErrNotExist) { if _, err := a.sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) {
conf.Override = append(conf.Override, nscd) conf.Override = append(conf.Override, nscd)
} }
// bind GPU stuff // bind GPU stuff
@ -239,7 +239,7 @@ func (a *app) Seal(config *fst.Config) error {
config.Confinement.Sandbox = conf config.Confinement.Sandbox = conf
} }
seal.directWayland = config.Confinement.Sandbox.DirectWayland seal.directWayland = config.Confinement.Sandbox.DirectWayland
if b, err := config.Confinement.Sandbox.Bwrap(a.os); err != nil { if b, err := config.Confinement.Sandbox.Bwrap(a.sys); err != nil {
return err return err
} else { } else {
seal.sys.bwrap = b seal.sys.bwrap = b
@ -265,7 +265,7 @@ func (a *app) Seal(config *fst.Config) error {
seal.Enablements = config.Confinement.Enablements seal.Enablements = config.Confinement.Enablements
// this method calls all share methods in sequence // this method calls all share methods in sequence
if err := seal.setupShares([2]*dbus.Config{config.Confinement.SessionBus, config.Confinement.SystemBus}, a.os); err != nil { if err := seal.setupShares([2]*dbus.Config{config.Confinement.SessionBus, config.Confinement.SystemBus}, a.sys); err != nil {
return err return err
} }
@ -274,6 +274,6 @@ func (a *app) Seal(config *fst.Config) error {
seal.sys.user.uid, seal.sys.user.username, config.Confinement.Groups, config.Command) seal.sys.user.uid, seal.sys.user.username, config.Confinement.Groups, config.Command)
// seal app and release lock // seal app and release lock
a.seal = seal a.appSeal = seal
return nil return nil
} }

View File

@ -21,8 +21,8 @@ import (
const shimSetupTimeout = 5 * time.Second const shimSetupTimeout = 5 * time.Second
func (a *app) Run(ctx context.Context, rs *fst.RunState) error { func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
a.lock.Lock() a.mu.Lock()
defer a.lock.Unlock() defer a.mu.Unlock()
if rs == nil { if rs == nil {
panic("attempted to pass nil state to run") panic("attempted to pass nil state to run")
@ -30,8 +30,8 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
// resolve exec paths // resolve exec paths
shimExec := [2]string{helper.BubblewrapName} shimExec := [2]string{helper.BubblewrapName}
if len(a.seal.command) > 0 { if len(a.appSeal.command) > 0 {
shimExec[1] = a.seal.command[0] shimExec[1] = a.appSeal.command[0]
} }
for i, n := range shimExec { for i, n := range shimExec {
if len(n) == 0 { if len(n) == 0 {
@ -48,18 +48,18 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
} }
// startup will go ahead, commit system setup // startup will go ahead, commit system setup
if err := a.seal.sys.Commit(ctx); err != nil { if err := a.appSeal.sys.Commit(ctx); err != nil {
return err return err
} }
a.seal.sys.needRevert = true a.appSeal.sys.needRevert = true
// start shim via manager // start shim via manager
a.shim = new(shim.Shim) a.shim = new(shim.Shim)
waitErr := make(chan error, 1) waitErr := make(chan error, 1)
if startTime, err := a.shim.Start( if startTime, err := a.shim.Start(
a.seal.sys.user.aid.String(), a.appSeal.sys.user.aid.String(),
a.seal.sys.user.supp, a.appSeal.sys.user.supp,
a.seal.sys.sp, a.appSeal.sys.sp,
); err != nil { ); err != nil {
return err return err
} else { } else {
@ -78,10 +78,10 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
// send payload // send payload
if err = a.shim.Serve(shimSetupCtx, &shim.Payload{ if err = a.shim.Serve(shimSetupCtx, &shim.Payload{
Argv: a.seal.command, Argv: a.appSeal.command,
Exec: shimExec, Exec: shimExec,
Bwrap: a.seal.sys.bwrap, Bwrap: a.appSeal.sys.bwrap,
Home: a.seal.sys.user.data, Home: a.appSeal.sys.user.data,
Verbose: fmsg.Load(), Verbose: fmsg.Load(),
}); err != nil { }); err != nil {
@ -97,10 +97,10 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
// register process state // register process state
var err0 = new(StateStoreError) var err0 = new(StateStoreError)
err0.Inner, err0.DoErr = a.seal.store.Do(a.seal.sys.user.aid.unwrap(), func(c state.Cursor) { err0.Inner, err0.DoErr = a.appSeal.store.Do(a.appSeal.sys.user.aid.unwrap(), func(c state.Cursor) {
err0.InnerErr = c.Save(&sd, a.seal.ct) err0.InnerErr = c.Save(&sd, a.appSeal.ct)
}) })
a.seal.sys.saveState = true a.appSeal.sys.saveState = true
if err = err0.equiv("cannot save process state:"); err != nil { if err = err0.equiv("cannot save process state:"); err != nil {
return err return err
} }
@ -141,16 +141,16 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
fmsg.Resume() fmsg.Resume()
// print queued up dbus messages // print queued up dbus messages
if a.seal.dbusMsg != nil { if a.appSeal.dbusMsg != nil {
a.seal.dbusMsg() a.appSeal.dbusMsg()
} }
// update store and revert app setup transaction // update store and revert app setup transaction
e := new(StateStoreError) e := new(StateStoreError)
e.Inner, e.DoErr = a.seal.store.Do(a.seal.sys.user.aid.unwrap(), func(b state.Cursor) { e.Inner, e.DoErr = a.appSeal.store.Do(a.appSeal.sys.user.aid.unwrap(), func(b state.Cursor) {
e.InnerErr = func() error { e.InnerErr = func() error {
// destroy defunct state entry // destroy defunct state entry
if cmd := a.shim.Unwrap(); cmd != nil && a.seal.sys.saveState { if cmd := a.shim.Unwrap(); cmd != nil && a.appSeal.sys.saveState {
if err := b.Destroy(a.id.unwrap()); err != nil { if err := b.Destroy(a.id.unwrap()); err != nil {
return err return err
} }
@ -198,8 +198,8 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
} }
} }
if a.seal.sys.needRevert { if a.appSeal.sys.needRevert {
if err := a.seal.sys.Revert(ec); err != nil { if err := a.appSeal.sys.Revert(ec); err != nil {
return err.(RevertCompoundError) return err.(RevertCompoundError)
} }
} }
@ -208,7 +208,7 @@ func (a *app) Run(ctx context.Context, rs *fst.RunState) error {
}() }()
}) })
e.Err = a.seal.store.Close() e.Err = a.appSeal.store.Close()
return e.equiv("error returned during cleanup:", e) return e.equiv("error returned during cleanup:", e)
} }