Dashboard › opencode › Session 0QTDM3WMXvjj
0QTDM3WMXvjjR7jRrPerform an independent, read-only security review of every file under /home/byk/.local/share/opencode-v2-pilot/supervisor. Inspect exact current source, protocol, units, tests, docs, and pinned modules. Threat model same-UID malicious PTY descendants and untrusted model command/input/output. Focus on SO_PEERCRED/SO_PEERPIDFD authenticity and PID reuse, systemd MainPID/cgroup/invocation checks, inherited authenticated fds, SCM_RIGHTS and cwd TOCTOU, D-Bus transient unit injection, unit properties, Docker/D-Bus escape, cgroup containment, symlink/path attacks, environment/credential leaks, protocol desync/DoS, output/input memory bounds, session admission races, orphan cleanup, supervisor crashes/restarts, root-service attack surface, launcher privileges, and filesystem permissions. Do not edit files, install/start services, or run privileged operations. You may run unprivileged tests. Cite current file:line evidence and classify each finding PASS/CONCERN/MUST-FIX. End exactly MERGE or DO-NOT-MERGE.
I’ll inventory the exact supervisor tree, read every source, protocol, unit, test, doc, and pinned dependency file, then trace each trust boundary against the stated same-UID and untrusted-I/O threat model. I will keep the review read-only, run only safe unprivileged checks, and report findings with exact line evidence.
[
{
"content": "Inventory every file and identify applicable repository guidance and pinned dependency manifests",
"status": "in_progress",
"priority": "high"
},
{
"content": "Read and trace source, protocol, units, tests, docs, and pinned module implementations",
"status": "pending",
"priority": "high"
},
{
"content": "Run safe unprivileged static and targeted tests without starting services",
"status": "pending",
"priority": "high"
},
{
"content": "Map evidence to every requested threat category and classify findings",
"status": "pending",
"priority": "high"
},
{
"content": "Deliver independent review with exact file:line citations and final merge verdict",
"status": "pending",
"priority": "high"
}
]
/home/byk/.local/share/opencode-v2-pilot/supervisor/ROOT-ACCEPTANCE.md /home/byk/.local/share/opencode-v2-pilot/supervisor/bin/opencode-pty-launcher /home/byk/.local/share/opencode-v2-pilot/supervisor/bin/opencode-pty-supervisor /home/byk/.local/share/opencode-v2-pilot/supervisor/PROTOCOL.md /home/byk/.local/share/opencode-v2-pilot/supervisor/opencode-pty.slice /home/byk/.local/share/opencode-v2-pilot/supervisor/opencode-pty-supervisor.service /home/byk/.local/share/opencode-v2-pilot/supervisor/go.sum /home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/supervisor/main.go /home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/launcher/main_test.go /home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/launcher/main.go /home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/auth_test.go /home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/server_test.go /home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/server.go /home/byk/.lo...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor</path> <type>directory</type> <entries> bin/ cmd/ go.mod go.sum internal/ opencode-pty-supervisor.service opencode-pty.slice PROTOCOL.md ROOT-ACCEPTANCE.md (9 entries) </entries>
/home/byk/.local/share/opencode-v2-pilot/config/opencode/node_modules/effect/AGENTS.md
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/go.mod</path> <type>file</type> <content> 1: module opencode-pty-supervisor 2: 3: go 1.22 4: 5: require ( 6: github.com/coreos/go-systemd/v22 v22.5.0 7: github.com/godbus/dbus/v5 v5.1.0 8: golang.org/x/sys v0.20.0 9: ) (End of file - total 9 lines) </content>
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/go.sum</path> <type>file</type> <content> 1: github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= 2: github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 3: github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 4: github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= 5: github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 6: golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 7: golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= (End of file - total 7 lines) </content>
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/PROTOCOL.md</path> <type>file</type> <content> 1: # PTY supervisor protocol 2: 3: The protocol uses one Unix `SOCK_STREAM` connection for one PTY. Every frame has a 12-byte header: 4: 5: - bytes 0–3: `OPTY` 6: - byte 4: version `1` 7: - byte 5: type 8: - bytes 6–7: zero 9: - bytes 8–11: unsigned big-endian payload length, at most 65536 10: 11: The authenticated client sends one start frame (`1`) with exactly one `SCM_RIGHTS` directory descriptor. Its payload contains unsigned big-endian `st_dev` and `st_ino` values, an optional runtime in seconds, an argument count, and length-prefixed argument bytes. The supervisor compares the descriptor's metadata, requires a directory, and never resolves a client path. 12: 13: After admission, the client sends input frames (`2`) of at most 32768 bytes. The supervisor sends output (`3`), exit (`4`), or error (`5`) frames. ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/ROOT-ACCEPTANCE.md</path> <type>file</type> <content> 1: # Root-only acceptance 2: 3: Do not start or enable the service until every check below passes. 4: 5: 1. Install both freshly built binaries in a root-controlled path. Never execute the root supervisor or transient launcher from the user-writable source tree. 6: 7: ```sh 8: sudo install -d -o root -g root -m 0755 /usr/local/libexec 9: sudo install -o root -g root -m 0755 bin/opencode-pty-supervisor /usr/local/libexec/opencode-pty-supervisor 10: sudo install -o root -g root -m 0755 bin/opencode-pty-launcher /usr/local/libexec/opencode-pty-launcher 11: ``` 12: 13: 2. Copy the reviewed service and slice files to `/etc/systemd/system`, owned by root and mode `0644`, then run `systemd-analyze verify` on the installed files. Do not enable or start either unit yet. 14: 15: 3. ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/opencode-pty-supervisor.service</path> <type>file</type> <content> 1: [Unit] 2: Description=OpenCode PTY supervisor 3: After=dbus.service 4: Requires=dbus.service 5: 6: [Service] 7: Type=exec 8: User=root 9: Group=byk 10: ExecStart=/usr/local/libexec/opencode-pty-supervisor 11: RuntimeDirectory=opencode-pty 12: RuntimeDirectoryMode=0750 13: RuntimeDirectoryPreserve=no 14: NoNewPrivileges=yes 15: UMask=0077 16: KillMode=control-group 17: KillSignal=SIGTERM 18: FinalKillSignal=SIGKILL 19: SendSIGKILL=yes 20: TimeoutStopSec=20s 21: OOMPolicy=kill 22: Delegate=no 23: RestrictAddressFamilies=AF_UNIX 24: PrivateTmp=yes 25: ProtectSystem=strict 26: ProtectKernelTunables=yes 27: ProtectKernelModules=yes 28: ProtectKernelLogs=yes 29: ProtectControlGroups=yes 30: ProtectClock=yes 31: RestrictSUIDSGID=yes 32: LockPersonality=yes 33: MemoryDenyWriteExecute=yes 34: 35: [Install] 36: WantedBy=multi-user.target (End of file - total 36 ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/opencode-pty.slice</path> <type>file</type> <content> 1: [Unit] 2: Description=OpenCode isolated PTY sessions 3: Before=slices.target 4: 5: [Slice] 6: CPUAccounting=yes 7: MemoryAccounting=yes 8: TasksAccounting=yes 9: MemoryMax=2G 10: TasksMax=512 (End of file - total 10 lines) </content>
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/supervisor/main.go</path>
<type>file</type>
<content>
1: package main
2:
3: import (
4: "context"
5: "fmt"
6: "os"
7: "os/signal"
8: "syscall"
9:
10: "opencode-pty-supervisor/internal/supervisor"
11: )
12:
13: func main() {
14: ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
15: defer cancel()
16: manager, err := supervisor.NewSystemdManager(ctx)
17: if err != nil {
18: fmt.Fprintln(os.Stderr, err)
19: os.Exit(1)
20: }
21: defer manager.Close()
22: if err := supervisor.NewServer(manager).Serve(ctx); err != nil {
23: fmt.Fprintln(os.Stderr, err)
24: os.Exit(1)
25: }
26: }
(End of file - total 26 lines)
</content>
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/launcher/main.go</path>
<type>file</type>
<content>
1: package main
2:
3: import (
4: "encoding/base64"
5: "errors"
6: "fmt"
7: "os"
8: "strings"
9: "syscall"
10: )
11:
12: const (
13: maxArgs = 128
14: maxArgSize = 4096
15: )
16:
17: func main() {
18: if err := run(os.Args[1:]); err != nil {
19: fmt.Fprintln(os.Stderr, err)
20: os.Exit(1)
21: }
22: }
23:
24: func run(encoded []string) error {
25: command, err := decodeCommand(encoded)
26: if err != nil {
27: return err
28: }
29: if err := syscall.Fchdir(2); err != nil {
30: return fmt.Errorf("fchdir approved cwd: %w", err)
31: }
32: if err := syscall.Dup2(1, 2); err != nil {
33: return fmt.Errorf("replace cwd descriptor: %w", err)
34: }
35: os.Clearenv()
36: fixed := map[string]string{
37: "HOME": "/home/byk",
38: "LANG": "C.UTF-8",
39: "LOGNAME": "byk",
40: "PATH": "/usr/local/bin:/usr/bin:/bin",
41: "TERM": ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/cmd/launcher/main_test.go</path>
<type>file</type>
<content>
1: package main
2:
3: import (
4: "bytes"
5: "encoding/base64"
6: "fmt"
7: "os"
8: "os/exec"
9: "strings"
10: "testing"
11: )
12:
13: func TestDecodeCommandQuotesEveryArgument(t *testing.T) {
14: encoded := []string{
15: "a" + base64.RawURLEncoding.EncodeToString([]byte("printf")),
16: "a" + base64.RawURLEncoding.EncodeToString([]byte("%s\\n")),
17: "a" + base64.RawURLEncoding.EncodeToString([]byte("a'b; $(id)")),
18: "a",
19: }
20: got, err := decodeCommand(encoded)
21: if err != nil {
22: t.Fatal(err)
23: }
24: want := "'printf' '%s\\n' 'a'\\''b; $(id)' ''"
25: if got != want {
26: t.Fatalf("got %q, want %q", got, want)
27: }
28: }
29:
30: func TestDecodeCommandRejectsInvalidGrammar(t *testing.T) {
31: if _, err := decodeCommand([]string{"bad="}); err == nil {
32: t.Fatal("expected error")
33: }
34: }
35:
36: func ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/protocol/frame.go</path>
<type>file</type>
<content>
1: package protocol
2:
3: import (
4: "encoding/binary"
5: "errors"
6: "fmt"
7: "io"
8: )
9:
10: const (
11: HeaderSize = 12
12: MaxFrameSize = 64 * 1024
13: MaxIOPayloadSize = 32 * 1024
14: Version = 1
15:
16: TypeStart = 1
17: TypeInput = 2
18: TypeOutput = 3
19: TypeExit = 4
20: TypeError = 5
21:
22: MaxArgs = 128
23: MaxArgSize = 4096
24: MaxRuntimeSec = 3600
25: )
26:
27: var (
28: magic = [4]byte{'O', 'P', 'T', 'Y'}
29: ErrInvalidFrame = errors.New("invalid frame")
30: ErrFrameTooLarge = errors.New("frame too large")
31: )
32:
33: type Frame struct {
34: Type byte
35: Payload []byte
36: }
37:
38: type Start struct {
39: Device uint64
40: Inode uint64
41: RuntimeSec uint32
42: Args []string
43: }
44:
45: func ReadFrame(reader io.Reader) (Frame, error) {
46: header := ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/protocol/frame_test.go</path>
<type>file</type>
<content>
1: package protocol
2:
3: import (
4: "bytes"
5: "errors"
6: "strings"
7: "testing"
8: )
9:
10: func TestStartRoundTrip(t *testing.T) {
11: want := Start{Device: 12, Inode: 34, RuntimeSec: 60, Args: []string{"printf", "%s", "hello world"}}
12: payload, err := EncodeStart(want)
13: if err != nil {
14: t.Fatal(err)
15: }
16: got, err := DecodeStart(payload)
17: if err != nil {
18: t.Fatal(err)
19: }
20: if got.Device != want.Device || got.Inode != want.Inode || got.RuntimeSec != want.RuntimeSec || strings.Join(got.Args, "\x00") != strings.Join(want.Args, "\x00") {
21: t.Fatalf("got %#v, want %#v", got, want)
22: }
23: }
24:
25: func TestFrameRoundTrip(t *testing.T) {
26: var buffer bytes.Buffer
27: want := Frame{Type: TypeInput, Payload: []byte("hello")}
28: if err := WriteFrame(&buffer, want); err != nil {
29: t.Fatal(err)
30: }
31: ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/auth.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "context"
5: "errors"
6: "fmt"
7: "net"
8:
9: "golang.org/x/sys/unix"
10: )
11:
12: func authenticate(ctx context.Context, connection *net.UnixConn, manager unitManager) error {
13: credential, pidfd, err := peerIdentity(connection)
14: if err != nil {
15: return err
16: }
17: defer unix.Close(pidfd)
18: mainPID, activeState, controlGroup, err := manager.ClientState(ctx)
19: if err != nil {
20: return fmt.Errorf("query client service: %w", err)
21: }
22: if credential.Pid <= 0 || uint32(credential.Pid) != mainPID {
23: return errors.New("peer is not the current service MainPID")
24: }
25: if activeState != "active" || controlGroup != expectedClientCgroup {
26: return errors.New("client service is not active in the expected cgroup")
27: }
28: if err := unix.PidfdSendSignal(pidfd, 0, nil, 0); err != ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/auth_test.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "context"
5: "os"
6: "testing"
7: )
8:
9: type authenticationManager struct {
10: pid uint32
11: activeState string
12: cgroup string
13: }
14:
15: func (manager *authenticationManager) ClientState(context.Context) (uint32, string, string, error) {
16: return manager.pid, manager.activeState, manager.cgroup, nil
17: }
18:
19: func (*authenticationManager) Start(context.Context, string, []string, *os.File, *os.File, uint32) error {
20: return nil
21: }
22:
23: func (*authenticationManager) StopAndWait(context.Context, string) error { return nil }
24: func (*authenticationManager) Wait(context.Context, string) (unitResult, error) {
25: return unitResult{}, nil
26: }
27: func (*authenticationManager) CleanupOrphans(context.Context) error { return nil }
28: func (*authenticationManager) Close() ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/systemd.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "context"
5: "encoding/base64"
6: "errors"
7: "fmt"
8: "os"
9: "regexp"
10: "time"
11:
12: systemddbus "github.com/coreos/go-systemd/v22/dbus"
13: "github.com/godbus/dbus/v5"
14: )
15:
16: const (
17: clientService = "opencode-v2.service"
18: supervisorService = "opencode-pty-supervisor.service"
19: ptySlice = "opencode-pty.slice"
20: expectedClientCgroup = "/system.slice/opencode-v2.service"
21: launcherPath = "/usr/local/libexec/opencode-pty-launcher"
22: unitPrefix = "opencode-pty-"
23: unitSuffix = ".service"
24: stopTimeout = 15 * time.Second
25: )
26:
27: var unitPattern = regexp.MustCompile(`^opencode-pty-[0-9a-f]{32}\.service$`)
28:
29: type unitResult struct {
30: Result string
31: ExecMainCode int32
32: ExecMainStatus ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/systemd_test.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "os"
5: "testing"
6:
7: "github.com/godbus/dbus/v5"
8: )
9:
10: func TestUnitNameGrammar(t *testing.T) {
11: valid := "opencode-pty-0123456789abcdef0123456789abcdef.service"
12: if !validUnitName(valid) {
13: t.Fatalf("rejected %q", valid)
14: }
15: for _, invalid := range []string{
16: "opencode-pty-.service",
17: "opencode-pty-0123456789ABCDEF0123456789ABCDEF.service",
18: "opencode-pty-0123456789abcdef0123456789abcdef.scope",
19: "opencode-pty-0123456789abcdef0123456789abcdef.service/../x",
20: } {
21: if validUnitName(invalid) {
22: t.Fatalf("accepted %q", invalid)
23: }
24: }
25: }
26:
27: func TestUnitPropertiesAreFixed(t *testing.T) {
28: stream, err := os.Open("/dev/null")
29: if err != nil {
30: t.Fatal(err)
31: }
32: defer stream.Close()
33: properties := ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/server.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "context"
5: "crypto/rand"
6: "encoding/binary"
7: "errors"
8: "fmt"
9: "io"
10: "net"
11: "os"
12: "os/user"
13: "strconv"
14: "sync"
15: "syscall"
16: "time"
17:
18: "opencode-pty-supervisor/internal/protocol"
19:
20: "golang.org/x/sys/unix"
21: )
22:
23: const (
24: socketPath = "/run/opencode-pty/supervisor.sock"
25: maxSessions = 16
26: socketBufferSize = 128 * 1024
27: handshakeTimeout = 5 * time.Second
28: )
29:
30: type Server struct {
31: manager unitManager
32: listener *net.UnixListener
33: sessions chan struct{}
34: connections map[*net.UnixConn]struct{}
35: mutex sync.Mutex
36: wait sync.WaitGroup
37: }
38:
39: func NewServer(manager unitManager) *Server {
40: return &Server{
41: manager: manager,
42: sessions: make(chan struct{}, ...
<path>/home/byk/.local/share/opencode-v2-pilot/supervisor/internal/supervisor/server_test.go</path>
<type>file</type>
<content>
1: package supervisor
2:
3: import (
4: "bytes"
5: "encoding/binary"
6: "net"
7: "os"
8: "syscall"
9: "testing"
10:
11: "opencode-pty-supervisor/internal/protocol"
12:
13: "golang.org/x/sys/unix"
14: )
15:
16: func TestReceiveStartWithDirectoryDescriptor(t *testing.T) {
17: server, client := unixConnectionPair(t)
18: defer server.Close()
19: defer client.Close()
20: cwd, err := os.Open(".")
21: if err != nil {
22: t.Fatal(err)
23: }
24: defer cwd.Close()
25: info, err := cwd.Stat()
26: if err != nil {
27: t.Fatal(err)
28: }
29: stat := info.Sys().(*syscall.Stat_t)
30: payload, err := protocol.EncodeStart(protocol.Start{Device: uint64(stat.Dev), Inode: stat.Ino, Args: []string{"printf", "ok"}})
31: if err != nil {
32: t.Fatal(err)
33: }
34: packet, err := protocol.MarshalFrame(protocol.Frame{Type: protocol.TypeStart, Payload: ...
The first source pass shows that the design does pin the peer with SO_PEERPIDFD, passes cwd by descriptor, fixes transient-unit names and arguments, and bounds individual frames. I am now checking the exact dependency implementations and effective unit/file controls because several guarantees depend on D-Bus FD marshalling, signal subscription behavior, systemd property semantics, and host permissions rather than this code alone.
/home/byk/go/pkg/mod /home/byk/go go1.22.2
bin/opencode-pty-launcher: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=6RQ2SGk3gMRB14wEJKBx/BaGu9vt8LS5pWElxxNOG/QVBBd8KFMpoFP2E7P7KR/yoMXHpawFoMlTKoHDWWm, with debug_info, not stripped bin/opencode-pty-supervisor: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=QNSxF-E7mbp_ecMBvxWo/CB3LcygzrBmD-duo2HiN/hPOfoy4MwUTbZ_KFbJsh/UgIoIOfxoJ_nI8w5bwhb, with debug_info, not stripped f97c546f46b6f2b818638c69ced6e461174549207225cd034ecf65da1017c20d bin/opencode-pty-launcher 65f00b20269806f513f5c6a479a7ca051db6a334ca4549121e5b813bbdf75989 bin/opencode-pty-supervisor drwxr-xr-x 755 byk:byk . drwxr-xr-x 755 byk:byk bin drwxr-xr-x 755 byk:byk cmd drwxr-xr-x 755 byk:byk internal -rw-r--r-- 644 byk:byk go.mod -rw-r--r-- 644 byk:byk go.sum -rw-r--r-- 644 byk:byk PROTOCOL.md -rw-r--r-- 644 byk:byk ROOT-ACCEPTANCE.md -rw-r--r-- 644 byk:byk opencode-pty-supervisor.service -rw-r--r-- 644 ...
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/subscription_test.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/subscription_set_test.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/subscription_set.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/subscription.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/set_test.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/set.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/properties.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods_test.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/dbus_test.go /home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/dbus.go
Found 11 matches
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/properties.go:
Line 57: func PropExecStart(command []string, uncleanIsFailure bool) Property {
Line 138: func PropBindsTo(units ...string) Property {
Line 186: func PropAfter(units ...string) Property {
Line 222: func PropSlice(slice string) Property {
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go:
Line 191: func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) {
Line 272: func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) {
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/dbus.go:
Line 122: conn, err := NewSystemConnectionContext(ctx)
Line 129: // Deprecated: use NewSystemConnectionContext instead.
Line 131: return NewSystemConnectionContext(context.Background())
Line 134: // ...
<path>/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/properties.go</path> <type>file</type> <content> 1: // Copyright 2015 CoreOS, Inc. 2: // 3: // Licensed under the Apache License, Version 2.0 (the "License"); 4: // you may not use this file except in compliance with the License. 5: // You may obtain a copy of the License at 6: // 7: // http://www.apache.org/licenses/LICENSE-2.0 8: // 9: // Unless required by applicable law or agreed to in writing, software 10: // distributed under the License is distributed on an "AS IS" BASIS, 11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12: // See the License for the specific language governing permissions and 13: // limitations under the License. 14: 15: package dbus 16: 17: import ( 18: "github.com/godbus/dbus/v5" 19: ) 20: 21: // From the systemd docs: 22: // 23: // The properties array of StartTransientUnit() may take many of the settings 24: // that may also be configured in unit ...
<path>/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go</path>
<type>file</type>
<content>
175: // ReloadOrTryRestartUnitContext attempts a reload if the unit supports it,
176: // and use a "Try" flavored restart otherwise.
177: func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
178: return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
179: }
180:
181: // Deprecated: use StartTransientUnitContext instead.
182: func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) {
183: return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch)
184: }
185:
186: // StartTransientUnitContext may be used to create and start a transient unit, which
187: // will be released as soon as it is not running or referenced anymore or the
188: // system is rebooted. ...
Found 50 matches
/home/byk/go/pkg/mod/github.com/godbus/dbus/v5@v5.1.0/transport_unix_test.go:
Line 15: func (t unixFDTest) Testfd(fd UnixFD) (string, *Error) {
Line 28: fd := v.Value().(UnixFD)
Line 39: Fd UnixFD
Line 56: u := s[0].(UnixFD)
Line 72: fd := sv.V.Value().(UnixFD)
Line 82: func TestUnixFDs(t *testing.T) {
Line 102: err = obj.Call("com.github.guelfey.test.Testfd", 0, UnixFD(r.Fd())).Store(&s)
Line 113: err = obj.Call("com.github.guelfey.test.Testvariant", 0, MakeVariant(UnixFD(r.Fd()))).Store(&s)
Line 124: err = obj.Call("com.github.guelfey.test.Teststruct", 0, unixfdContainer{UnixFD(r.Fd())}).Store(&s)
Line 135: err = obj.Call("com.github.guelfey.test.Testvariantstruct", 0, MakeVariant(unixfdContainer{UnixFD(r.Fd())})).Store(&s)
Line 146: err = obj.Call("com.github.guelfey.test.Teststructvariant", 0, variantContainer{MakeVariant(UnixFD(r.Fd()))}).Store(&s)
/home/byk/go/pkg/mod/github.com/godbus/dbus/v5@v5.1.0/transport_unix.go:
...
<path>/home/byk/go/pkg/mod/github.com/godbus/dbus/v5@v5.1.0/transport_unix.go</path>
<type>file</type>
<content>
110: // decode headers and look for unix fds
111: headerdata := make([]byte, hlen+4)
112: copy(headerdata, csheader[12:])
113: if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
114: return nil, err
115: }
116: dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0))
117: dec.pos = 12
118: vs, err := dec.Decode(Signature{"a(yv)"})
119: if err != nil {
120: return nil, err
121: }
122: Store(vs, &headers)
123: for _, v := range headers {
124: if v.Field == byte(FieldUnixFDs) {
125: unixfds, _ = v.Variant.value.(uint32)
126: }
127: }
128: all := make([]byte, 16+hlen+blen)
129: copy(all, csheader[:])
130: copy(all[16:], headerdata[4:])
131: if _, err := io.ReadFull(t.rdr, all[16+hlen:]); err != nil {
132: return nil, err
133: }
134: if unixfds != 0 {
135: if !t.hasUnixFDs {
136: return nil, errors.New("dbus: got unix ...
[
{
"content": "Inventory every file and identify applicable repository guidance and pinned dependency manifests",
"status": "completed",
"priority": "high"
},
{
"content": "Read and trace source, protocol, units, tests, docs, and pinned module implementations",
"status": "in_progress",
"priority": "high"
},
{
"content": "Run safe unprivileged static and targeted tests without starting services",
"status": "pending",
"priority": "high"
},
{
"content": "Map evidence to every requested threat category and classify findings",
"status": "pending",
"priority": "high"
},
{
"content": "Deliver independent review with exact file:line citations and final merge verdict",
"status": "pending",
"priority": "high"
}
]
<path>/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/dbus.go</path>
<type>file</type>
<content>
100: subStateSubscriber struct {
101: updateCh chan<- *SubStateUpdate
102: errCh chan<- error
103: sync.Mutex
104: ignore map[dbus.ObjectPath]int64
105: cleanIgnore int64
106: }
107: propertiesSubscriber struct {
108: updateCh chan<- *PropertiesUpdate
109: errCh chan<- error
110: sync.Mutex
111: }
112: }
113:
114: // Deprecated: use NewWithContext instead.
115: func New() (*Conn, error) {
116: return NewWithContext(context.Background())
117: }
118:
119: // NewWithContext establishes a connection to any available bus and authenticates.
120: // Callers should call Close() when done with the connection.
121: func NewWithContext(ctx context.Context) (*Conn, error) {
122: conn, err := NewSystemConnectionContext(ctx)
123: if err != nil && os.Geteuid() == 0 {
124: return NewSystemdConnectionContext(ctx)
125: }
126: return conn, err
127: ...
Found 3 matches
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go:
Line 54: func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) {
Line 122: func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
Line 477: func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) {
<path>/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go</path>
<type>file</type>
<content>
40: var id uint32
41: var job dbus.ObjectPath
42: var unit string
43: var result string
44: dbus.Store(signal.Body, &id, &job, &unit, &result)
45: c.jobListener.Lock()
46: out, ok := c.jobListener.jobs[job]
47: if ok {
48: out <- result
49: delete(c.jobListener.jobs, job)
50: }
51: c.jobListener.Unlock()
52: }
53:
54: func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) {
55: if ch != nil {
56: c.jobListener.Lock()
57: defer c.jobListener.Unlock()
58: }
59:
60: var p dbus.ObjectPath
61: err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p)
62: if err != nil {
63: return 0, err
64: }
65:
66: if ch != nil {
67: c.jobListener.jobs[p] = ch
68: }
69:
70: // ignore error since 0 is fine if conversion fails
71: jobID, _ := strconv.Atoi(path.Base(string(p)))
72:
73: return ...
all modules verified
ok opencode-pty-supervisor/cmd/launcher (cached) ? opencode-pty-supervisor/cmd/supervisor [no test files] ok opencode-pty-supervisor/internal/protocol (cached) ok opencode-pty-supervisor/internal/supervisor (cached)
(no output)
bin/opencode-pty-launcher: go1.22.2 path opencode-pty-supervisor/cmd/launcher mod opencode-pty-supervisor (devel) build -buildmode=exe build -compiler=gc build -trimpath=true build CGO_ENABLED=1 build GOARCH=amd64 build GOOS=linux build GOAMD64=v1 bin/opencode-pty-supervisor: go1.22.2 path opencode-pty-supervisor/cmd/supervisor mod opencode-pty-supervisor (devel) dep github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= dep github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= dep golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= build -buildmode=exe build -compiler=gc build -trimpath=true build CGO_ENABLED=1 build GOARCH=amd64 build GOOS=linux build GOAMD64=v1
systemd 255 (255.4-1ubuntu8.17) +PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
opencode-pty-supervisor.service: Command /usr/local/libexec/opencode-pty-supervisor is not executable: No such file or directory
NAME DESCRIPTION EXPOSURE ✗ RootDirectory=/RootImage= Service runs within the host's root directory 0.1 SupplementaryGroups= Service runs as root, option does not matter RemoveIPC= Service runs as root, option does not apply ✗ User=/DynamicUser= Service runs as root user 0.4 ✓ CapabilityBoundingSet=~CAP_SYS_TIME Service processes cannot change the system clock ✓ NoNewPrivileges= Service processes cannot acquire new privileges ...
MainPID=0 ControlGroup= Delegate=no User= Group= NoNewPrivileges=no KillMode=control-group LoadState=not-found ActiveState=inactive SubState=dead FragmentPath= InvocationID=
MISSING /run/opencode-pty MISSING /run/opencode-pty/supervisor.sock srw-rw-rw- 666 root:root socket /run/dbus/system_bus_socket srw-rw---- 660 root:docker socket /run/docker.sock srw-rw---- 660 root:docker socket /var/run/docker.sock srw-rw-rw- 666 byk:byk socket /run/user/1000/bus MISSING /run/user/1000/docker.sock MISSING /run/user/1000/podman/podman.sock MISSING /usr/local/libexec/opencode-pty-supervisor MISSING /usr/local/libexec/opencode-pty-launcher
uid=1000(byk) gid=1000(byk) groups=1000(byk),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),101(lxd),111(docker) script from util-linux 2.39.3 byk:1000:1000:/home/byk:/home/byk/.local/bin/xonsh
sh
ripgrep execution failed
MISSING /var/snap/lxd/common/lxd/unix.socket MISSING /var/lib/lxd/unix.socket MISSING /run/lxd.socket MISSING /run/snapd.socket srw-rw---- 660 root:root socket /run/containerd/containerd.sock MISSING /run/podman/podman.sock
<path>/proc/sys/kernel/yama/ptrace_scope</path> <type>file</type> <content> 1: 1 (End of file - total 1 lines) </content>
Two merge blockers are now concrete: the manager queries only org.freedesktop.systemd1.Unit, but MainPID, SubState, Result, and ExecMain* belong to the service interface; and the transient unit runs untrusted commands as byk without home, process, network, device, or supplementary-group isolation. I am validating these against systemd 255 and checking shutdown/orphan races before assigning the final severity set.
Failed to get property MainPID on interface org.freedesktop.systemd1.Unit: Unknown interface org.freedesktop.systemd1.Unit or property MainPID. u 811 s "active" Failed to get property SubState on interface org.freedesktop.systemd1.Service: Unknown interface org.freedesktop.systemd1.Service or property SubState.
Failed to get property Result on interface org.freedesktop.systemd1.Unit: Unknown interface org.freedesktop.systemd1.Unit or property Result. s "success" Failed to get property ExecMainCode on interface org.freedesktop.systemd1.Unit: Unknown interface org.freedesktop.systemd1.Unit or property ExecMainCode. i 0
drwxr-xr-x 6 byk byk 4096 Sep 8 04:47 /tmp/opencode
f97c546f46b6f2b818638c69ced6e461174549207225cd034ecf65da1017c20d bin/opencode-pty-launcher f97c546f46b6f2b818638c69ced6e461174549207225cd034ecf65da1017c20d /tmp/opencode/review-opencode-pty-launcher 65f00b20269806f513f5c6a479a7ca051db6a334ca4549121e5b813bbdf75989 bin/opencode-pty-supervisor 65f00b20269806f513f5c6a479a7ca051db6a334ca4549121e5b813bbdf75989 /tmp/opencode/review-opencode-pty-supervisor
(no output)
drwxr-xr-x 755 root:root /home drwxr-x--x 751 byk:byk /home/byk drwxrwxr-x 775 byk:byk /home/byk/.local drwxrwxr-x 775 byk:byk /home/byk/.local/share drwxr-xr-x 755 byk:byk /home/byk/.local/share/opencode-v2-pilot drwxr-xr-x 755 byk:byk /home/byk/.local/share/opencode-v2-pilot/supervisor
? opencode-pty-supervisor/cmd/supervisor [no test files] ok opencode-pty-supervisor/cmd/launcher 1.100s ok opencode-pty-supervisor/internal/protocol 1.028s ok opencode-pty-supervisor/internal/supervisor 1.018s
[
{
"content": "Inventory every file and identify applicable repository guidance and pinned dependency manifests",
"status": "completed",
"priority": "high"
},
{
"content": "Read and trace source, protocol, units, tests, docs, and pinned module implementations",
"status": "completed",
"priority": "high"
},
{
"content": "Run safe unprivileged static and targeted tests without starting services",
"status": "completed",
"priority": "high"
},
{
"content": "Map evidence to every requested threat category and classify findings",
"status": "in_progress",
"priority": "high"
},
{
"content": "Deliver independent review with exact file:line citations and final merge verdict",
"status": "pending",
"priority": "high"
}
]
[
{
"content": "Inventory every file and identify applicable repository guidance and pinned dependency manifests",
"status": "completed",
"priority": "high"
},
{
"content": "Read and trace source, protocol, units, tests, docs, and pinned module implementations",
"status": "completed",
"priority": "high"
},
{
"content": "Run safe unprivileged static and targeted tests without starting services",
"status": "completed",
"priority": "high"
},
{
"content": "Map evidence to every requested threat category and classify findings",
"status": "completed",
"priority": "high"
},
{
"content": "Deliver independent review with exact file:line citations and final merge verdict",
"status": "completed",
"priority": "high"
}
]
Review Result
I reviewed all 19 files under /home/byk/.local/share/opencode-v2-pilot/supervisor, both binaries, all pinned Go module declarations and relevant implementations, the unit files, protocol, tests, and acceptance document. I made no source or service changes and ran no privileged commands.
MUST-FIX
ClientState calls GetUnitPropertiesContext and expects MainPID:
internal/supervisor/systemd.go:64-81internal/supervisor/auth.go:18-27The pinned go-systemd implementation requests only org.freedesktop.systemd1.Unit:
/home/byk/go/pkg/mod/github.com/coreos/go-systemd/v22@v22.5.0/dbus/methods.go:270-275MainPID belongs to org.freedesktop.systemd1.Service, not Unit. An unprivileged host query confirmed systemd 255 rejects Unit.MainPID while returning Service.MainPID.
The same bug affects completion. Wait fetches Unit properties, then decodeUnitResult expects Result, ExecMainCode, and ExecMainStatus, which belong to the Service interface:
internal/supervisor/systemd.go:101-125internal/supervisor/systemd.go:271-284Current tests use synthetic maps and a fake manager, so they cannot detect this:
internal/supervisor/auth_test.go:9-27internal/supervisor/systemd_test.go:51-58Positive checks exist, but they only compare a numeric PID, service state, and the service’s configured cgroup before and after one pidfd liveness probe:
internal/supervisor/auth.go:12-38internal/supervisor/systemd.go:64-81The code never checks:
SO_PEERCRED.InvocationID.* 🟡 (04:50) `internal/supervisor/server_test.go` contains 5 tests: `TestReceiveStartWithDirectoryDescriptor`, `TestReceiveStartRejectsMetadataMismatch`, `TestReceiveStartHandlesFragmentedHeader`, `TestCopyInputRejectsOutputFrame`, and `TestExitPayloadEncodingIsBounded`; helper `unixConnectionPair(t *testing.T)` creates an `AF_UNIX` `SOCK_STREAM|SOCK_CLOEXEC` socket pair and returns two `*net.Uni…
Date: Sep 8, 2026 * 🟡 (04:48) `internal/supervisor/server.go` defines `socketBufferSize = 128 * 1024`, tracks active Unix connections in `connections map[*net.UnixConn]struct{}` protected by `mutex sync.Mutex`, performs startup orphan cleanup via `server.manager.CleanupOrphans()`, closes tracked connections during shutdown, and uses a `server.sessions` semaphore whose slot is released with `<-se…
Date: Sep 8, 2026 * 🟡 (04:46) Supervisor repository inventory found 19 files under `/home/byk/.local/share/opencode-v2-pilot/supervisor`: `ROOT-ACCEPTANCE.md`, `PROTOCOL.md`, `go.mod`, `go.sum`, `opencode-pty-supervisor.service`, `opencode-pty.slice`, `bin/opencode-pty-launcher`, `bin/opencode-pty-supervisor`, `cmd/supervisor/main.go`, `cmd/launcher/main.go`, `cmd/launcher/main_test.go`, `intern…
Date: Sep 8, 2026 * 🔴 [requested-security-review] (04:46) User requested an independent, read-only security review of every file under `/home/byk/.local/share/opencode-v2-pilot/supervisor`, covering exact current source, protocol, units, tests, docs, and pinned modules. * 🔴 (04:46) User defined the threat model as same-UID malicious PTY descendants and untrusted model command/input/output. * 🔴…