forked from rosa/hakurei
hst: optionally cover /run/ early
This works around awkward root permissions. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -83,6 +83,8 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
|
|||||||
Home: home,
|
Home: home,
|
||||||
Path: shell,
|
Path: shell,
|
||||||
Args: []string{"zsh", "-c"},
|
Args: []string{"zsh", "-c"},
|
||||||
|
|
||||||
|
Flags: hst.FCoverRun,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -122,7 +122,7 @@ talk com.canonical.Unity
|
|||||||
"exec Discord --ozone-platform-hint=wayland",
|
"exec Discord --ozone-platform-hint=wayland",
|
||||||
},
|
},
|
||||||
|
|
||||||
Flags: hst.FUserns | hst.FHostNet | hst.FMapRealUID |
|
Flags: hst.FCoverRun | hst.FUserns | hst.FHostNet | hst.FMapRealUID |
|
||||||
hst.FShareRuntime | hst.FShareTmpdir,
|
hst.FShareRuntime | hst.FShareTmpdir,
|
||||||
},
|
},
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func TestPrintShowInstance(t *testing.T) {
|
|||||||
Identity: 9 (org.chromium.Chromium)
|
Identity: 9 (org.chromium.Chromium)
|
||||||
Enablements: wayland, dbus, pipewire
|
Enablements: wayland, dbus, pipewire
|
||||||
Groups: video, dialout, plugdev
|
Groups: video, dialout, plugdev
|
||||||
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir
|
||||||
Home: /data/data/org.chromium.Chromium
|
Home: /data/data/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
@@ -161,7 +161,7 @@ App
|
|||||||
Identity: 9 (org.chromium.Chromium)
|
Identity: 9 (org.chromium.Chromium)
|
||||||
Enablements: wayland, dbus, pipewire
|
Enablements: wayland, dbus, pipewire
|
||||||
Groups: video, dialout, plugdev
|
Groups: video, dialout, plugdev
|
||||||
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir
|
||||||
Home: /data/data/org.chromium.Chromium
|
Home: /data/data/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
@@ -355,6 +355,7 @@ App
|
|||||||
"multiarch": true,
|
"multiarch": true,
|
||||||
"map_real_uid": true,
|
"map_real_uid": true,
|
||||||
"device": true,
|
"device": true,
|
||||||
|
"cover_run": true,
|
||||||
"share_runtime": true,
|
"share_runtime": true,
|
||||||
"share_tmpdir": true
|
"share_tmpdir": true
|
||||||
},
|
},
|
||||||
@@ -506,6 +507,7 @@ App
|
|||||||
"multiarch": true,
|
"multiarch": true,
|
||||||
"map_real_uid": true,
|
"map_real_uid": true,
|
||||||
"device": true,
|
"device": true,
|
||||||
|
"cover_run": true,
|
||||||
"share_runtime": true,
|
"share_runtime": true,
|
||||||
"share_tmpdir": true
|
"share_tmpdir": true
|
||||||
}
|
}
|
||||||
@@ -704,6 +706,7 @@ func TestPrintPs(t *testing.T) {
|
|||||||
"multiarch": true,
|
"multiarch": true,
|
||||||
"map_real_uid": true,
|
"map_real_uid": true,
|
||||||
"device": true,
|
"device": true,
|
||||||
|
"cover_run": true,
|
||||||
"share_runtime": true,
|
"share_runtime": true,
|
||||||
"share_tmpdir": true
|
"share_tmpdir": true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ const (
|
|||||||
// FDevice mount /dev/ from the init mount namespace as is in the container
|
// FDevice mount /dev/ from the init mount namespace as is in the container
|
||||||
// mount namespace.
|
// mount namespace.
|
||||||
FDevice
|
FDevice
|
||||||
|
// FCoverRun covers /run/ in the container mount namespace early.
|
||||||
|
FCoverRun
|
||||||
|
|
||||||
// FShareRuntime shares XDG_RUNTIME_DIR between containers under the same identity.
|
// FShareRuntime shares XDG_RUNTIME_DIR between containers under the same identity.
|
||||||
FShareRuntime
|
FShareRuntime
|
||||||
@@ -101,6 +103,8 @@ func (flags Flags) String() string {
|
|||||||
return "mapuid"
|
return "mapuid"
|
||||||
case FDevice:
|
case FDevice:
|
||||||
return "device"
|
return "device"
|
||||||
|
case FCoverRun:
|
||||||
|
return "cover_run"
|
||||||
case FShareRuntime:
|
case FShareRuntime:
|
||||||
return "runtime"
|
return "runtime"
|
||||||
case FShareTmpdir:
|
case FShareTmpdir:
|
||||||
@@ -196,6 +200,8 @@ type containerConfigJSON = struct {
|
|||||||
|
|
||||||
// Corresponds to [FDevice].
|
// Corresponds to [FDevice].
|
||||||
Device bool `json:"device,omitempty"`
|
Device bool `json:"device,omitempty"`
|
||||||
|
// Corresponds to [FCoverRun].
|
||||||
|
CoverRun bool `json:"cover_run,omitempty"`
|
||||||
|
|
||||||
// Corresponds to [FShareRuntime].
|
// Corresponds to [FShareRuntime].
|
||||||
ShareRuntime bool `json:"share_runtime,omitempty"`
|
ShareRuntime bool `json:"share_runtime,omitempty"`
|
||||||
@@ -219,6 +225,7 @@ func (c *ContainerConfig) MarshalJSON() ([]byte, error) {
|
|||||||
Multiarch: c.Flags&FMultiarch != 0,
|
Multiarch: c.Flags&FMultiarch != 0,
|
||||||
MapRealUID: c.Flags&FMapRealUID != 0,
|
MapRealUID: c.Flags&FMapRealUID != 0,
|
||||||
Device: c.Flags&FDevice != 0,
|
Device: c.Flags&FDevice != 0,
|
||||||
|
CoverRun: c.Flags&FCoverRun != 0,
|
||||||
ShareRuntime: c.Flags&FShareRuntime != 0,
|
ShareRuntime: c.Flags&FShareRuntime != 0,
|
||||||
ShareTmpdir: c.Flags&FShareTmpdir != 0,
|
ShareTmpdir: c.Flags&FShareTmpdir != 0,
|
||||||
})
|
})
|
||||||
@@ -262,6 +269,9 @@ func (c *ContainerConfig) UnmarshalJSON(data []byte) error {
|
|||||||
if v.Device {
|
if v.Device {
|
||||||
c.Flags |= FDevice
|
c.Flags |= FDevice
|
||||||
}
|
}
|
||||||
|
if v.CoverRun {
|
||||||
|
c.Flags |= FCoverRun
|
||||||
|
}
|
||||||
if v.ShareRuntime {
|
if v.ShareRuntime {
|
||||||
c.Flags |= FShareRuntime
|
c.Flags |= FShareRuntime
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ func TestFlagsString(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"none", 0, "none"},
|
{"none", 0, "none"},
|
||||||
{"none high", hst.FAll + 1, "none"},
|
{"none high", hst.FAll + 1, "none"},
|
||||||
{"all", hst.FAll, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir"},
|
{"all", hst.FAll, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir"},
|
||||||
{"all high", math.MaxUint, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir"},
|
{"all high", math.MaxUint, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir"},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
@@ -53,7 +53,7 @@ func TestContainerConfig(t *testing.T) {
|
|||||||
{"hostnet hostabstract mapuid", &hst.ContainerConfig{Flags: hst.FHostNet | hst.FHostAbstract | hst.FMapRealUID},
|
{"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}`},
|
`{"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},
|
{"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,"share_runtime":true,"share_tmpdir":true}`},
|
`{"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,"cover_run":true,"share_runtime":true,"share_tmpdir":true}`},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ func TestTemplate(t *testing.T) {
|
|||||||
"multiarch": true,
|
"multiarch": true,
|
||||||
"map_real_uid": true,
|
"map_real_uid": true,
|
||||||
"device": true,
|
"device": true,
|
||||||
|
"cover_run": true,
|
||||||
"share_runtime": true,
|
"share_runtime": true,
|
||||||
"share_tmpdir": true
|
"share_tmpdir": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ func TestOutcomeRun(t *testing.T) {
|
|||||||
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
||||||
|
|
||||||
// spRuntimeOp
|
// spRuntimeOp
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/1971"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/1971"), std.BindWritable).
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func TestShimEntrypoint(t *testing.T) {
|
|||||||
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
||||||
|
|
||||||
// spRuntimeOp
|
// spRuntimeOp
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/tmp/hakurei.10/runtime/9999"), m("/run/user/1000"), std.BindWritable).
|
Bind(m("/tmp/hakurei.10/runtime/9999"), m("/run/user/1000"), std.BindWritable).
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ func (s *spRuntimeOp) toContainer(state *outcomeStateParams) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if state.Container.Flags&hst.FCoverRun != 0 {
|
||||||
|
state.params.Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755)
|
||||||
|
}
|
||||||
state.params.Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755)
|
state.params.Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755)
|
||||||
if state.Container.Flags&hst.FShareRuntime != 0 {
|
if state.Container.Flags&hst.FShareRuntime != 0 {
|
||||||
_, runtimeDirInst := s.commonPaths(state.outcomeState)
|
_, runtimeDirInst := s.commonPaths(state.outcomeState)
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func TestSpRuntimeOp(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{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
@@ -67,6 +68,7 @@ func TestSpRuntimeOp(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{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
@@ -94,6 +96,7 @@ func TestSpRuntimeOp(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{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
@@ -117,6 +120,7 @@ func TestSpRuntimeOp(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{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Tmpfs(fhs.AbsRun, xdgRuntimeDirSize, 0755).
|
||||||
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
Tmpfs(fhs.AbsRunUser, xdgRuntimeDirSize, 0755).
|
||||||
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
Bind(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), m("/run/user/1000"), std.BindWritable),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
|
|||||||
Reference in New Issue
Block a user