diff --git a/internal/app/app_test.go b/internal/app/app_test.go index 34313df..96b3670 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -464,7 +464,7 @@ func TestApp(t *testing.T) { } gotSys = system.New(t.Context(), msg, sPriv.uid.unwrap()) - if err := (&outcomeStateSys{config: tc.config, sys: gotSys, outcomeState: &sPriv}).toSystem(); err != nil { + if err := sPriv.newSys(tc.config, gotSys).toSystem(); err != nil { t.Fatalf("toSystem: error = %#v", err) } diff --git a/internal/app/finalise.go b/internal/app/finalise.go index 62b380e..0adfcb4 100644 --- a/internal/app/finalise.go +++ b/internal/app/finalise.go @@ -81,7 +81,7 @@ func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *state.ID, c } sys := system.New(k.ctx, msg, s.uid.unwrap()) - if err := (&outcomeStateSys{config: config, sys: sys, outcomeState: &s}).toSystem(); err != nil { + if err := s.newSys(config, sys).toSystem(); err != nil { return err } diff --git a/internal/app/outcome.go b/internal/app/outcome.go index c5f0fa7..84a4bae 100644 --- a/internal/app/outcome.go +++ b/internal/app/outcome.go @@ -134,7 +134,7 @@ func (s *outcomeState) instancePath() *check.Absolute { return s.sc.SharePath.Ap func (s *outcomeState) runtimePath() *check.Absolute { return s.sc.RunDirPath.Append(s.id.String()) } // outcomeStateSys wraps outcomeState and [system.I]. Used on the priv side only. -// Implementations of outcomeOp must not access fields other than sys and config unless explicitly stated. +// Implementations of outcomeOp must not access fields other than sys unless explicitly stated. type outcomeStateSys struct { // Whether XDG_RUNTIME_DIR is used post hsu. useRuntimeDir bool @@ -142,13 +142,33 @@ type outcomeStateSys struct { sharePath *check.Absolute // Process-specific directory in XDG_RUNTIME_DIR, nil if unused. runtimeSharePath *check.Absolute - // Must not be modified by outcomeOp. - config *hst.Config + + // Copied from [hst.Config]. Safe for read by outcomeOp.toSystem. + appId string + // Copied from [hst.Config]. Safe for read by outcomeOp.toSystem. + et hst.Enablement + + // Copied from [hst.Config]. Safe for read by spWaylandOp.toSystem only. + directWayland bool + // Copied header from [hst.Config]. Safe for read by spFinalOp.toSystem only. + extraPerms []*hst.ExtraPermConfig + // Copied address from [hst.Config. Safe for read by spDBusOp.toSystem only. + sessionBus, systemBus *hst.BusConfig sys *system.I *outcomeState } +// outcomeState returns the address of a new outcomeStateSys embedding the current outcomeState. +func (s *outcomeState) newSys(config *hst.Config, sys *system.I) *outcomeStateSys { + return &outcomeStateSys{ + appId: config.ID, et: config.Enablements.Unwrap(), + directWayland: config.DirectWayland, extraPerms: config.ExtraPerms, + sessionBus: config.SessionBus, systemBus: config.SystemBus, + sys: sys, outcomeState: s, + } +} + // ensureRuntimeDir must be called if access to paths within XDG_RUNTIME_DIR is required. func (state *outcomeStateSys) ensureRuntimeDir() { if state.useRuntimeDir { @@ -245,7 +265,7 @@ func (state *outcomeStateSys) toSystem() error { &spPulseOp{}, &spDBusOp{}, - spFinal{}, + spFinalOp{}, } state.Shim.Ops = make([]outcomeOp, 0, len(ops)) diff --git a/internal/app/spdbus.go b/internal/app/spdbus.go index ac27eeb..604450a 100644 --- a/internal/app/spdbus.go +++ b/internal/app/spdbus.go @@ -19,26 +19,26 @@ type spDBusOp struct { } func (s *spDBusOp) toSystem(state *outcomeStateSys) error { - if state.config.Enablements.Unwrap()&hst.EDBus == 0 { + if state.et&hst.EDBus == 0 { return errNotEnabled } - if state.config.SessionBus == nil { - state.config.SessionBus = dbus.NewConfig(state.config.ID, true, true) + if state.sessionBus == nil { + state.sessionBus = dbus.NewConfig(state.appId, true, true) } // downstream socket paths sessionPath, systemPath := state.instance().Append("bus"), state.instance().Append("system_bus_socket") if err := state.sys.ProxyDBus( - state.config.SessionBus, state.config.SystemBus, + state.sessionBus, state.systemBus, sessionPath, systemPath, ); err != nil { return err } state.sys.UpdatePerm(sessionPath, acl.Read, acl.Write) - if state.config.SystemBus != nil { + if state.systemBus != nil { s.ProxySystem = true state.sys.UpdatePerm(systemPath, acl.Read, acl.Write) } diff --git a/internal/app/spfinal.go b/internal/app/spfinal.go index 8760d09..f67d255 100644 --- a/internal/app/spfinal.go +++ b/internal/app/spfinal.go @@ -13,15 +13,15 @@ import ( "hakurei.app/system/acl" ) -func init() { gob.Register(spFinal{}) } +func init() { gob.Register(spFinalOp{}) } -// spFinal is a transitional op destined for removal after #3, #8, #9 has been resolved. +// spFinalOp is a transitional op destined for removal after #3, #8, #9 has been resolved. // It exists to avoid reordering the expected entries in test cases. -type spFinal struct{} +type spFinalOp struct{} -func (s spFinal) toSystem(state *outcomeStateSys) error { +func (s spFinalOp) toSystem(state *outcomeStateSys) error { // append ExtraPerms last - for _, p := range state.config.ExtraPerms { + for _, p := range state.extraPerms { if p == nil || p.Path == nil { continue } @@ -45,7 +45,7 @@ func (s spFinal) toSystem(state *outcomeStateSys) error { return nil } -func (s spFinal) toContainer(state *outcomeStateParams) error { +func (s spFinalOp) toContainer(state *outcomeStateParams) error { // TODO(ophestra): move this to spFilesystemOp after #8 and #9 // mount root read-only as the final setup Op diff --git a/internal/app/sppulse.go b/internal/app/sppulse.go index 9fc22f6..8a2e753 100644 --- a/internal/app/sppulse.go +++ b/internal/app/sppulse.go @@ -24,7 +24,7 @@ type spPulseOp struct { } func (s *spPulseOp) toSystem(state *outcomeStateSys) error { - if state.config.Enablements.Unwrap()&hst.EPulse == 0 { + if state.et&hst.EPulse == 0 { return errNotEnabled } diff --git a/internal/app/spwayland.go b/internal/app/spwayland.go index 25fc118..5355c32 100644 --- a/internal/app/spwayland.go +++ b/internal/app/spwayland.go @@ -18,7 +18,7 @@ type spWaylandOp struct { } func (s *spWaylandOp) toSystem(state *outcomeStateSys) error { - if state.config.Enablements.Unwrap()&hst.EWayland == 0 { + if state.et&hst.EWayland == 0 { return errNotEnabled } @@ -33,14 +33,14 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error { socketPath = a } - if !state.config.DirectWayland { // set up security-context-v1 - appID := state.config.ID - if appID == "" { + if !state.directWayland { // set up security-context-v1 + appId := state.appId + if appId == "" { // use instance ID in case app id is not set - appID = "app.hakurei." + state.id.String() + appId = "app.hakurei." + state.id.String() } // downstream socket paths - state.sys.Wayland(state.instance().Append("wayland"), socketPath, appID, state.id.String()) + state.sys.Wayland(state.instance().Append("wayland"), socketPath, appId, state.id.String()) } else { // bind mount wayland socket (insecure) state.msg.Verbose("direct wayland access, PROCEED WITH CAUTION") state.ensureRuntimeDir() diff --git a/internal/app/spx11.go b/internal/app/spx11.go index 219f2cb..a597e34 100644 --- a/internal/app/spx11.go +++ b/internal/app/spx11.go @@ -25,7 +25,7 @@ type spX11Op struct { } func (s *spX11Op) toSystem(state *outcomeStateSys) error { - if state.config.Enablements.Unwrap()&hst.EX11 == 0 { + if state.et&hst.EX11 == 0 { return errNotEnabled }