diff options
| author | Ophestra <cat@gensokyo.uk> | 2024-12-28 13:23:27 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2024-12-28 13:23:27 +0900 |
| commit | 847b667489e661d0e59240d64614a33392d94e0d (patch) | |
| tree | 88f7f068d762b3cf9f6198de03b4f3e3277dfea3 /internal | |
| parent | c70f0612ad32f9ba5dc4ecf793aa4553929372d4 (diff) | |
app: extra acl entries from configuration
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/app/seal.go | 98 | ||||
| -rw-r--r-- | internal/app/share.go | 8 |
2 files changed, 71 insertions, 35 deletions
diff --git a/internal/app/seal.go b/internal/app/seal.go index 87e62b36..82b7983e 100644 --- a/internal/app/seal.go +++ b/internal/app/seal.go @@ -8,6 +8,7 @@ import ( "regexp" "strconv" + "git.gensokyo.uk/security/fortify/acl" "git.gensokyo.uk/security/fortify/dbus" "git.gensokyo.uk/security/fortify/fst" "git.gensokyo.uk/security/fortify/internal/fmsg" @@ -48,6 +49,8 @@ type appSeal struct { et system.Enablements // wayland socket direct access directWayland bool + // extra UpdatePerm ops + extraPerms []*sealedExtraPerm // prevents sharing from happening twice shared bool @@ -59,6 +62,11 @@ type appSeal struct { // protected by upstream mutex } +type sealedExtraPerm struct { + name string + perms acl.Perms +} + // Seal seals the app launch context func (a *app) Seal(config *fst.Config) error { a.lock.Lock() @@ -100,46 +108,66 @@ func (a *app) Seal(config *fst.Config) error { if config.Confinement.AppID < 0 || config.Confinement.AppID > 9999 { return fmsg.WrapError(ErrUser, fmt.Sprintf("aid %d out of range", config.Confinement.AppID)) + } + seal.sys.user = appUser{ + aid: config.Confinement.AppID, + as: strconv.Itoa(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) { + return fmsg.WrapError(ErrName, + fmt.Sprintf("invalid user name %q", seal.sys.user.username)) + } + if seal.sys.user.data == "" || !path.IsAbs(seal.sys.user.data) { + return fmsg.WrapError(ErrHome, + fmt.Sprintf("invalid home directory %q", seal.sys.user.data)) + } + if seal.sys.user.home == "" { + seal.sys.user.home = seal.sys.user.data + } + + // invoke fsu for full uid + if u, err := a.os.Uid(seal.sys.user.aid); err != nil { + return fmsg.WrapErrorSuffix(err, + "cannot obtain uid from fsu:") } else { - seal.sys.user = appUser{ - aid: config.Confinement.AppID, - as: strconv.Itoa(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) { - return fmsg.WrapError(ErrName, - fmt.Sprintf("invalid user name %q", seal.sys.user.username)) - } - if seal.sys.user.data == "" || !path.IsAbs(seal.sys.user.data) { - return fmsg.WrapError(ErrHome, - fmt.Sprintf("invalid home directory %q", seal.sys.user.data)) - } - if seal.sys.user.home == "" { - seal.sys.user.home = seal.sys.user.data - } + seal.sys.user.uid = u + seal.sys.user.us = strconv.Itoa(u) + } - // invoke fsu for full uid - if u, err := a.os.Uid(seal.sys.user.aid); err != nil { - return fmsg.WrapErrorSuffix(err, - "cannot obtain uid from fsu:") + // resolve supplementary group ids from names + seal.sys.user.supp = make([]string, len(config.Confinement.Groups)) + for i, name := range config.Confinement.Groups { + if g, err := a.os.LookupGroup(name); err != nil { + return fmsg.WrapError(err, + fmt.Sprintf("unknown group %q", name)) } else { - seal.sys.user.uid = u - seal.sys.user.us = strconv.Itoa(u) + seal.sys.user.supp[i] = g.Gid } + } - // resolve supplementary group ids from names - seal.sys.user.supp = make([]string, len(config.Confinement.Groups)) - for i, name := range config.Confinement.Groups { - if g, err := a.os.LookupGroup(name); err != nil { - return fmsg.WrapError(err, - fmt.Sprintf("unknown group %q", name)) - } else { - seal.sys.user.supp[i] = g.Gid - } + // build extra perms + seal.extraPerms = make([]*sealedExtraPerm, len(config.Confinement.ExtraPerms)) + for i, p := range config.Confinement.ExtraPerms { + if p == nil { + continue + } + + seal.extraPerms[i] = new(sealedExtraPerm) + seal.extraPerms[i].name = p.Path + seal.extraPerms[i].perms = make(acl.Perms, 0, 3) + if p.Read { + seal.extraPerms[i].perms = append(seal.extraPerms[i].perms, acl.Read) + } + if p.Write { + seal.extraPerms[i].perms = append(seal.extraPerms[i].perms, acl.Write) + } + if p.Execute { + seal.extraPerms[i].perms = append(seal.extraPerms[i].perms, acl.Execute) } } diff --git a/internal/app/share.go b/internal/app/share.go index dea55a87..0a18e310 100644 --- a/internal/app/share.go +++ b/internal/app/share.go @@ -292,6 +292,14 @@ func (seal *appSeal) setupShares(bus [2]*dbus.Config, os linux.System) error { seal.sys.bwrap.Tmpfs(dest, 8*1024) } + // append extra perms + for _, p := range seal.extraPerms { + if p == nil { + continue + } + seal.sys.UpdatePermType(system.User, p.name, p.perms...) + } + return nil } |
