hst: reword and move constants
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hakurei (push) Successful in 3m8s
Test / Hpkg (push) Successful in 4m0s
Test / Sandbox (race detector) (push) Successful in 4m25s
Test / Hakurei (race detector) (push) Successful in 5m14s
Test / Sandbox (push) Successful in 1m26s
Test / Flake checks (push) Successful in 1m32s

These values are considered part of the stable, exported API, so move them to hst.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-10-05 17:40:32 +09:00
parent a63a372fe0
commit ae7b343cde
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
7 changed files with 43 additions and 33 deletions

View File

@ -45,7 +45,7 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
c.Command("shim", command.UsageInternal, func([]string) error { app.ShimMain(); return errSuccess }) c.Command("shim", command.UsageInternal, func([]string) error { app.ShimMain(); return errSuccess })
c.Command("app", "Load app from configuration file", func(args []string) error { c.Command("app", "Load and start container from configuration file", func(args []string) error {
if len(args) < 1 { if len(args) < 1 {
log.Fatal("app requires at least 1 argument") log.Fatal("app requires at least 1 argument")
} }
@ -74,14 +74,14 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
flagWayland, flagX11, flagDBus, flagPulse bool flagWayland, flagX11, flagDBus, flagPulse bool
) )
c.NewCommand("run", "Configure and start a permissive default sandbox", func(args []string) error { c.NewCommand("run", "Configure and start a permissive container", func(args []string) error {
// initialise config from flags // initialise config from flags
config := &hst.Config{ config := &hst.Config{
ID: flagID, ID: flagID,
Args: args, Args: args,
} }
if flagIdentity < 0 || flagIdentity > 9999 { if flagIdentity < hst.IdentityMin || flagIdentity > hst.IdentityMax {
log.Fatalf("identity %d out of range", flagIdentity) log.Fatalf("identity %d out of range", flagIdentity)
} }

View File

@ -21,8 +21,8 @@ func TestHelp(t *testing.T) {
Usage: hakurei [-h | --help] [-v] [--json] COMMAND [OPTIONS] Usage: hakurei [-h | --help] [-v] [--json] COMMAND [OPTIONS]
Commands: Commands:
app Load app from configuration file app Load and start container from configuration file
run Configure and start a permissive default sandbox run Configure and start a permissive container
show Show live or local app configuration show Show live or local app configuration
ps List active instances ps List active instances
version Display version information version Display version information

View File

@ -1,5 +1,7 @@
package main package main
// minimise imports to avoid inadvertently calling init or global variable functions
import ( import (
"bytes" "bytes"
"fmt" "fmt"
@ -19,6 +21,9 @@ const (
envGroups = "HAKUREI_GROUPS" envGroups = "HAKUREI_GROUPS"
PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_NO_NEW_PRIVS = 0x26
identityMin = 0
identityMax = 9999
) )
func main() { func main() {
@ -91,7 +96,7 @@ func main() {
// allowed identity range 0 to 9999 // allowed identity range 0 to 9999
if as, ok := os.LookupEnv(envIdentity); !ok { if as, ok := os.LookupEnv(envIdentity); !ok {
log.Fatal("HAKUREI_IDENTITY not set") log.Fatal("HAKUREI_IDENTITY not set")
} else if identity, err := parseUint32Fast(as); err != nil || identity < 0 || identity > 9999 { } else if identity, err := parseUint32Fast(as); err != nil || identity < identityMin || identity > identityMax {
log.Fatal("invalid identity") log.Fatal("invalid identity")
} else { } else {
uid += identity uid += identity

4
dist/comp/_hakurei vendored
View File

@ -54,8 +54,8 @@ __hakurei_instances() {
{ {
local -a _hakurei_cmds local -a _hakurei_cmds
_hakurei_cmds=( _hakurei_cmds=(
"app:Load app from configuration file" "app:Load and start container from configuration file"
"run:Configure and start a permissive default sandbox" "run:Configure and start a permissive container"
"show:Show live or local app configuration" "show:Show live or local app configuration"
"ps:List active instances" "ps:List active instances"
"version:Display version information" "version:Display version information"

View File

@ -12,10 +12,20 @@ const Tmp = "/.hakurei"
var AbsTmp = container.MustAbs(Tmp) var AbsTmp = container.MustAbs(Tmp)
const ( const (
// DefaultWaitDelay is used when WaitDelay has its zero value. // WaitDelayDefault is used when WaitDelay has its zero value.
DefaultWaitDelay = 5 * time.Second WaitDelayDefault = 5 * time.Second
// MaxWaitDelay is used if WaitDelay exceeds its value. // WaitDelayMax is used if WaitDelay exceeds its value.
MaxWaitDelay = 30 * time.Second WaitDelayMax = 30 * time.Second
// IdentityMin is the minimum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMin = 0
// IdentityMax is the maximum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMax = 9999
// ShimExitRequest is returned when the priv side process requests shim exit.
ShimExitRequest = 254
// ShimExitOrphan is returned when the shim is orphaned before priv side delivers a signal.
ShimExitOrphan = 3
) )
type ( type (
@ -69,8 +79,8 @@ type (
Hostname string `json:"hostname,omitempty"` Hostname string `json:"hostname,omitempty"`
// Duration in nanoseconds to wait for after interrupting the initial process. // Duration in nanoseconds to wait for after interrupting the initial process.
// Defaults to [DefaultWaitDelay] if less than or equals to zero, // Defaults to [WaitDelayDefault] if less than or equals to zero,
// or [MaxWaitDelay] if greater than [MaxWaitDelay]. // or [WaitDelayMax] if greater than [WaitDelayMax].
WaitDelay time.Duration `json:"wait_delay,omitempty"` WaitDelay time.Duration `json:"wait_delay,omitempty"`
// Emit Flatpak-compatible seccomp filter programs. // Emit Flatpak-compatible seccomp filter programs.

View File

@ -83,8 +83,8 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
k.ct = ct k.ct = ct
} }
// allowed identity range 0 to 9999, this is checked again in hsu // this is checked again in hsu
if config.Identity < 0 || config.Identity > 9999 { if config.Identity < hst.IdentityMin || config.Identity > hst.IdentityMax {
return newWithMessage(fmt.Sprintf("identity %d out of range", config.Identity)) return newWithMessage(fmt.Sprintf("identity %d out of range", config.Identity))
} }
@ -187,9 +187,9 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
// enforce bounds and default early // enforce bounds and default early
if s.Container.WaitDelay <= 0 { if s.Container.WaitDelay <= 0 {
kp.waitDelay = hst.DefaultWaitDelay kp.waitDelay = hst.WaitDelayDefault
} else if s.Container.WaitDelay > hst.MaxWaitDelay { } else if s.Container.WaitDelay > hst.WaitDelayMax {
kp.waitDelay = hst.MaxWaitDelay kp.waitDelay = hst.WaitDelayMax
} else { } else {
kp.waitDelay = s.Container.WaitDelay kp.waitDelay = s.Container.WaitDelay
} }

View File

@ -15,6 +15,7 @@ import (
"hakurei.app/container" "hakurei.app/container"
"hakurei.app/container/seccomp" "hakurei.app/container/seccomp"
"hakurei.app/hst"
) )
//#include "shim-signal.h" //#include "shim-signal.h"
@ -23,27 +24,21 @@ import "C"
const shimEnv = "HAKUREI_SHIM" const shimEnv = "HAKUREI_SHIM"
type shimParams struct { type shimParams struct {
// monitor pid, checked against ppid in signal handler // Priv side pid, checked against ppid in signal handler for the syscall.SIGCONT hack.
Monitor int Monitor int
// duration to wait for after interrupting a container's initial process before the container is killed; // Duration to wait for after interrupting a container's initial process before the container is killed.
// zero value defaults to [DefaultShimWaitDelay], values exceeding [MaxShimWaitDelay] becomes [MaxShimWaitDelay] // Limits are enforced on the priv side.
WaitDelay time.Duration WaitDelay time.Duration
// finalised container params // Finalised container params.
// TODO(ophestra): transmit outcomeState instead (params to shim)
Container *container.Params Container *container.Params
// verbosity pass through // Verbosity pass through.
Verbose bool Verbose bool
} }
const (
// ShimExitRequest is returned when the monitor process requests shim exit.
ShimExitRequest = 254
// ShimExitOrphan is returned when the shim is orphaned before monitor delivers a signal.
ShimExitOrphan = 3
)
// ShimMain is the main function of the shim process and runs as the unconstrained target user. // ShimMain is the main function of the shim process and runs as the unconstrained target user.
func ShimMain() { func ShimMain() {
log.SetPrefix("shim: ") log.SetPrefix("shim: ")
@ -107,12 +102,12 @@ func ShimMain() {
// setup has not completed, terminate immediately // setup has not completed, terminate immediately
msg.Resume() msg.Resume()
os.Exit(ShimExitRequest) os.Exit(hst.ShimExitRequest)
return return
case 1: // got SIGCONT after adoption: monitor died before delivering signal case 1: // got SIGCONT after adoption: monitor died before delivering signal
msg.BeforeExit() msg.BeforeExit()
os.Exit(ShimExitOrphan) os.Exit(hst.ShimExitOrphan)
return return
case 2: // unreachable case 2: // unreachable