app: move app ID to app struct

App ID is inherent to App, and it makes no sense to generate it as part of the app sealing process.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
Ophestra Umiker 2024-10-20 00:07:48 +09:00
parent 1da845d78b
commit ad0034b09a
Signed by: cat
SSH Key Fingerprint: SHA256:vQhTOP4tHcsFb0365dxe6HJBKpv7PZ0KZNFx2AjBnRI
8 changed files with 38 additions and 29 deletions

View File

@ -7,26 +7,39 @@ import (
) )
type App interface { type App interface {
Seal(config *Config) error // ID returns a copy of App's unique ID.
ID() ID
// Start sets up the system and starts the App.
Start() error Start() error
// Wait waits for App's process to exit and reverts system setup.
Wait() (int, error) Wait() (int, error)
// WaitErr returns error returned by the underlying wait syscall.
WaitErr() error WaitErr() error
Seal(config *Config) error
String() string String() string
} }
type app struct { type app struct {
// application unique identifier
id *ID
// underlying user switcher process
cmd *exec.Cmd
// child process related information // child process related information
seal *appSeal seal *appSeal
// underlying fortified child process
cmd *exec.Cmd
// wayland connection if wayland mediation is enabled // wayland connection if wayland mediation is enabled
wayland *net.UnixConn wayland *net.UnixConn
// error returned waiting for process // error returned waiting for process
wait error waitErr error
lock sync.RWMutex lock sync.RWMutex
} }
func (a *app) ID() ID {
return *a.id
}
func (a *app) String() string { func (a *app) String() string {
if a == nil { if a == nil {
return "(invalid fortified app)" return "(invalid fortified app)"
@ -47,9 +60,11 @@ func (a *app) String() string {
} }
func (a *app) WaitErr() error { func (a *app) WaitErr() error {
return a.wait return a.waitErr
} }
func New() App { func New() (App, error) {
return new(app) a := new(app)
a.id = new(ID)
return a, newAppID(a.id)
} }

View File

@ -5,14 +5,13 @@ import (
"encoding/hex" "encoding/hex"
) )
type appID [16]byte type ID [16]byte
func (a *appID) String() string { func (a *ID) String() string {
return hex.EncodeToString(a[:]) return hex.EncodeToString(a[:])
} }
func newAppID() (*appID, error) { func newAppID(id *ID) error {
a := &appID{} _, err := rand.Read(id[:])
_, err := rand.Read(a[:]) return err
return a, err
} }

View File

@ -53,18 +53,11 @@ func (a *app) Seal(config *Config) error {
// create seal // create seal
seal := new(appSeal) seal := new(appSeal)
// generate application ID
if id, err := newAppID(); err != nil {
return fmsg.WrapErrorSuffix(err,
"cannot generate application ID:")
} else {
seal.id = id
}
// fetch system constants // fetch system constants
seal.SystemConstants = internal.GetSC() seal.SystemConstants = internal.GetSC()
// pass through config values // pass through config values
seal.id = a.id.String()
seal.fid = config.ID seal.fid = config.ID
seal.command = config.Command seal.command = config.Command

View File

@ -32,7 +32,7 @@ func (seal *appSeal) shareRuntime() {
seal.sys.UpdatePermType(system.User, seal.RuntimePath, acl.Execute) seal.sys.UpdatePermType(system.User, seal.RuntimePath, acl.Execute)
// ensure process-specific share local to XDG_RUNTIME_DIR (e.g. `/run/user/%d/fortify/%s`) // ensure process-specific share local to XDG_RUNTIME_DIR (e.g. `/run/user/%d/fortify/%s`)
seal.shareLocal = path.Join(seal.RunDirPath, seal.id.String()) seal.shareLocal = path.Join(seal.RunDirPath, seal.id)
seal.sys.Ephemeral(system.Process, seal.shareLocal, 0700) seal.sys.Ephemeral(system.Process, seal.shareLocal, 0700)
seal.sys.UpdatePerm(seal.shareLocal, acl.Execute) seal.sys.UpdatePerm(seal.shareLocal, acl.Execute)
} }

View File

@ -20,7 +20,7 @@ func (seal *appSeal) shareSystem() {
// ensure process-specific share (e.g. `/tmp/fortify.%d/%s`) // ensure process-specific share (e.g. `/tmp/fortify.%d/%s`)
// acl is unnecessary as this directory is world executable // acl is unnecessary as this directory is world executable
seal.share = path.Join(seal.SharePath, seal.id.String()) seal.share = path.Join(seal.SharePath, seal.id)
seal.sys.Ephemeral(system.Process, seal.share, 0701) seal.sys.Ephemeral(system.Process, seal.share, 0701)
// ensure child tmpdir parent directory (e.g. `/tmp/fortify.%d/tmpdir`) // ensure child tmpdir parent directory (e.g. `/tmp/fortify.%d/tmpdir`)

View File

@ -173,7 +173,7 @@ func (a *app) Wait() (int, error) {
var exitError *exec.ExitError var exitError *exec.ExitError
if !errors.As(err, &exitError) { if !errors.As(err, &exitError) {
// should be unreachable // should be unreachable
a.wait = err a.waitErr = err
} }
// store non-zero return code // store non-zero return code

View File

@ -12,14 +12,14 @@ import (
// appSeal seals the application with child-related information // appSeal seals the application with child-related information
type appSeal struct { type appSeal struct {
// application unique identifier
id *appID
// wayland socket path if mediated wayland is enabled // wayland socket path if mediated wayland is enabled
wl string wl string
// wait for wayland client to exit if mediated wayland is enabled, // wait for wayland client to exit if mediated wayland is enabled,
// (wlDone == nil) determines whether mediated wayland setup is performed // (wlDone == nil) determines whether mediated wayland setup is performed
wlDone chan struct{} wlDone chan struct{}
// app unique ID string representation
id string
// freedesktop application ID // freedesktop application ID
fid string fid string
// argv to start process with in the final confined environment // argv to start process with in the final confined environment

View File

@ -54,8 +54,10 @@ func main() {
// invoke app // invoke app
r := 1 r := 1
a := app.New() a, err := app.New()
if err := a.Seal(loadConfig()); err != nil { if err != nil {
fatalf("cannot create app: %s\n", err)
} else if err = a.Seal(loadConfig()); err != nil {
logBaseError(err, "fortify: cannot seal app:") logBaseError(err, "fortify: cannot seal app:")
} else if err = a.Start(); err != nil { } else if err = a.Start(); err != nil {
logBaseError(err, "fortify: cannot start app:") logBaseError(err, "fortify: cannot start app:")
@ -65,7 +67,7 @@ func main() {
} }
logWaitError(err) logWaitError(err)
} }
if err := a.WaitErr(); err != nil { if err = a.WaitErr(); err != nil {
fmt.Println("fortify: inner wait failed:", err) fmt.Println("fortify: inner wait failed:", err)
} }
os.Exit(r) os.Exit(r)