aboutsummaryrefslogtreecommitdiffhomepage
path: root/hst/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'hst/config.go')
-rw-r--r--hst/config.go120
1 files changed, 73 insertions, 47 deletions
diff --git a/hst/config.go b/hst/config.go
index 0c66c274..51ac62ec 100644
--- a/hst/config.go
+++ b/hst/config.go
@@ -8,74 +8,97 @@ import (
"hakurei.app/container/check"
)
-// Config configures an application container, implemented in internal/app.
+// Config configures an application container.
type Config struct {
// Reverse-DNS style configured arbitrary identifier string.
- // Passed to wayland security-context-v1 and used as part of defaults in dbus session proxy.
+ //
+ // This value is passed as is to Wayland security-context-v1 and used as
+ // part of defaults in D-Bus session proxy. The zero value causes a default
+ // value to be derived from the container instance.
ID string `json:"id,omitempty"`
// System services to make available in the container.
Enablements *Enablements `json:"enablements,omitempty"`
// Session D-Bus proxy configuration.
- // If set to nil, session bus proxy assume built-in defaults.
+ //
+ // Has no effect if [EDBus] but is not set in Enablements. The zero value
+ // assumes built-in defaults derived from ID.
SessionBus *BusConfig `json:"session_bus,omitempty"`
// System D-Bus proxy configuration.
- // If set to nil, system bus proxy is disabled.
+ //
+ // Has no effect if [EDBus] but is not set in Enablements. The zero value
+ // disables system bus proxy.
SystemBus *BusConfig `json:"system_bus,omitempty"`
- // Direct access to wayland socket, no attempt is made to attach security-context-v1
- // and the bare socket is made available to the container.
+ // Direct access to Wayland socket, no attempt is made to attach
+ // security-context-v1 and the bare socket is made available to the
+ // container.
//
- // This option is unsupported and most likely enables full control over the Wayland
- // session. Do not set this to true unless you are sure you know what you are doing.
+ // This option is unsupported and will most likely enable full control over
+ // the Wayland session from within the container. Do not set this to true
+ // unless you are sure you know what you are doing.
DirectWayland bool `json:"direct_wayland,omitempty"`
- // Direct access to the PipeWire socket established via SecurityContext::Create, no
- // attempt is made to start the pipewire-pulse server.
+
+ // Direct access to the PipeWire socket established via SecurityContext::Create,
+ // no attempt is made to start the pipewire-pulse server.
+ //
+ // The SecurityContext machinery is fatally flawed, it unconditionally sets
+ // read and execute bits on all objects for clients with the lowest achievable
+ // privilege level (by setting PW_KEY_ACCESS to "restricted" or by satisfying
+ // all conditions of [the /.flatpak-info hack]). This enables them to call
+ // any method targeting any object, and since Registry::Destroy checks for
+ // the read and execute bit, allows the destruction of any object other than
+ // PW_ID_CORE as well.
//
- // The SecurityContext machinery is fatally flawed, it blindly sets read and execute
- // bits on all objects for clients with the lowest achievable privilege level (by
- // setting PW_KEY_ACCESS to "restricted"). This enables them to call any method
- // targeting any object, and since Registry::Destroy checks for the read and execute bit,
- // allows the destruction of any object other than PW_ID_CORE as well. This behaviour
- // is implemented separately in media-session and wireplumber, with the wireplumber
- // implementation in Lua via an embedded Lua vm. In all known setups, wireplumber is
- // in use, and there is no known way to change its behaviour and set permissions
- // differently without replacing the Lua script. Also, since PipeWire relies on these
- // permissions to work, reducing them is not possible.
+ // This behaviour is implemented separately in media-session and wireplumber,
+ // with the wireplumber implementation in Lua via an embedded Lua vm. In all
+ // known setups, wireplumber is in use, and in that case, no option for
+ // configuring this behaviour exists, without replacing the Lua script.
+ // Also, since PipeWire relies on these permissions to work, reducing them
+ // was never possible in the first place.
//
- // Currently, the only other sandboxed use case is flatpak, which is not aware of
- // PipeWire and blindly exposes the bare PulseAudio socket to the container (behaves
- // like DirectPulse). This socket is backed by the pipewire-pulse compatibility daemon,
- // which obtains client pid via the SO_PEERCRED option. The PipeWire daemon, pipewire-pulse
- // daemon and the session manager daemon then separately performs the /.flatpak-info hack
- // described in https://git.gensokyo.uk/security/hakurei/issues/21. Under such use case,
- // since the client has no direct access to PipeWire, insecure parts of the protocol are
- // obscured by pipewire-pulse simply not implementing them, and thus hiding the flaws
- // described above.
+ // Currently, the only other sandboxed use case is flatpak, which is not
+ // aware of PipeWire and blindly exposes the bare PulseAudio socket to the
+ // container (behaves like DirectPulse). This socket is backed by the
+ // pipewire-pulse compatibility daemon, which obtains client pid via the
+ // SO_PEERCRED option. The PipeWire daemon, pipewire-pulse daemon and the
+ // session manager daemon then separately performs [the /.flatpak-info hack].
+ // Under such use case, since the client has no direct access to PipeWire,
+ // insecure parts of the protocol are obscured by the absence of an
+ // equivalent API in PulseAudio, or pipewire-pulse simply not implementing
+ // them.
//
- // Hakurei does not rely on the /.flatpak-info hack. Instead, a socket is sets up via
- // SecurityContext. A pipewire-pulse server connected through it achieves the same
- // permissions as flatpak does via the /.flatpak-info hack and is maintained for the
- // life of the container.
+ // Hakurei does not rely on [the /.flatpak-info hack]. Instead, a socket is
+ // sets up via SecurityContext. A pipewire-pulse server connected through it
+ // achieves the same permissions as flatpak does via [the /.flatpak-info hack]
+ // and is maintained for the life of the container.
+ //
+ // This option is unsupported and enables a denial-of-service attack as the
+ // sandboxed client is able to destroy any client object and thus
+ // disconnecting them from PipeWire, or destroy the SecurityContext object,
+ // preventing any further container creation.
//
- // This option is unsupported and enables a denial-of-service attack as the sandboxed
- // client is able to destroy any client object and thus disconnecting them from PipeWire,
- // or destroy the SecurityContext object preventing any further container creation.
// Do not set this to true, it is insecure under any configuration.
+ //
+ // [the /.flatpak-info hack]: https://git.gensokyo.uk/security/hakurei/issues/21
DirectPipeWire bool `json:"direct_pipewire,omitempty"`
- // Direct access to PulseAudio socket, no attempt is made to establish pipewire-pulse
- // server via a PipeWire socket with a SecurityContext attached and the bare socket
- // is made available to the container.
+
+ // Direct access to PulseAudio socket, no attempt is made to establish
+ // pipewire-pulse server via a PipeWire socket with a SecurityContext
+ // attached, and the bare socket is made available to the container.
//
- // This option is unsupported and enables arbitrary code execution as the PulseAudio
- // server. Do not set this to true, it is insecure under any configuration.
+ // This option is unsupported and enables arbitrary code execution as the
+ // PulseAudio server.
+ //
+ // Do not set this to true, it is insecure under any configuration.
DirectPulse bool `json:"direct_pulse,omitempty"`
// Extra acl updates to perform before setuid.
ExtraPerms []ExtraPermConfig `json:"extra_perms,omitempty"`
- // Numerical application id, passed to hsu, used to derive init user namespace credentials.
+ // Numerical application id, passed to hsu, used to derive init user
+ // namespace credentials.
Identity int `json:"identity"`
// Init user namespace supplementary groups inherited by all container processes.
Groups []string `json:"groups"`
@@ -85,17 +108,20 @@ type Config struct {
}
var (
- // ErrConfigNull is returned by [Config.Validate] for an invalid configuration that contains a null value for any
- // field that must not be null.
+ // ErrConfigNull is returned by [Config.Validate] for an invalid configuration
+ // that contains a null value for any field that must not be null.
ErrConfigNull = errors.New("unexpected null in config")
- // ErrIdentityBounds is returned by [Config.Validate] for an out of bounds [Config.Identity] value.
+ // ErrIdentityBounds is returned by [Config.Validate] for an out of bounds
+ // [Config.Identity] value.
ErrIdentityBounds = errors.New("identity out of bounds")
- // ErrEnviron is returned by [Config.Validate] if an environment variable name contains '=' or NUL.
+ // ErrEnviron is returned by [Config.Validate] if an environment variable
+ // name contains '=' or NUL.
ErrEnviron = errors.New("invalid environment variable name")
- // ErrInsecure is returned by [Config.Validate] if the configuration is considered insecure.
+ // ErrInsecure is returned by [Config.Validate] if the configuration is
+ // considered insecure.
ErrInsecure = errors.New("configuration is insecure")
)