package host import ( "context" "crypto/sha256" "debug/buildinfo" "encoding/hex" "io" "os" "github.com/carlosframework/platform/internal/hostbox" "github.com/carlosframework/platform/internal/instancectl" "github.com/carlosframework/platform/internal/rootstate" "github.com/carlosframework/platform/internal/safefile" ) func (h *ClaimLaunchRoot) rootInstalledProgram(ctx context.Context, q hostbox.RoleLaunchRequest, started instancectl.ClaimUnitStarted, observed ClaimLaunchObserved) (string, error) { if q.Reservation == nil || q.Spec == nil || observed.TenantPID <= 0 || observed.TenantStart == "" || observed.Running != q.Reservation.Executable || observed.Executable != observed.Running { return "", os.ErrPermission } if err := h.ValidateExecutable(q.Reservation.Target.Host, q.Executable, q.Spec.Digest); err != nil { return "", err } f, err := safefile.OpenFile(q.Executable, os.O_RDONLY, 0) if err != nil { return "", err } defer f.Close() id, err := rootstate.Identity(f) if err != nil { return "", err } if id.Device != observed.Running.Device || id.Inode != observed.Running.Inode { return "", os.ErrPermission } digest := sha256.New() if _, err := io.Copy(digest, f); err != nil { return "", err } if hex.EncodeToString(digest.Sum(nil)) != q.Spec.Digest { return "", os.ErrPermission } program := "" if info, err := buildinfo.Read(f); err == nil { program = info.Path } again, err := h.Kernel.Observe(started) if err != nil || again != observed { return "", os.ErrPermission } if err := h.Units.Same(ctx, started); err != nil { return "", err } return program, nil }