hst/container: pack boolean options
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m12s
Test / Hakurei (push) Successful in 3m8s
Test / Hpkg (push) Successful in 4m2s
Test / Hakurei (race detector) (push) Successful in 4m46s
Test / Sandbox (race detector) (push) Successful in 2m11s
Test / Flake checks (push) Successful in 1m37s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m12s
Test / Hakurei (push) Successful in 3m8s
Test / Hpkg (push) Successful in 4m2s
Test / Hakurei (race detector) (push) Successful in 4m46s
Test / Sandbox (race detector) (push) Successful in 2m11s
Test / Flake checks (push) Successful in 1m37s
The memory saving is relatively insignificant, however this increases serialisation efficiency. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
a341466942
commit
4c647add0d
@ -147,11 +147,6 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
|||||||
Enablements: hst.NewEnablements(et),
|
Enablements: hst.NewEnablements(et),
|
||||||
|
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Userns: true,
|
|
||||||
HostNet: true,
|
|
||||||
Tty: true,
|
|
||||||
HostAbstract: true,
|
|
||||||
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
// autoroot, includes the home directory
|
// autoroot, includes the home directory
|
||||||
{FilesystemConfig: &hst.FSBind{
|
{FilesystemConfig: &hst.FSBind{
|
||||||
@ -167,6 +162,8 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
|||||||
|
|
||||||
Path: progPath,
|
Path: progPath,
|
||||||
Args: args,
|
Args: args,
|
||||||
|
|
||||||
|
Flags: hst.FUserns | hst.FHostNet | hst.FHostAbstract | hst.FTty,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,19 +87,19 @@ func printShowInstance(
|
|||||||
t.Printf(" Hostname:\t%s\n", params.Hostname)
|
t.Printf(" Hostname:\t%s\n", params.Hostname)
|
||||||
}
|
}
|
||||||
flags := make([]string, 0, 7)
|
flags := make([]string, 0, 7)
|
||||||
writeFlag := func(name string, value bool) {
|
writeFlag := func(name string, flag uintptr, force bool) {
|
||||||
if value {
|
if params.Flags&flag != 0 || force {
|
||||||
flags = append(flags, name)
|
flags = append(flags, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeFlag("userns", params.Userns)
|
writeFlag("userns", hst.FUserns, false)
|
||||||
writeFlag("devel", params.Devel)
|
writeFlag("devel", hst.FDevel, false)
|
||||||
writeFlag("net", params.HostNet)
|
writeFlag("net", hst.FHostNet, false)
|
||||||
writeFlag("abstract", params.HostAbstract)
|
writeFlag("abstract", hst.FHostAbstract, false)
|
||||||
writeFlag("device", params.Device)
|
writeFlag("device", hst.FDevice, false)
|
||||||
writeFlag("tty", params.Tty)
|
writeFlag("tty", hst.FTty, false)
|
||||||
writeFlag("mapuid", params.MapRealUID)
|
writeFlag("mapuid", hst.FMapRealUID, false)
|
||||||
writeFlag("directwl", config.DirectWayland)
|
writeFlag("directwl", 0, config.DirectWayland)
|
||||||
if len(flags) == 0 {
|
if len(flags) == 0 {
|
||||||
flags = append(flags, "none")
|
flags = append(flags, "none")
|
||||||
}
|
}
|
||||||
|
@ -252,20 +252,11 @@ App
|
|||||||
"container": {
|
"container": {
|
||||||
"hostname": "localhost",
|
"hostname": "localhost",
|
||||||
"wait_delay": -1,
|
"wait_delay": -1,
|
||||||
"seccomp_compat": true,
|
|
||||||
"devel": true,
|
|
||||||
"userns": true,
|
|
||||||
"host_net": true,
|
|
||||||
"host_abstract": true,
|
|
||||||
"tty": true,
|
|
||||||
"multiarch": true,
|
|
||||||
"env": {
|
"env": {
|
||||||
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
||||||
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
||||||
},
|
},
|
||||||
"map_real_uid": true,
|
|
||||||
"device": true,
|
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
@ -331,7 +322,16 @@ App
|
|||||||
"--disable-smooth-scrolling",
|
"--disable-smooth-scrolling",
|
||||||
"--enable-features=UseOzonePlatform",
|
"--enable-features=UseOzonePlatform",
|
||||||
"--ozone-platform=wayland"
|
"--ozone-platform=wayland"
|
||||||
]
|
],
|
||||||
|
"seccomp_compat": true,
|
||||||
|
"devel": true,
|
||||||
|
"userns": true,
|
||||||
|
"host_net": true,
|
||||||
|
"host_abstract": true,
|
||||||
|
"tty": true,
|
||||||
|
"multiarch": true,
|
||||||
|
"map_real_uid": true,
|
||||||
|
"device": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"time": "1970-01-01T00:00:00.000000009Z"
|
"time": "1970-01-01T00:00:00.000000009Z"
|
||||||
@ -402,20 +402,11 @@ App
|
|||||||
"container": {
|
"container": {
|
||||||
"hostname": "localhost",
|
"hostname": "localhost",
|
||||||
"wait_delay": -1,
|
"wait_delay": -1,
|
||||||
"seccomp_compat": true,
|
|
||||||
"devel": true,
|
|
||||||
"userns": true,
|
|
||||||
"host_net": true,
|
|
||||||
"host_abstract": true,
|
|
||||||
"tty": true,
|
|
||||||
"multiarch": true,
|
|
||||||
"env": {
|
"env": {
|
||||||
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
||||||
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
||||||
},
|
},
|
||||||
"map_real_uid": true,
|
|
||||||
"device": true,
|
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
@ -481,7 +472,16 @@ App
|
|||||||
"--disable-smooth-scrolling",
|
"--disable-smooth-scrolling",
|
||||||
"--enable-features=UseOzonePlatform",
|
"--enable-features=UseOzonePlatform",
|
||||||
"--ozone-platform=wayland"
|
"--ozone-platform=wayland"
|
||||||
]
|
],
|
||||||
|
"seccomp_compat": true,
|
||||||
|
"devel": true,
|
||||||
|
"userns": true,
|
||||||
|
"host_net": true,
|
||||||
|
"host_abstract": true,
|
||||||
|
"tty": true,
|
||||||
|
"multiarch": true,
|
||||||
|
"map_real_uid": true,
|
||||||
|
"device": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, true},
|
`, true},
|
||||||
@ -612,20 +612,11 @@ func TestPrintPs(t *testing.T) {
|
|||||||
"container": {
|
"container": {
|
||||||
"hostname": "localhost",
|
"hostname": "localhost",
|
||||||
"wait_delay": -1,
|
"wait_delay": -1,
|
||||||
"seccomp_compat": true,
|
|
||||||
"devel": true,
|
|
||||||
"userns": true,
|
|
||||||
"host_net": true,
|
|
||||||
"host_abstract": true,
|
|
||||||
"tty": true,
|
|
||||||
"multiarch": true,
|
|
||||||
"env": {
|
"env": {
|
||||||
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
||||||
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
||||||
},
|
},
|
||||||
"map_real_uid": true,
|
|
||||||
"device": true,
|
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
@ -691,7 +682,16 @@ func TestPrintPs(t *testing.T) {
|
|||||||
"--disable-smooth-scrolling",
|
"--disable-smooth-scrolling",
|
||||||
"--enable-features=UseOzonePlatform",
|
"--enable-features=UseOzonePlatform",
|
||||||
"--ozone-platform=wayland"
|
"--ozone-platform=wayland"
|
||||||
]
|
],
|
||||||
|
"seccomp_compat": true,
|
||||||
|
"devel": true,
|
||||||
|
"userns": true,
|
||||||
|
"host_net": true,
|
||||||
|
"host_abstract": true,
|
||||||
|
"tty": true,
|
||||||
|
"multiarch": true,
|
||||||
|
"map_real_uid": true,
|
||||||
|
"device": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"time": "1970-01-01T00:00:00.000000009Z"
|
"time": "1970-01-01T00:00:00.000000009Z"
|
||||||
|
@ -76,15 +76,7 @@ func (app *appInfo) toHst(pathSet *appPathSet, pathname *check.Absolute, argv []
|
|||||||
Groups: app.Groups,
|
Groups: app.Groups,
|
||||||
|
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Hostname: formatHostname(app.Name),
|
Hostname: formatHostname(app.Name),
|
||||||
Devel: app.Devel,
|
|
||||||
Userns: app.Userns,
|
|
||||||
HostNet: app.HostNet,
|
|
||||||
HostAbstract: app.HostAbstract,
|
|
||||||
Device: app.Device,
|
|
||||||
Tty: app.Tty || flagDropShell,
|
|
||||||
MapRealUID: app.MapRealUID,
|
|
||||||
Multiarch: app.Multiarch,
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: pathSet.cacheDir.Append("etc"), Special: true}},
|
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: pathSet.cacheDir.Append("etc"), Special: true}},
|
||||||
{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath.Append("store"), Target: pathNixStore}},
|
{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath.Append("store"), Target: pathNixStore}},
|
||||||
@ -113,6 +105,31 @@ func (app *appInfo) toHst(pathSet *appPathSet, pathname *check.Absolute, argv []
|
|||||||
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if app.Devel {
|
||||||
|
config.Container.Flags |= hst.FDevel
|
||||||
|
}
|
||||||
|
if app.Userns {
|
||||||
|
config.Container.Flags |= hst.FUserns
|
||||||
|
}
|
||||||
|
if app.HostNet {
|
||||||
|
config.Container.Flags |= hst.FHostNet
|
||||||
|
}
|
||||||
|
if app.HostAbstract {
|
||||||
|
config.Container.Flags |= hst.FHostAbstract
|
||||||
|
}
|
||||||
|
if app.Device {
|
||||||
|
config.Container.Flags |= hst.FDevice
|
||||||
|
}
|
||||||
|
if app.Tty || flagDropShell {
|
||||||
|
config.Container.Flags |= hst.FTty
|
||||||
|
}
|
||||||
|
if app.MapRealUID {
|
||||||
|
config.Container.Flags |= hst.FMapRealUID
|
||||||
|
}
|
||||||
|
if app.Multiarch {
|
||||||
|
config.Container.Flags |= hst.FMultiarch
|
||||||
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,14 @@ func withNixDaemon(
|
|||||||
action string, command []string, net bool, updateConfig func(config *hst.Config) *hst.Config,
|
action string, command []string, net bool, updateConfig func(config *hst.Config) *hst.Config,
|
||||||
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func(),
|
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func(),
|
||||||
) {
|
) {
|
||||||
|
flags := hst.FMultiarch | hst.FUserns // nix sandbox requires userns
|
||||||
|
if net {
|
||||||
|
flags |= hst.FHostNet
|
||||||
|
}
|
||||||
|
if dropShell {
|
||||||
|
flags |= hst.FTty
|
||||||
|
}
|
||||||
|
|
||||||
mustRunAppDropShell(ctx, msg, updateConfig(&hst.Config{
|
mustRunAppDropShell(ctx, msg, updateConfig(&hst.Config{
|
||||||
ID: app.ID,
|
ID: app.ID,
|
||||||
|
|
||||||
@ -28,11 +36,8 @@ func withNixDaemon(
|
|||||||
Identity: app.Identity,
|
Identity: app.Identity,
|
||||||
|
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Hostname: formatHostname(app.Name) + "-" + action,
|
Hostname: formatHostname(app.Name) + "-" + action,
|
||||||
Userns: true, // nix sandbox requires userns
|
|
||||||
HostNet: net,
|
|
||||||
Multiarch: true,
|
|
||||||
Tty: dropShell,
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: pathSet.cacheDir.Append("etc"), Special: true}},
|
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: pathSet.cacheDir.Append("etc"), Special: true}},
|
||||||
{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath, Target: pathNix, Write: true}},
|
{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath, Target: pathNix, Write: true}},
|
||||||
@ -58,6 +63,8 @@ func withNixDaemon(
|
|||||||
// terminate nix-daemon
|
// terminate nix-daemon
|
||||||
" && pkill nix-daemon",
|
" && pkill nix-daemon",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Flags: flags,
|
||||||
},
|
},
|
||||||
}), dropShell, beforeFail)
|
}), dropShell, beforeFail)
|
||||||
}
|
}
|
||||||
@ -66,7 +73,13 @@ func withCacheDir(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
msg message.Msg,
|
msg message.Msg,
|
||||||
action string, command []string, workDir *check.Absolute,
|
action string, command []string, workDir *check.Absolute,
|
||||||
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func()) {
|
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func(),
|
||||||
|
) {
|
||||||
|
flags := hst.FMultiarch
|
||||||
|
if dropShell {
|
||||||
|
flags |= hst.FTty
|
||||||
|
}
|
||||||
|
|
||||||
mustRunAppDropShell(ctx, msg, &hst.Config{
|
mustRunAppDropShell(ctx, msg, &hst.Config{
|
||||||
ID: app.ID,
|
ID: app.ID,
|
||||||
|
|
||||||
@ -79,9 +92,8 @@ func withCacheDir(
|
|||||||
Identity: app.Identity,
|
Identity: app.Identity,
|
||||||
|
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Hostname: formatHostname(app.Name) + "-" + action,
|
Hostname: formatHostname(app.Name) + "-" + action,
|
||||||
Multiarch: true,
|
|
||||||
Tty: dropShell,
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: workDir.Append(fhs.Etc), Special: true}},
|
{FilesystemConfig: &hst.FSBind{Target: fhs.AbsEtc, Source: workDir.Append(fhs.Etc), Special: true}},
|
||||||
{FilesystemConfig: &hst.FSBind{Source: workDir.Append("nix"), Target: pathNix}},
|
{FilesystemConfig: &hst.FSBind{Source: workDir.Append("nix"), Target: pathNix}},
|
||||||
@ -98,6 +110,8 @@ func withCacheDir(
|
|||||||
|
|
||||||
Path: pathShell,
|
Path: pathShell,
|
||||||
Args: []string{bash, "-lc", strings.Join(command, " && ")},
|
Args: []string{bash, "-lc", strings.Join(command, " && ")},
|
||||||
|
|
||||||
|
Flags: flags,
|
||||||
},
|
},
|
||||||
}, dropShell, beforeFail)
|
}, dropShell, beforeFail)
|
||||||
}
|
}
|
||||||
|
151
hst/container.go
151
hst/container.go
@ -1,6 +1,8 @@
|
|||||||
package hst
|
package hst
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
@ -29,6 +31,37 @@ const (
|
|||||||
ShimExitOrphan = 3
|
ShimExitOrphan = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// FMultiarch unblocks syscalls required for multiarch to work on applicable targets.
|
||||||
|
FMultiarch uintptr = 1 << iota
|
||||||
|
|
||||||
|
// FSeccompCompat causes emitted seccomp filter programs to be identical to Flatpak.
|
||||||
|
FSeccompCompat
|
||||||
|
// FDevel unblocks ptrace and friends.
|
||||||
|
FDevel
|
||||||
|
// FUserns unblocks userns creation and container setup syscalls.
|
||||||
|
FUserns
|
||||||
|
// FHostNet skips net namespace creation.
|
||||||
|
FHostNet
|
||||||
|
// FHostAbstract skips setting up abstract unix socket scope.
|
||||||
|
FHostAbstract
|
||||||
|
// FTty unblocks dangerous terminal I/O (faking input).
|
||||||
|
FTty
|
||||||
|
|
||||||
|
// FMapRealUID maps the target user uid to the privileged user uid in the container user namespace.
|
||||||
|
// Some programs fail to connect to dbus session running as a different uid,
|
||||||
|
// this option works around it by mapping priv-side caller uid in container.
|
||||||
|
FMapRealUID
|
||||||
|
|
||||||
|
// FDevice mount /dev/ from the init mount namespace as-is in the container mount namespace.
|
||||||
|
FDevice
|
||||||
|
|
||||||
|
fMax
|
||||||
|
|
||||||
|
// FAll is [ContainerConfig.Flags] with all currently defined bits set.
|
||||||
|
FAll = fMax - 1
|
||||||
|
)
|
||||||
|
|
||||||
// ContainerConfig describes the container configuration to be applied to an underlying [container].
|
// ContainerConfig describes the container configuration to be applied to an underlying [container].
|
||||||
type ContainerConfig struct {
|
type ContainerConfig struct {
|
||||||
// Container UTS namespace hostname.
|
// Container UTS namespace hostname.
|
||||||
@ -39,33 +72,9 @@ type ContainerConfig struct {
|
|||||||
// Values lesser than zero is equivalent to zero, bypassing [WaitDelayDefault].
|
// Values lesser than zero is equivalent to zero, bypassing [WaitDelayDefault].
|
||||||
WaitDelay time.Duration `json:"wait_delay,omitempty"`
|
WaitDelay time.Duration `json:"wait_delay,omitempty"`
|
||||||
|
|
||||||
// Emit Flatpak-compatible seccomp filter programs.
|
|
||||||
SeccompCompat bool `json:"seccomp_compat,omitempty"`
|
|
||||||
// Allow ptrace and friends.
|
|
||||||
Devel bool `json:"devel,omitempty"`
|
|
||||||
// Allow userns creation and container setup syscalls.
|
|
||||||
Userns bool `json:"userns,omitempty"`
|
|
||||||
// Share host net namespace.
|
|
||||||
HostNet bool `json:"host_net,omitempty"`
|
|
||||||
// Share abstract unix socket scope.
|
|
||||||
HostAbstract bool `json:"host_abstract,omitempty"`
|
|
||||||
// Allow dangerous terminal I/O (faking input).
|
|
||||||
Tty bool `json:"tty,omitempty"`
|
|
||||||
// Allow multiarch.
|
|
||||||
Multiarch bool `json:"multiarch,omitempty"`
|
|
||||||
|
|
||||||
// Initial process environment variables.
|
// Initial process environment variables.
|
||||||
Env map[string]string `json:"env"`
|
Env map[string]string `json:"env"`
|
||||||
|
|
||||||
/* Map target user uid to privileged user uid in the container user namespace.
|
|
||||||
|
|
||||||
Some programs fail to connect to dbus session running as a different uid,
|
|
||||||
this option works around it by mapping priv-side caller uid in container. */
|
|
||||||
MapRealUID bool `json:"map_real_uid"`
|
|
||||||
|
|
||||||
// Mount /dev/ from the init mount namespace as-is in the container mount namespace.
|
|
||||||
Device bool `json:"device,omitempty"`
|
|
||||||
|
|
||||||
/* Container mount points.
|
/* Container mount points.
|
||||||
|
|
||||||
If the first element targets /, it is inserted early and excluded from path hiding. */
|
If the first element targets /, it is inserted early and excluded from path hiding. */
|
||||||
@ -83,4 +92,98 @@ type ContainerConfig struct {
|
|||||||
Path *check.Absolute `json:"path,omitempty"`
|
Path *check.Absolute `json:"path,omitempty"`
|
||||||
// Final args passed to the initial program.
|
// Final args passed to the initial program.
|
||||||
Args []string `json:"args"`
|
Args []string `json:"args"`
|
||||||
|
|
||||||
|
// Flags holds boolean options of [ContainerConfig].
|
||||||
|
Flags uintptr `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerConfigF is [ContainerConfig] stripped of its methods.
|
||||||
|
// The [ContainerConfig.Flags] field does not survive a [json] round trip.
|
||||||
|
type ContainerConfigF ContainerConfig
|
||||||
|
|
||||||
|
// containerConfigJSON is the [json] representation of [ContainerConfig].
|
||||||
|
type containerConfigJSON = struct {
|
||||||
|
*ContainerConfigF
|
||||||
|
|
||||||
|
// Corresponds to [FSeccompCompat].
|
||||||
|
SeccompCompat bool `json:"seccomp_compat,omitempty"`
|
||||||
|
// Corresponds to [FDevel].
|
||||||
|
Devel bool `json:"devel,omitempty"`
|
||||||
|
// Corresponds to [FUserns].
|
||||||
|
Userns bool `json:"userns,omitempty"`
|
||||||
|
// Corresponds to [FHostNet].
|
||||||
|
HostNet bool `json:"host_net,omitempty"`
|
||||||
|
// Corresponds to [FHostAbstract].
|
||||||
|
HostAbstract bool `json:"host_abstract,omitempty"`
|
||||||
|
// Corresponds to [FTty].
|
||||||
|
Tty bool `json:"tty,omitempty"`
|
||||||
|
|
||||||
|
// Corresponds to [FMultiarch].
|
||||||
|
Multiarch bool `json:"multiarch,omitempty"`
|
||||||
|
|
||||||
|
// Corresponds to [FMapRealUID].
|
||||||
|
MapRealUID bool `json:"map_real_uid"`
|
||||||
|
|
||||||
|
// Corresponds to [FDevice].
|
||||||
|
Device bool `json:"device,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContainerConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
if c == nil {
|
||||||
|
return nil, syscall.EINVAL
|
||||||
|
}
|
||||||
|
return json.Marshal(&containerConfigJSON{
|
||||||
|
ContainerConfigF: (*ContainerConfigF)(c),
|
||||||
|
|
||||||
|
SeccompCompat: c.Flags&FSeccompCompat != 0,
|
||||||
|
Devel: c.Flags&FDevel != 0,
|
||||||
|
Userns: c.Flags&FUserns != 0,
|
||||||
|
HostNet: c.Flags&FHostNet != 0,
|
||||||
|
HostAbstract: c.Flags&FHostAbstract != 0,
|
||||||
|
Tty: c.Flags&FTty != 0,
|
||||||
|
Multiarch: c.Flags&FMultiarch != 0,
|
||||||
|
MapRealUID: c.Flags&FMapRealUID != 0,
|
||||||
|
Device: c.Flags&FDevice != 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContainerConfig) UnmarshalJSON(data []byte) error {
|
||||||
|
if c == nil {
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
v := new(containerConfigJSON)
|
||||||
|
if err := json.Unmarshal(data, &v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*c = *(*ContainerConfig)(v.ContainerConfigF)
|
||||||
|
if v.SeccompCompat {
|
||||||
|
c.Flags |= FSeccompCompat
|
||||||
|
}
|
||||||
|
if v.Devel {
|
||||||
|
c.Flags |= FDevel
|
||||||
|
}
|
||||||
|
if v.Userns {
|
||||||
|
c.Flags |= FUserns
|
||||||
|
}
|
||||||
|
if v.HostNet {
|
||||||
|
c.Flags |= FHostNet
|
||||||
|
}
|
||||||
|
if v.HostAbstract {
|
||||||
|
c.Flags |= FHostAbstract
|
||||||
|
}
|
||||||
|
if v.Tty {
|
||||||
|
c.Flags |= FTty
|
||||||
|
}
|
||||||
|
if v.Multiarch {
|
||||||
|
c.Flags |= FMultiarch
|
||||||
|
}
|
||||||
|
if v.MapRealUID {
|
||||||
|
c.Flags |= FMapRealUID
|
||||||
|
}
|
||||||
|
if v.Device {
|
||||||
|
c.Flags |= FDevice
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
76
hst/container_test.go
Normal file
76
hst/container_test.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package hst_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"hakurei.app/hst"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestContainerConfig(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
c *hst.ContainerConfig
|
||||||
|
data string
|
||||||
|
}{
|
||||||
|
{"nil", nil, "null"},
|
||||||
|
{"zero", new(hst.ContainerConfig),
|
||||||
|
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"map_real_uid":false}`},
|
||||||
|
{"seccomp compat", &hst.ContainerConfig{Flags: hst.FSeccompCompat},
|
||||||
|
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"seccomp_compat":true,"map_real_uid":false}`},
|
||||||
|
{"hostnet hostabstract", &hst.ContainerConfig{Flags: hst.FHostNet | hst.FHostAbstract},
|
||||||
|
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"host_net":true,"host_abstract":true,"map_real_uid":false}`},
|
||||||
|
{"hostnet hostabstract mapuid", &hst.ContainerConfig{Flags: hst.FHostNet | hst.FHostAbstract | hst.FMapRealUID},
|
||||||
|
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"host_net":true,"host_abstract":true,"map_real_uid":true}`},
|
||||||
|
{"all", &hst.ContainerConfig{Flags: hst.FAll},
|
||||||
|
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"seccomp_compat":true,"devel":true,"userns":true,"host_net":true,"host_abstract":true,"tty":true,"multiarch":true,"map_real_uid":true,"device":true}`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
t.Run("marshal", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
if got, err := json.Marshal(tc.c); err != nil {
|
||||||
|
t.Fatalf("Marshal: error = %v", err)
|
||||||
|
} else if string(got) != tc.data {
|
||||||
|
t.Errorf("Marshal:\n%s, want\n%s", string(got), tc.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unmarshal", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
{
|
||||||
|
got := new(hst.ContainerConfig)
|
||||||
|
if err := json.Unmarshal([]byte(tc.data), &got); err != nil {
|
||||||
|
t.Fatalf("Unmarshal: error = %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tc.c) {
|
||||||
|
t.Errorf("Unmarshal: %v, want %v", got, tc.c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("passthrough", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
if _, err := (*hst.ContainerConfig)(nil).MarshalJSON(); !errors.Is(err, syscall.EINVAL) {
|
||||||
|
t.Errorf("MarshalJSON: error = %v", err)
|
||||||
|
}
|
||||||
|
if err := (*hst.ContainerConfig)(nil).UnmarshalJSON(nil); !errors.Is(err, syscall.EINVAL) {
|
||||||
|
t.Errorf("UnmarshalJSON: error = %v", err)
|
||||||
|
}
|
||||||
|
if err := new(hst.ContainerConfig).UnmarshalJSON([]byte{}); err == nil {
|
||||||
|
t.Errorf("UnmarshalJSON: error = %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
17
hst/hst.go
17
hst/hst.go
@ -3,6 +3,7 @@ package hst
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -96,17 +97,8 @@ func Template() *Config {
|
|||||||
Groups: []string{"video", "dialout", "plugdev"},
|
Groups: []string{"video", "dialout", "plugdev"},
|
||||||
|
|
||||||
Container: &ContainerConfig{
|
Container: &ContainerConfig{
|
||||||
Hostname: "localhost",
|
Hostname: "localhost",
|
||||||
Devel: true,
|
WaitDelay: -1,
|
||||||
Userns: true,
|
|
||||||
HostNet: true,
|
|
||||||
HostAbstract: true,
|
|
||||||
Device: true,
|
|
||||||
WaitDelay: -1,
|
|
||||||
SeccompCompat: true,
|
|
||||||
Tty: true,
|
|
||||||
Multiarch: true,
|
|
||||||
MapRealUID: true,
|
|
||||||
// example API credentials pulled from Google Chrome
|
// example API credentials pulled from Google Chrome
|
||||||
// DO NOT USE THESE IN A REAL BROWSER
|
// DO NOT USE THESE IN A REAL BROWSER
|
||||||
Env: map[string]string{
|
Env: map[string]string{
|
||||||
@ -143,6 +135,9 @@ func Template() *Config {
|
|||||||
"--enable-features=UseOzonePlatform",
|
"--enable-features=UseOzonePlatform",
|
||||||
"--ozone-platform=wayland",
|
"--ozone-platform=wayland",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Set all bits here so new flags trip the template test.
|
||||||
|
Flags: math.MaxUint,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -164,20 +165,11 @@ func TestTemplate(t *testing.T) {
|
|||||||
"container": {
|
"container": {
|
||||||
"hostname": "localhost",
|
"hostname": "localhost",
|
||||||
"wait_delay": -1,
|
"wait_delay": -1,
|
||||||
"seccomp_compat": true,
|
|
||||||
"devel": true,
|
|
||||||
"userns": true,
|
|
||||||
"host_net": true,
|
|
||||||
"host_abstract": true,
|
|
||||||
"tty": true,
|
|
||||||
"multiarch": true,
|
|
||||||
"env": {
|
"env": {
|
||||||
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
|
||||||
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
|
||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
|
||||||
},
|
},
|
||||||
"map_real_uid": true,
|
|
||||||
"device": true,
|
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
@ -243,14 +235,41 @@ func TestTemplate(t *testing.T) {
|
|||||||
"--disable-smooth-scrolling",
|
"--disable-smooth-scrolling",
|
||||||
"--enable-features=UseOzonePlatform",
|
"--enable-features=UseOzonePlatform",
|
||||||
"--ozone-platform=wayland"
|
"--ozone-platform=wayland"
|
||||||
]
|
],
|
||||||
|
"seccomp_compat": true,
|
||||||
|
"devel": true,
|
||||||
|
"userns": true,
|
||||||
|
"host_net": true,
|
||||||
|
"host_abstract": true,
|
||||||
|
"tty": true,
|
||||||
|
"multiarch": true,
|
||||||
|
"map_real_uid": true,
|
||||||
|
"device": true
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
if p, err := json.MarshalIndent(hst.Template(), "", "\t"); err != nil {
|
t.Run("marshal", func(t *testing.T) {
|
||||||
t.Fatalf("cannot marshal: %v", err)
|
t.Parallel()
|
||||||
} else if s := string(p); s != want {
|
if p, err := json.MarshalIndent(hst.Template(), "", "\t"); err != nil {
|
||||||
t.Fatalf("Template:\n%s\nwant:\n%s",
|
t.Fatalf("cannot marshal: %v", err)
|
||||||
s, want)
|
} else if s := string(p); s != want {
|
||||||
}
|
t.Fatalf("Template:\n%s\nwant:\n%s",
|
||||||
|
s, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unmarshal", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var got *hst.Config
|
||||||
|
if err := json.Unmarshal([]byte(want), &got); err != nil {
|
||||||
|
t.Fatalf("Unmarshal: error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wantVal := hst.Template()
|
||||||
|
wantVal.Container.Flags = hst.FAll
|
||||||
|
if !reflect.DeepEqual(got, wantVal) {
|
||||||
|
t.Fatalf("Unmarshal: %#v, want %#v", got, wantVal)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ func TestApp(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"nixos permissive defaults no enablements", new(stubNixOS),
|
"nixos permissive defaults no enablements", new(stubNixOS),
|
||||||
&hst.Config{Container: &hst.ContainerConfig{
|
&hst.Config{Container: &hst.ContainerConfig{
|
||||||
Userns: true, HostNet: true, HostAbstract: true, Tty: true,
|
|
||||||
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
{FilesystemConfig: &hst.FSBind{
|
{FilesystemConfig: &hst.FSBind{
|
||||||
Target: fhs.AbsRoot,
|
Target: fhs.AbsRoot,
|
||||||
@ -71,6 +69,8 @@ func TestApp(t *testing.T) {
|
|||||||
|
|
||||||
Path: m("/run/current-system/sw/bin/zsh"),
|
Path: m("/run/current-system/sw/bin/zsh"),
|
||||||
Args: []string{"/run/current-system/sw/bin/zsh"},
|
Args: []string{"/run/current-system/sw/bin/zsh"},
|
||||||
|
|
||||||
|
Flags: hst.FUserns | hst.FHostNet | hst.FHostAbstract | hst.FTty,
|
||||||
}},
|
}},
|
||||||
state.ID{
|
state.ID{
|
||||||
0x4a, 0x45, 0x0b, 0x65,
|
0x4a, 0x45, 0x0b, 0x65,
|
||||||
@ -162,8 +162,6 @@ func TestApp(t *testing.T) {
|
|||||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPulse),
|
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPulse),
|
||||||
|
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Userns: true, HostNet: true, HostAbstract: true, Tty: true,
|
|
||||||
|
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
{FilesystemConfig: &hst.FSBind{
|
{FilesystemConfig: &hst.FSBind{
|
||||||
Target: fhs.AbsRoot,
|
Target: fhs.AbsRoot,
|
||||||
@ -194,6 +192,8 @@ func TestApp(t *testing.T) {
|
|||||||
|
|
||||||
Path: m("/run/current-system/sw/bin/zsh"),
|
Path: m("/run/current-system/sw/bin/zsh"),
|
||||||
Args: []string{"zsh", "-c", "exec chromium "},
|
Args: []string{"zsh", "-c", "exec chromium "},
|
||||||
|
|
||||||
|
Flags: hst.FUserns | hst.FHostNet | hst.FHostAbstract | hst.FTty,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
state.ID{
|
state.ID{
|
||||||
@ -308,7 +308,7 @@ func TestApp(t *testing.T) {
|
|||||||
ID: "org.chromium.Chromium",
|
ID: "org.chromium.Chromium",
|
||||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPulse),
|
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPulse),
|
||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Userns: true, HostNet: true, MapRealUID: true, Env: nil,
|
Env: nil,
|
||||||
Filesystem: []hst.FilesystemConfigJSON{
|
Filesystem: []hst.FilesystemConfigJSON{
|
||||||
f(&hst.FSBind{Source: m("/bin")}),
|
f(&hst.FSBind{Source: m("/bin")}),
|
||||||
f(&hst.FSBind{Source: m("/usr/bin/")}),
|
f(&hst.FSBind{Source: m("/usr/bin/")}),
|
||||||
@ -330,6 +330,8 @@ func TestApp(t *testing.T) {
|
|||||||
Home: m("/var/lib/persist/module/hakurei/0/1"),
|
Home: m("/var/lib/persist/module/hakurei/0/1"),
|
||||||
|
|
||||||
Path: m("/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start"),
|
Path: m("/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start"),
|
||||||
|
|
||||||
|
Flags: hst.FUserns | hst.FHostNet | hst.FMapRealUID,
|
||||||
},
|
},
|
||||||
SystemBus: &hst.BusConfig{
|
SystemBus: &hst.BusConfig{
|
||||||
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
|
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
|
||||||
|
@ -94,7 +94,7 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *state.ID, config
|
|||||||
s.Shim.WaitDelay = s.Container.WaitDelay
|
s.Shim.WaitDelay = s.Container.WaitDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Container.MapRealUID {
|
if s.Container.Flags&hst.FMapRealUID != 0 {
|
||||||
s.Mapuid, s.Mapgid = k.getuid(), k.getgid()
|
s.Mapuid, s.Mapgid = k.getuid(), k.getgid()
|
||||||
} else {
|
} else {
|
||||||
s.Mapuid, s.Mapgid = k.overflowUid(msg), k.overflowGid(msg)
|
s.Mapuid, s.Mapgid = k.overflowUid(msg), k.overflowGid(msg)
|
||||||
|
@ -48,9 +48,9 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error {
|
|||||||
const preallocateOpsCount = 1 << 5
|
const preallocateOpsCount = 1 << 5
|
||||||
|
|
||||||
state.params.Hostname = state.Container.Hostname
|
state.params.Hostname = state.Container.Hostname
|
||||||
state.params.RetainSession = state.Container.Tty
|
state.params.RetainSession = state.Container.Flags&hst.FTty != 0
|
||||||
state.params.HostNet = state.Container.HostNet
|
state.params.HostNet = state.Container.Flags&hst.FHostNet != 0
|
||||||
state.params.HostAbstract = state.Container.HostAbstract
|
state.params.HostAbstract = state.Container.Flags&hst.FHostAbstract != 0
|
||||||
|
|
||||||
if state.Container.Path == nil {
|
if state.Container.Path == nil {
|
||||||
return newWithMessage("invalid program path")
|
return newWithMessage("invalid program path")
|
||||||
@ -67,24 +67,24 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error {
|
|||||||
// this behaviour is implemented in the shim
|
// this behaviour is implemented in the shim
|
||||||
state.params.ForwardCancel = state.Shim.WaitDelay > 0
|
state.params.ForwardCancel = state.Shim.WaitDelay > 0
|
||||||
|
|
||||||
if state.Container.Multiarch {
|
if state.Container.Flags&hst.FMultiarch != 0 {
|
||||||
state.params.SeccompFlags |= seccomp.AllowMultiarch
|
state.params.SeccompFlags |= seccomp.AllowMultiarch
|
||||||
}
|
}
|
||||||
|
|
||||||
if !state.Container.SeccompCompat {
|
if state.Container.Flags&hst.FSeccompCompat == 0 {
|
||||||
state.params.SeccompPresets |= bits.PresetExt
|
state.params.SeccompPresets |= bits.PresetExt
|
||||||
}
|
}
|
||||||
if !state.Container.Devel {
|
if state.Container.Flags&hst.FDevel == 0 {
|
||||||
state.params.SeccompPresets |= bits.PresetDenyDevel
|
state.params.SeccompPresets |= bits.PresetDenyDevel
|
||||||
}
|
}
|
||||||
if !state.Container.Userns {
|
if state.Container.Flags&hst.FUserns == 0 {
|
||||||
state.params.SeccompPresets |= bits.PresetDenyNS
|
state.params.SeccompPresets |= bits.PresetDenyNS
|
||||||
}
|
}
|
||||||
if !state.Container.Tty {
|
if state.Container.Flags&hst.FTty == 0 {
|
||||||
state.params.SeccompPresets |= bits.PresetDenyTTY
|
state.params.SeccompPresets |= bits.PresetDenyTTY
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.Container.MapRealUID {
|
if state.Container.Flags&hst.FMapRealUID != 0 {
|
||||||
state.params.Uid = state.Mapuid
|
state.params.Uid = state.Mapuid
|
||||||
state.params.Gid = state.Mapgid
|
state.params.Gid = state.Mapgid
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error {
|
|||||||
state.params.
|
state.params.
|
||||||
Proc(fhs.AbsProc).
|
Proc(fhs.AbsProc).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755)
|
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755)
|
||||||
if !state.Container.Device {
|
if state.Container.Flags&hst.FDevice == 0 {
|
||||||
state.params.DevWritable(fhs.AbsDev, true)
|
state.params.DevWritable(fhs.AbsDev, true)
|
||||||
} else {
|
} else {
|
||||||
state.params.Bind(fhs.AbsDev, fhs.AbsDev, bits.BindWritable|bits.BindDevice)
|
state.params.Bind(fhs.AbsDev, fhs.AbsDev, bits.BindWritable|bits.BindDevice)
|
||||||
@ -275,7 +275,7 @@ func (s *spFilesystemOp) toContainer(state *outcomeStateParams) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no more configured paths beyond this point
|
// no more configured paths beyond this point
|
||||||
if !state.Container.Device {
|
if state.Container.Flags&hst.FDevice == 0 {
|
||||||
state.params.Remount(fhs.AbsDev, syscall.MS_RDONLY)
|
state.params.Remount(fhs.AbsDev, syscall.MS_RDONLY)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -51,12 +51,7 @@ func TestSpParamsOp(t *testing.T) {
|
|||||||
}, func() *hst.Config {
|
}, func() *hst.Config {
|
||||||
c := hst.Template()
|
c := hst.Template()
|
||||||
c.Container.Args = nil
|
c.Container.Args = nil
|
||||||
c.Container.Multiarch = false
|
c.Container.Flags = hst.FHostNet | hst.FHostAbstract | hst.FMapRealUID
|
||||||
c.Container.SeccompCompat = false
|
|
||||||
c.Container.Devel = false
|
|
||||||
c.Container.Userns = false
|
|
||||||
c.Container.Tty = false
|
|
||||||
c.Container.Device = false
|
|
||||||
return c
|
return c
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("lookupEnv", stub.ExpectArgs{"TERM"}, "xterm", nil),
|
call("lookupEnv", stub.ExpectArgs{"TERM"}, "xterm", nil),
|
||||||
@ -65,8 +60,8 @@ func TestSpParamsOp(t *testing.T) {
|
|||||||
// this op configures the container state and does not make calls during toContainer
|
// this op configures the container state and does not make calls during toContainer
|
||||||
}, &container.Params{
|
}, &container.Params{
|
||||||
Hostname: config.Container.Hostname,
|
Hostname: config.Container.Hostname,
|
||||||
HostNet: config.Container.HostNet,
|
HostNet: true,
|
||||||
HostAbstract: config.Container.HostAbstract,
|
HostAbstract: true,
|
||||||
Path: config.Container.Path,
|
Path: config.Container.Path,
|
||||||
Args: []string{config.Container.Path.String()},
|
Args: []string{config.Container.Path.String()},
|
||||||
SeccompPresets: bits.PresetExt | bits.PresetDenyDevel | bits.PresetDenyNS | bits.PresetDenyTTY,
|
SeccompPresets: bits.PresetExt | bits.PresetDenyDevel | bits.PresetDenyNS | bits.PresetDenyTTY,
|
||||||
@ -109,9 +104,9 @@ func TestSpParamsOp(t *testing.T) {
|
|||||||
// this op configures the container state and does not make calls during toContainer
|
// this op configures the container state and does not make calls during toContainer
|
||||||
}, &container.Params{
|
}, &container.Params{
|
||||||
Hostname: config.Container.Hostname,
|
Hostname: config.Container.Hostname,
|
||||||
RetainSession: config.Container.Tty,
|
RetainSession: true,
|
||||||
HostNet: config.Container.HostNet,
|
HostNet: true,
|
||||||
HostAbstract: config.Container.HostAbstract,
|
HostAbstract: true,
|
||||||
Path: config.Container.Path,
|
Path: config.Container.Path,
|
||||||
Args: config.Container.Args,
|
Args: config.Container.Args,
|
||||||
SeccompFlags: seccomp.AllowMultiarch,
|
SeccompFlags: seccomp.AllowMultiarch,
|
||||||
@ -159,7 +154,7 @@ func TestSpFilesystemOp(t *testing.T) {
|
|||||||
}}},
|
}}},
|
||||||
{FilesystemConfig: &hst.FSEphemeral{Target: hst.AbsPrivateTmp}},
|
{FilesystemConfig: &hst.FSEphemeral{Target: hst.AbsPrivateTmp}},
|
||||||
}
|
}
|
||||||
c.Container.Device = false
|
c.Container.Flags &= ^hst.FDevice
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
configSmall := newConfigSmall()
|
configSmall := newConfigSmall()
|
||||||
|
@ -54,7 +54,7 @@ func (s *spX11Op) toSystem(state *outcomeStateSys) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.sys.UpdatePermType(hst.EX11, socketPath, acl.Read, acl.Write, acl.Execute)
|
state.sys.UpdatePermType(hst.EX11, socketPath, acl.Read, acl.Write, acl.Execute)
|
||||||
if !state.Container.HostAbstract {
|
if state.Container.Flags&hst.FHostAbstract == 0 {
|
||||||
s.Display = "unix:" + socketPath.String()
|
s.Display = "unix:" + socketPath.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user