Files
nezha_domains/integration/agentcompat/internal/scenario/transfer_sentinels.go
T
2026-07-20 04:51:20 +00:00

58 lines
1.9 KiB
Go

//go:build linux
package scenario
import (
"bytes"
"errors"
"fmt"
"os"
"path/filepath"
"github.com/nezhahq/nezha/integration/agentcompat/internal/fixture"
)
var transferSentinelContent = []byte("outside-transfer-root-sentinel")
type transferSentinels struct {
paths []string
}
func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (transferSentinels, error) {
directPath := filepath.Join(workspaceRoot, "outside-transfer-sentinel")
symlinkDirectory := filepath.Join(workspaceRoot, "outside-transfer-directory")
symlinkTarget := filepath.Join(symlinkDirectory, "target-sentinel")
if err := os.Mkdir(symlinkDirectory, 0o700); err != nil {
return transferSentinels{}, fmt.Errorf("create transfer sentinel directory: %w", err)
}
for _, path := range []string{directPath, symlinkTarget} {
if err := os.WriteFile(path, transferSentinelContent, 0o600); err != nil {
return transferSentinels{}, fmt.Errorf("write transfer sentinel: %w", err)
}
}
symlinkPath := filepath.Join(root.Absolute(), "linked")
if err := os.Symlink(symlinkDirectory, symlinkPath); err != nil {
return transferSentinels{}, fmt.Errorf("create transfer sentinel symlink: %w", err)
}
if _, err := root.Path("../outside-transfer-sentinel"); err == nil {
return transferSentinels{}, errors.New("transfer AgentPath accepted parent escape")
}
if _, err := root.Path("linked/target-sentinel"); err == nil {
return transferSentinels{}, errors.New("transfer AgentPath accepted symlink parent")
}
return transferSentinels{paths: []string{directPath, symlinkTarget}}, nil
}
func (sentinels transferSentinels) unchanged() (bool, error) {
for _, path := range sentinels.paths {
content, err := os.ReadFile(path)
if err != nil {
return false, fmt.Errorf("read transfer sentinel: %w", err)
}
if !bytes.Equal(content, transferSentinelContent) {
return false, nil
}
}
return true, nil
}