aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/seal.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-19 01:36:07 +0900
committerOphestra <cat@gensokyo.uk>2025-02-19 01:36:29 +0900
commitdfd94675236844ebcec9ea51f2547ad4fd049357 (patch)
tree16571c77c980054423a5e1a1909251cbd37f13e4 /internal/app/seal.go
parent53571f030e86884bc13fe1d3760ac6bf51d2938b (diff)
app: merge seal with sys
The existence of the appSealSys struct was an implementation detail obsolete since system.I was integrated in 084cd84f36a1d608541b4aa4e1e95334395d8953. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/seal.go')
-rw-r--r--internal/app/seal.go96
1 files changed, 64 insertions, 32 deletions
diff --git a/internal/app/seal.go b/internal/app/seal.go
index 9fce8f2c..251ee2d6 100644
--- a/internal/app/seal.go
+++ b/internal/app/seal.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/fs"
+ "os"
"path"
"regexp"
@@ -42,8 +43,13 @@ type appSeal struct {
appID string
// final argv, passed to init
command []string
- // state instance initialised during seal and used on process lifecycle events
+
+ // state instance initialised during seal; used during process lifecycle events
store state.Store
+ // whether [system.I] was committed; used during process lifecycle events
+ needRevert bool
+ // whether state was inserted into [state.Store]; used during process lifecycle events
+ stateInStore bool
// process-specific share directory path ([os.TempDir])
share string
@@ -57,13 +63,24 @@ type appSeal struct {
// when this gets set no attempt is made to attach security-context-v1
// and the bare socket is mounted to the sandbox
directWayland bool
+ // mount tmpfs over these paths, runs right before extraPerms
+ override []string
// extra [acl.Update] ops, appended at the end of [system.I]
extraPerms []*sealedExtraPerm
+ // post fsu state
+ user appUser
+ // inner XDG_RUNTIME_DIR, default formatting via user
+ innerRuntimeDir string
+ // mapped uid and gid in user namespace
+ mapuid *stringPair[int]
+
+ sys *system.I
+ container *bwrap.Config
+ bwrapSync *os.File
+
// prevents sharing from happening twice
shared bool
- // seal system-level component
- sys *appSealSys
system.Enablements
fst.Paths
@@ -71,6 +88,24 @@ type appSeal struct {
// protected by upstream mutex
}
+// appUser stores post-fsu credentials and metadata
+type appUser struct {
+ // application id
+ aid *stringPair[int]
+ // target uid resolved by fid:aid
+ uid *stringPair[int]
+
+ // supplementary group ids
+ supp []string
+
+ // home directory host path
+ data string
+ // app user home directory
+ home string
+ // passwd database username
+ username string
+}
+
type sealedExtraPerm struct {
name string
perms acl.Perms
@@ -110,9 +145,6 @@ func (a *app) Seal(config *fst.Config) error {
seal.appID = config.ID
seal.command = config.Command
- // create seal system component
- seal.sys = new(appSealSys)
-
{
// mapped uid defaults to 65534 to work around file ownership checks due to a bwrap limitation
mapuid := 65534
@@ -121,8 +153,8 @@ func (a *app) Seal(config *fst.Config) error {
// separate workaround is introduced to map priv-side caller uid in namespace
mapuid = a.sys.Geteuid()
}
- seal.sys.mapuid = newInt(mapuid)
- seal.sys.runtime = path.Join("/run/user", seal.sys.mapuid.String())
+ seal.mapuid = newInt(mapuid)
+ seal.innerRuntimeDir = path.Join("/run/user", seal.mapuid.String())
}
// validate uid and set user info
@@ -130,42 +162,42 @@ func (a *app) Seal(config *fst.Config) error {
return fmsg.WrapError(ErrUser,
fmt.Sprintf("aid %d out of range", config.Confinement.AppID))
}
- seal.sys.user = appUser{
+ seal.user = appUser{
aid: newInt(config.Confinement.AppID),
data: config.Confinement.Outer,
home: config.Confinement.Inner,
username: config.Confinement.Username,
}
- if seal.sys.user.username == "" {
- seal.sys.user.username = "chronos"
- } else if !posixUsername.MatchString(seal.sys.user.username) ||
- len(seal.sys.user.username) >= internal.Sysconf_SC_LOGIN_NAME_MAX() {
+ if seal.user.username == "" {
+ seal.user.username = "chronos"
+ } else if !posixUsername.MatchString(seal.user.username) ||
+ len(seal.user.username) >= internal.Sysconf_SC_LOGIN_NAME_MAX() {
return fmsg.WrapError(ErrName,
- fmt.Sprintf("invalid user name %q", seal.sys.user.username))
+ fmt.Sprintf("invalid user name %q", seal.user.username))
}
- if seal.sys.user.data == "" || !path.IsAbs(seal.sys.user.data) {
+ if seal.user.data == "" || !path.IsAbs(seal.user.data) {
return fmsg.WrapError(ErrHome,
- fmt.Sprintf("invalid home directory %q", seal.sys.user.data))
+ fmt.Sprintf("invalid home directory %q", seal.user.data))
}
- if seal.sys.user.home == "" {
- seal.sys.user.home = seal.sys.user.data
+ if seal.user.home == "" {
+ seal.user.home = seal.user.data
}
// invoke fsu for full uid
- if u, err := a.sys.Uid(seal.sys.user.aid.unwrap()); err != nil {
+ if u, err := a.sys.Uid(seal.user.aid.unwrap()); err != nil {
return err
} else {
- seal.sys.user.uid = newInt(u)
+ seal.user.uid = newInt(u)
}
// resolve supplementary group ids from names
- seal.sys.user.supp = make([]string, len(config.Confinement.Groups))
+ seal.user.supp = make([]string, len(config.Confinement.Groups))
for i, name := range config.Confinement.Groups {
if g, err := a.sys.LookupGroup(name); err != nil {
return fmsg.WrapError(err,
fmt.Sprintf("unknown group %q", name))
} else {
- seal.sys.user.supp[i] = g.Gid
+ seal.user.supp[i] = g.Gid
}
}
@@ -242,11 +274,11 @@ func (a *app) Seal(config *fst.Config) error {
if b, err := config.Confinement.Sandbox.Bwrap(a.sys); err != nil {
return err
} else {
- seal.sys.bwrap = b
+ seal.container = b
}
- seal.sys.override = config.Confinement.Sandbox.Override
- if seal.sys.bwrap.SetEnv == nil {
- seal.sys.bwrap.SetEnv = make(map[string]string)
+ seal.override = config.Confinement.Sandbox.Override
+ if seal.container.SetEnv == nil {
+ seal.container.SetEnv = make(map[string]string)
}
// open process state store
@@ -255,11 +287,11 @@ func (a *app) Seal(config *fst.Config) error {
seal.store = state.NewMulti(seal.RunDirPath)
// initialise system interface with os uid
- seal.sys.I = system.New(seal.sys.user.uid.unwrap())
- seal.sys.I.IsVerbose = fmsg.Load
- seal.sys.I.Verbose = fmsg.Verbose
- seal.sys.I.Verbosef = fmsg.Verbosef
- seal.sys.I.WrapErr = fmsg.WrapError
+ seal.sys = system.New(seal.user.uid.unwrap())
+ seal.sys.IsVerbose = fmsg.Load
+ seal.sys.Verbose = fmsg.Verbose
+ seal.sys.Verbosef = fmsg.Verbosef
+ seal.sys.WrapErr = fmsg.WrapError
// pass through enablements
seal.Enablements = config.Confinement.Enablements
@@ -271,7 +303,7 @@ func (a *app) Seal(config *fst.Config) error {
// verbose log seal information
fmsg.Verbosef("created application seal for uid %s (%s) groups: %v, command: %s",
- seal.sys.user.uid, seal.sys.user.username, config.Confinement.Groups, config.Command)
+ seal.user.uid, seal.user.username, config.Confinement.Groups, config.Command)
// seal app and release lock
a.appSeal = seal