aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-10-20 22:54:47 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-10-21 18:46:06 +0900
commit380d1f45851b7dffb963c51da96a17ba41f3cfb8 (patch)
tree984c9b50d890157847e3f3bc942659e6431c03a9 /internal/app
parent133f23e0de77dc32de2753b23ed8173344a0e699 (diff)
app: move wayland mediation to shim package
Values used in the Wayland mediation implementation is stored in various struct fields strewn across multiple app structs and checks are messy and confusing. This commit unifies them into a single struct and access it using much better looking methods. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'internal/app')
-rw-r--r--internal/app/app.go4
-rw-r--r--internal/app/seal.go44
-rw-r--r--internal/app/share.display.go6
-rw-r--r--internal/app/start.go19
-rw-r--r--internal/app/system.go42
5 files changed, 51 insertions, 64 deletions
diff --git a/internal/app/app.go b/internal/app/app.go
index 4c3a60c3..5c5e3452 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -1,7 +1,6 @@
package app
import (
- "net"
"os/exec"
"sync"
)
@@ -27,9 +26,6 @@ type app struct {
cmd *exec.Cmd
// child process related information
seal *appSeal
-
- // wayland connection if wayland mediation is enabled
- wayland *net.UnixConn
// error returned waiting for process
waitErr error
diff --git a/internal/app/seal.go b/internal/app/seal.go
index d4b4efa7..7de6aecb 100644
--- a/internal/app/seal.go
+++ b/internal/app/seal.go
@@ -11,6 +11,7 @@ import (
"git.ophivana.moe/security/fortify/dbus"
"git.ophivana.moe/security/fortify/internal"
"git.ophivana.moe/security/fortify/internal/fmsg"
+ "git.ophivana.moe/security/fortify/internal/shim"
"git.ophivana.moe/security/fortify/internal/state"
"git.ophivana.moe/security/fortify/internal/system"
"git.ophivana.moe/security/fortify/internal/verbose"
@@ -36,6 +37,43 @@ var (
ErrMachineCtl = errors.New("machinectl not available")
)
+// appSeal seals the application with child-related information
+type appSeal struct {
+ // app unique ID string representation
+ id string
+ // wayland mediation, disabled if nil
+ wl *shim.Wayland
+
+ // freedesktop application ID
+ fid string
+ // argv to start process with in the final confined environment
+ command []string
+ // persistent process state store
+ store state.Store
+
+ // uint8 representation of launch method sealed from config
+ launchOption uint8
+ // process-specific share directory path
+ share string
+ // process-specific share directory path local to XDG_RUNTIME_DIR
+ shareLocal string
+
+ // path to launcher program
+ toolPath string
+ // pass-through enablement tracking from config
+ et system.Enablements
+
+ // prevents sharing from happening twice
+ shared bool
+ // seal system-level component
+ sys *appSealSys
+
+ // used in various sealing operations
+ internal.SystemConstants
+
+ // protected by upstream mutex
+}
+
// Seal seals the app launch context
func (a *app) Seal(config *Config) error {
a.lock.Lock()
@@ -176,10 +214,10 @@ func (a *app) Seal(config *Config) error {
seal.sys.bwrap.SetEnv = make(map[string]string)
}
- // create wayland client wait channel if mediated wayland is enabled
- // this channel being set enables mediated wayland setup later on
+ // create wayland struct and client wait channel if mediated wayland is enabled
+ // this field being set enables mediated wayland setup later on
if config.Confinement.Sandbox.Wayland {
- seal.wlDone = make(chan struct{})
+ seal.wl = shim.NewWayland()
}
// open process state store
diff --git a/internal/app/share.display.go b/internal/app/share.display.go
index 7c50b636..18fad7a7 100644
--- a/internal/app/share.display.go
+++ b/internal/app/share.display.go
@@ -34,7 +34,7 @@ func (seal *appSeal) shareDisplay() error {
if wd, ok := os.LookupEnv(waylandDisplay); !ok {
return fmsg.WrapError(ErrWayland,
"WAYLAND_DISPLAY is not set")
- } else if seal.wlDone == nil {
+ } else if seal.wl == nil {
// hardlink wayland socket
wp := path.Join(seal.RuntimePath, wd)
wpi := path.Join(seal.shareLocal, "wayland")
@@ -46,8 +46,8 @@ func (seal *appSeal) shareDisplay() error {
// ensure Wayland socket ACL (e.g. `/run/user/%d/wayland-%d`)
seal.sys.UpdatePermType(system.EWayland, wp, acl.Read, acl.Write, acl.Execute)
} else {
- // set wayland socket path (e.g. `/run/user/%d/wayland-%d`)
- seal.wl = path.Join(seal.RuntimePath, wd)
+ // set wayland socket path for mediation (e.g. `/run/user/%d/wayland-%d`)
+ seal.wl.Path = path.Join(seal.RuntimePath, wd)
}
}
diff --git a/internal/app/start.go b/internal/app/start.go
index 6d301028..3106a1e8 100644
--- a/internal/app/start.go
+++ b/internal/app/start.go
@@ -62,23 +62,19 @@ func (a *app) Start() error {
confSockPath := path.Join(a.seal.share, "shim")
a.cmd = exec.Command(a.seal.toolPath, commandBuilder(shim.EnvShim+"="+confSockPath)...)
a.cmd.Env = []string{}
- a.cmd.Stdin = os.Stdin
- a.cmd.Stdout = os.Stdout
- a.cmd.Stderr = os.Stderr
+ a.cmd.Stdin, a.cmd.Stdout, a.cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
a.cmd.Dir = a.seal.RunDirPath
- if wls, err := shim.ServeConfig(confSockPath, a.seal.sys.UID(), &shim.Payload{
+ if err := shim.ServeConfig(confSockPath, a.seal.sys.UID(), &shim.Payload{
Argv: a.seal.command,
Exec: shimExec,
Bwrap: a.seal.sys.bwrap,
- WL: a.seal.wlDone != nil,
+ WL: a.seal.wl != nil,
Verbose: verbose.Get(),
- }, a.seal.wl, a.seal.wlDone); err != nil {
+ }, a.seal.wl); err != nil {
return fmsg.WrapErrorSuffix(err,
- "cannot listen on shim socket:")
- } else {
- a.wayland = wls
+ "cannot serve shim setup:")
}
// start shim
@@ -185,9 +181,8 @@ func (a *app) Wait() (int, error) {
verbose.Println("process", strconv.Itoa(a.cmd.Process.Pid), "exited with exit code", r)
// close wayland connection
- if a.wayland != nil {
- close(a.seal.wlDone)
- if err := a.wayland.Close(); err != nil {
+ if a.seal.wl != nil {
+ if err := a.seal.wl.Close(); err != nil {
fmt.Println("fortify: cannot close wayland connection:", err)
}
}
diff --git a/internal/app/system.go b/internal/app/system.go
index 834bdc91..2fc413e7 100644
--- a/internal/app/system.go
+++ b/internal/app/system.go
@@ -5,51 +5,9 @@ import (
"git.ophivana.moe/security/fortify/dbus"
"git.ophivana.moe/security/fortify/helper/bwrap"
- "git.ophivana.moe/security/fortify/internal"
- "git.ophivana.moe/security/fortify/internal/state"
"git.ophivana.moe/security/fortify/internal/system"
)
-// appSeal seals the application with child-related information
-type appSeal struct {
- // wayland socket path if mediated wayland is enabled
- wl string
- // wait for wayland client to exit if mediated wayland is enabled,
- // (wlDone == nil) determines whether mediated wayland setup is performed
- wlDone chan struct{}
-
- // app unique ID string representation
- id string
- // freedesktop application ID
- fid string
- // argv to start process with in the final confined environment
- command []string
- // persistent process state store
- store state.Store
-
- // uint8 representation of launch method sealed from config
- launchOption uint8
- // process-specific share directory path
- share string
- // process-specific share directory path local to XDG_RUNTIME_DIR
- shareLocal string
-
- // path to launcher program
- toolPath string
- // pass-through enablement tracking from config
- et system.Enablements
-
- // prevents sharing from happening twice
- shared bool
- // seal system-level component
- sys *appSealSys
-
- // used in various sealing operations
- internal.SystemConstants
-
- // protected by upstream mutex
-}
-
// appSealSys encapsulates app seal behaviour with OS interactions
type appSealSys struct {
bwrap *bwrap.Config