app: embed appSeal in app struct
Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
aa164081e1
commit
53571f030e
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user