From 519869a00360ffb8b6ff5e2e21902d84d937e271 Mon Sep 17 00:00:00 2001 From: ollie Date: Sun, 19 Jul 2026 11:33:34 +0200 Subject: [PATCH] execute: ensure elevate adapter is running before elevated calls Add ensureElevateAdapter() which probes the adapter socket and starts elevate-adapter-start if unreachable. Runs in the execute server process (outside the sandbox) so the adapter starts unsandboxed. --- pkg/tools/execute/server.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pkg/tools/execute/server.go b/pkg/tools/execute/server.go index 18db4a2..aa167d3 100644 --- a/pkg/tools/execute/server.go +++ b/pkg/tools/execute/server.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "net" "os" "os/exec" "path/filepath" @@ -404,6 +405,35 @@ func (e *Server) Close() { } } +// ensureElevateAdapter checks if the elevate adapter is reachable and starts +// it if not. Runs outside the sandbox so the adapter process is unsandboxed. +func ensureElevateAdapter() { + sock := os.Getenv("OLLIE_ELEVATE_SOCKET") + if sock == "" { + xdg := os.Getenv("XDG_RUNTIME_DIR") + if xdg == "" { + return + } + sock = filepath.Join(xdg, "ollie", "elevate.sock") + } + // Quick connect test + conn, err := net.DialTimeout("unix", sock, 500*time.Millisecond) + if err == nil { + conn.Close() + return + } + // Not running — start it + startScript := filepath.Join(PluginsPath(), "elevate-adapter-start") + if _, err := os.Stat(startScript); err != nil { + return + } + cmd := exec.Command(startScript) //nolint:gosec + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + _ = cmd.Run() + // Give it a moment to bind the socket + time.Sleep(300 * time.Millisecond) +} + // executeElevated runs cmd outside the sandbox via x/elevate. // Returns (output, error); a non-zero exit code is treated as an error. // If detach is true, the process is immediately backgrounded into the detach registry. @@ -413,6 +443,8 @@ func (e *Server) executeElevated(ctx context.Context, cmd, dir string, timeout i return "", fmt.Errorf("elevation not available: x/elevate not found") } + ensureElevateAdapter() + wantDetach := len(detach) > 0 && detach[0] var cancel context.CancelFunc