aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-08-26 02:15:00 +0900
committerOphestra <cat@gensokyo.uk>2025-08-26 02:16:33 +0900
commit4cf694d2b31c7aa5c66cbb83d7d54c1a6cb1b4aa (patch)
treed4d964e10e8a50f60cc438ece76362b174e329c0
parentc9facb746b7be0f2d8f6b9b2227340ba2ec12060 (diff)
hst: use hsu userid for share path suffix
The privileged user is identifier to hakurei through its hsu userid. Using the kernel uid here makes little sense and is a leftover design choice from before hsu was implemented. Closes #7. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/hpkg/test/test.py2
-rw-r--r--hst/hst.go6
-rw-r--r--internal/sys/interface.go25
-rw-r--r--internal/sys/std.go20
-rw-r--r--test/sandbox/case/device.nix4
-rw-r--r--test/sandbox/case/mapuid.nix4
-rw-r--r--test/sandbox/case/pd.nix4
-rw-r--r--test/sandbox/case/pdlike.nix4
-rw-r--r--test/sandbox/case/preset.nix4
-rw-r--r--test/sandbox/case/tty.nix4
-rw-r--r--test/sandbox/test.py2
-rw-r--r--test/test.py8
12 files changed, 53 insertions, 34 deletions
diff --git a/cmd/hpkg/test/test.py b/cmd/hpkg/test/test.py
index 5a199acc..d491def3 100644
--- a/cmd/hpkg/test/test.py
+++ b/cmd/hpkg/test/test.py
@@ -90,7 +90,7 @@ machine.wait_for_file("/tmp/hpkg-install-ok")
swaymsg("exec hpkg -v start org.codeberg.dnkl.foot")
wait_for_window("hakurei@machine-foot")
machine.send_chars("clear; wayland-info && touch /tmp/success-client\n")
-machine.wait_for_file("/tmp/hakurei.1000/tmpdir/2/success-client")
+machine.wait_for_file("/tmp/hakurei.0/tmpdir/2/success-client")
collect_state_ui("app_wayland")
check_state("foot", {"wayland": True, "dbus": True, "pulse": True})
# Verify acl on XDG_RUNTIME_DIR:
diff --git a/hst/hst.go b/hst/hst.go
index 6549450c..d9c1168b 100644
--- a/hst/hst.go
+++ b/hst/hst.go
@@ -12,16 +12,18 @@ import (
type Paths struct {
// temporary directory returned by [os.TempDir] (usually `/tmp`)
TempDir *container.Absolute `json:"temp_dir"`
- // path to shared directory (usually `/tmp/hakurei.%d`)
+ // path to shared directory (usually `/tmp/hakurei.%d`, [Info.User])
SharePath *container.Absolute `json:"share_path"`
- // XDG_RUNTIME_DIR value (usually `/run/user/%d`)
+ // XDG_RUNTIME_DIR value (usually `/run/user/%d`, uid)
RuntimePath *container.Absolute `json:"runtime_path"`
// application runtime directory (usually `/run/user/%d/hakurei`)
RunDirPath *container.Absolute `json:"run_dir_path"`
}
type Info struct {
+ // User is the userid according to hsu.
User int `json:"user"`
+
Paths
}
diff --git a/internal/sys/interface.go b/internal/sys/interface.go
index 5dbe18e6..ed765ece 100644
--- a/internal/sys/interface.go
+++ b/internal/sys/interface.go
@@ -22,9 +22,9 @@ type State interface {
LookupEnv(key string) (string, bool)
// TempDir provides [os.TempDir].
TempDir() string
- // LookPath provides [exec.LookPath].
+ // LookPath provides exec.LookPath.
LookPath(file string) (string, error)
- // MustExecutable provides [proc.MustExecutable].
+ // MustExecutable provides [container.MustExecutable].
MustExecutable() string
// LookupGroup provides [user.LookupGroup].
LookupGroup(name string) (*user.Group, error)
@@ -32,9 +32,9 @@ type State interface {
ReadDir(name string) ([]fs.DirEntry, error)
// Stat provides [os.Stat].
Stat(name string) (fs.FileInfo, error)
- // Open provides [os.Open]
+ // Open provides [os.Open].
Open(name string) (fs.File, error)
- // EvalSymlinks provides [filepath.EvalSymlinks]
+ // EvalSymlinks provides filepath.EvalSymlinks.
EvalSymlinks(path string) (string, error)
// Exit provides [os.Exit].
Exit(code int)
@@ -45,19 +45,28 @@ type State interface {
// Paths returns a populated [hst.Paths] struct.
Paths() hst.Paths
// Uid invokes hsu and returns target uid.
- // Any errors returned by Uid is already wrapped [fmsg.BaseError].
- Uid(aid int) (int, error)
+ // Any errors returned by Uid is already wrapped [hlog.BaseError].
+ Uid(identity int) (int, error)
+}
+
+// GetUserID obtains user id from hsu by querying uid of identity 0.
+func GetUserID(os State) (int, error) {
+ if uid, err := os.Uid(0); err != nil {
+ return -1, err
+ } else {
+ return (uid / 10000) - 100, nil
+ }
}
// CopyPaths is a generic implementation of [hst.Paths].
-func CopyPaths(os State, v *hst.Paths) {
+func CopyPaths(os State, v *hst.Paths, userid int) {
if tempDir, err := container.NewAbs(os.TempDir()); err != nil {
log.Fatalf("invalid TMPDIR: %v", err)
} else {
v.TempDir = tempDir
}
- v.SharePath = v.TempDir.Append("hakurei." + strconv.Itoa(os.Getuid()))
+ v.SharePath = v.TempDir.Append("hakurei." + strconv.Itoa(userid))
hlog.Verbosef("process share directory at %q", v.SharePath)
r, _ := os.LookupEnv(xdgRuntimeDir)
diff --git a/internal/sys/std.go b/internal/sys/std.go
index 89fdd289..828cbc45 100644
--- a/internal/sys/std.go
+++ b/internal/sys/std.go
@@ -49,11 +49,19 @@ func (s *Std) Printf(format string, v ...any) { hlog.Verbosef(form
const xdgRuntimeDir = "XDG_RUNTIME_DIR"
func (s *Std) Paths() hst.Paths {
- s.pathsOnce.Do(func() { CopyPaths(s, &s.paths) })
+ s.pathsOnce.Do(func() {
+ if userid, err := GetUserID(s); err != nil {
+ hlog.PrintBaseError(err, "cannot obtain user id from hsu:")
+ hlog.BeforeExit()
+ s.Exit(1)
+ } else {
+ CopyPaths(s, &s.paths, userid)
+ }
+ })
return s.paths
}
-func (s *Std) Uid(aid int) (int, error) {
+func (s *Std) Uid(identity int) (int, error) {
s.uidOnce.Do(func() {
s.uidCopy = make(map[int]struct {
uid int
@@ -63,7 +71,7 @@ func (s *Std) Uid(aid int) (int, error) {
{
s.uidMu.RLock()
- u, ok := s.uidCopy[aid]
+ u, ok := s.uidCopy[identity]
s.uidMu.RUnlock()
if ok {
return u.uid, u.err
@@ -77,7 +85,7 @@ func (s *Std) Uid(aid int) (int, error) {
uid int
err error
}{}
- defer func() { s.uidCopy[aid] = u }()
+ defer func() { s.uidCopy[identity] = u }()
u.uid = -1
hsuPath := internal.MustHsuPath()
@@ -85,7 +93,7 @@ func (s *Std) Uid(aid int) (int, error) {
cmd := exec.Command(hsuPath)
cmd.Path = hsuPath
cmd.Stderr = os.Stderr // pass through fatal messages
- cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(aid)}
+ cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(identity)}
cmd.Dir = container.FHSRoot
var (
p []byte
@@ -95,7 +103,7 @@ func (s *Std) Uid(aid int) (int, error) {
if p, u.err = cmd.Output(); u.err == nil {
u.uid, u.err = strconv.Atoi(string(p))
if u.err != nil {
- u.err = hlog.WrapErrSuffix(u.err, "cannot parse uid from hsu:")
+ u.err = hlog.WrapErr(u.err, "invalid uid string from hsu")
}
} else if errors.As(u.err, &exitError) && exitError != nil && exitError.ExitCode() == 1 {
u.err = hlog.WrapErr(syscall.EACCES, "") // hsu prints to stderr in this case
diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix
index 5d607d92..831b6ab2 100644
--- a/test/sandbox/case/device.nix
+++ b/test/sandbox/case/device.nix
@@ -230,8 +230,8 @@ in
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
- (ent "/tmp/hakurei.1000/runtime/4" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/4" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix
index c18bf796..486d4390 100644
--- a/test/sandbox/case/mapuid.nix
+++ b/test/sandbox/case/mapuid.nix
@@ -257,8 +257,8 @@ in
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
- (ent "/tmp/hakurei.1000/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
(ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix
index 14b62b40..6bad3e73 100644
--- a/test/sandbox/case/pd.nix
+++ b/test/sandbox/case/pd.nix
@@ -186,8 +186,8 @@
(ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
(ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000")
- (ent "/tmp/hakurei.1000/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
];
diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix
index c87ab46c..1fdc5925 100644
--- a/test/sandbox/case/pdlike.nix
+++ b/test/sandbox/case/pdlike.nix
@@ -252,8 +252,8 @@ in
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
- (ent "/tmp/hakurei.1000/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix
index d8f6879e..721659f5 100644
--- a/test/sandbox/case/preset.nix
+++ b/test/sandbox/case/preset.nix
@@ -250,8 +250,8 @@ in
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
- (ent "/tmp/hakurei.1000/runtime/1" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/1" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/1" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/1" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix
index 15b60ad0..0aed7831 100644
--- a/test/sandbox/case/tty.nix
+++ b/test/sandbox/case/tty.nix
@@ -262,8 +262,8 @@ in
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
- (ent "/tmp/hakurei.1000/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/tmp/hakurei.1000/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/hakurei.0/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/test.py b/test/sandbox/test.py
index 6ae3e145..5997b890 100644
--- a/test/sandbox/test.py
+++ b/test/sandbox/test.py
@@ -60,7 +60,7 @@ check_offset = 0
def check_sandbox(name):
global check_offset
swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}")
- machine.wait_for_file(f"/tmp/hakurei.1000/tmpdir/{check_offset}/sandbox-ok", timeout=15)
+ machine.wait_for_file(f"/tmp/hakurei.0/tmpdir/{check_offset}/sandbox-ok", timeout=15)
check_filter(check_offset, name, "hakurei-test")
check_offset += 1
diff --git a/test/test.py b/test/test.py
index c02766c7..96253534 100644
--- a/test/test.py
+++ b/test/test.py
@@ -113,12 +113,12 @@ def aid(offset):
def tmpdir_path(offset, name):
- return f"/tmp/hakurei.1000/tmpdir/{aid(offset)}/{name}"
+ return f"/tmp/hakurei.0/tmpdir/{aid(offset)}/{name}"
# Start hakurei permissive defaults outside Wayland session:
print(machine.succeed("sudo -u alice -i hakurei -v run -a 0 touch /tmp/pd-bare-ok"))
-machine.wait_for_file("/tmp/hakurei.1000/tmpdir/0/pd-bare-ok", timeout=5)
+machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-bare-ok", timeout=5)
# Verify silent output permissive defaults:
output = machine.succeed("sudo -u alice -i hakurei run -a 0 true &>/dev/stdout")
@@ -131,8 +131,8 @@ def silent_output_interrupt(flags):
wait_for_window("alice@machine")
# aid 0 does not have home-manager
machine.send_chars(f"exec hakurei run {flags}-a 0 sh -c 'export PATH=/run/current-system/sw/bin:$PATH && touch /tmp/pd-silent-ready && sleep infinity' &>/tmp/pd-silent\n")
- machine.wait_for_file("/tmp/hakurei.1000/tmpdir/0/pd-silent-ready", timeout=15)
- machine.succeed("rm /tmp/hakurei.1000/tmpdir/0/pd-silent-ready")
+ machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-silent-ready", timeout=15)
+ machine.succeed("rm /tmp/hakurei.0/tmpdir/0/pd-silent-ready")
machine.send_key("ctrl-c")
machine.wait_until_fails("pgrep foot", timeout=5)
machine.wait_until_fails(f"pgrep -u alice -f 'hakurei run {flags}-a 0 '", timeout=5)