aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-11-04 03:15:39 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-11-04 03:15:39 +0900
commitaf15b1c048e97c092f7a5eeb30f20d13cd972486 (patch)
treec2d9e82655844cbf7130651f3a918b8c8a256f13 /internal
parent7962681f4a9ea0614fe788ca2cda2c697cfff162 (diff)
app: support mapping target uid as privileged uid in sandbox
Chromium's D-Bus client implementation refuses to work when its getuid call returns a different value than what the D-Bus server is running as. The reason behind this is not fully understood, but this workaround is implemented to support chromium and electron apps. This is not used by default since it has many side effects that break many other programs, like SSH on NixOS. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'internal')
-rw-r--r--internal/app/config.go15
-rw-r--r--internal/app/seal.go12
-rw-r--r--internal/app/share.system.go4
-rw-r--r--internal/app/system.go5
4 files changed, 25 insertions, 11 deletions
diff --git a/internal/app/config.go b/internal/app/config.go
index eccb5922..6a25d833 100644
--- a/internal/app/config.go
+++ b/internal/app/config.go
@@ -8,11 +8,6 @@ import (
"git.ophivana.moe/security/fortify/internal/system"
)
-const (
- mappedID = 65534
- mappedIDString = "65534"
-)
-
// Config is used to seal an *App
type Config struct {
// D-Bus application ID
@@ -54,6 +49,8 @@ type SandboxConfig struct {
Net bool `json:"net,omitempty"`
// do not run in new session
NoNewSession bool `json:"no_new_session,omitempty"`
+ // map target user uid to privileged user uid in the user namespace
+ UseRealUID bool `json:"use_real_uid"`
// mediated access to wayland socket
Wayland bool `json:"wayland,omitempty"`
@@ -82,11 +79,15 @@ type FilesystemConfig struct {
// Bwrap returns the address of the corresponding bwrap.Config to s.
// Note that remaining tmpfs entries must be queued by the caller prior to launch.
-func (s *SandboxConfig) Bwrap() *bwrap.Config {
+func (s *SandboxConfig) Bwrap(uid int) *bwrap.Config {
if s == nil {
return nil
}
+ if !s.UseRealUID {
+ uid = 65534
+ }
+
conf := (&bwrap.Config{
Net: s.Net,
UserNS: s.UserNS,
@@ -100,7 +101,7 @@ func (s *SandboxConfig) Bwrap() *bwrap.Config {
// initialise map
Chmod: make(map[string]os.FileMode),
}).
- SetUID(mappedID).SetGID(mappedID).
+ SetUID(uid).SetGID(uid).
Procfs("/proc").DevTmpfs("/dev").Mqueue("/dev/mqueue").
Tmpfs("/dev/fortify", 4*1024)
diff --git a/internal/app/seal.go b/internal/app/seal.go
index 6852ddc6..aaf8a2d6 100644
--- a/internal/app/seal.go
+++ b/internal/app/seal.go
@@ -129,6 +129,15 @@ func (a *app) Seal(config *Config) error {
// create seal system component
seal.sys = new(appSealSys)
+ // mapped uid
+ if config.Confinement.Sandbox != nil && config.Confinement.Sandbox.UseRealUID {
+ seal.sys.mappedID = a.os.Geteuid()
+ } else {
+ seal.sys.mappedID = 65534
+ }
+ seal.sys.mappedIDString = strconv.Itoa(seal.sys.mappedID)
+ seal.sys.runtime = path.Join("/run/user", seal.sys.mappedIDString)
+
// look up user from system
if u, err := a.os.Lookup(config.User); err != nil {
if errors.As(err, new(user.UnknownUserError)) {
@@ -139,7 +148,6 @@ func (a *app) Seal(config *Config) error {
}
} else {
seal.sys.user = u
- seal.sys.runtime = path.Join("/run/user", mappedIDString)
}
// map sandbox config to bwrap
@@ -228,7 +236,7 @@ func (a *app) Seal(config *Config) error {
config.Confinement.Sandbox = conf
}
- seal.sys.bwrap = config.Confinement.Sandbox.Bwrap()
+ seal.sys.bwrap = config.Confinement.Sandbox.Bwrap(a.os.Geteuid())
seal.sys.override = config.Confinement.Sandbox.Override
if seal.sys.bwrap.SetEnv == nil {
seal.sys.bwrap.SetEnv = make(map[string]string)
diff --git a/internal/app/share.system.go b/internal/app/share.system.go
index 26e9b568..08b006c3 100644
--- a/internal/app/share.system.go
+++ b/internal/app/share.system.go
@@ -58,12 +58,12 @@ func (seal *appSeal) sharePasswd(os linux.System) {
homeDir = seal.sys.user.HomeDir
seal.sys.bwrap.SetEnv["HOME"] = seal.sys.user.HomeDir
}
- passwd := username + ":x:" + mappedIDString + ":" + mappedIDString + ":Fortify:" + homeDir + ":" + sh + "\n"
+ passwd := username + ":x:" + seal.sys.mappedIDString + ":" + seal.sys.mappedIDString + ":Fortify:" + homeDir + ":" + sh + "\n"
seal.sys.Write(passwdPath, passwd)
// write /etc/group
groupPath := path.Join(seal.share, "group")
- seal.sys.Write(groupPath, "fortify:x:"+mappedIDString+":\n")
+ seal.sys.Write(groupPath, "fortify:x:"+seal.sys.mappedIDString+":\n")
// bind /etc/passwd and /etc/group
seal.sys.bwrap.Bind(passwdPath, "/etc/passwd")
diff --git a/internal/app/system.go b/internal/app/system.go
index 3c17cf41..47bbd7ed 100644
--- a/internal/app/system.go
+++ b/internal/app/system.go
@@ -20,6 +20,11 @@ type appSealSys struct {
// target user sealed from config
user *user.User
+ // mapped uid and gid in user namespace
+ mappedID int
+ // string representation of mappedID
+ mappedIDString string
+
needRevert bool
saveState bool
*system.I