internal/pipewire: set finalizer on scc
All checks were successful
Test / Create distribution (push) Successful in 36s
Test / Sandbox (push) Successful in 45s
Test / Sandbox (race detector) (push) Successful in 2m38s
Test / Hpkg (push) Successful in 4m16s
Test / Hakurei (push) Successful in 4m27s
Test / Hakurei (race detector) (push) Successful in 4m52s
Test / Flake checks (push) Successful in 1m38s

This prevents leaking the socket and pipe fds.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-12-07 17:29:22 +09:00
parent 8cdd659239
commit 7c6fc1128b
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"io" "io"
"os" "os"
"runtime"
"syscall" "syscall"
) )
@ -125,8 +126,8 @@ type securityContextCloser struct {
} }
// Close closes both ends of the pipe. // Close closes both ends of the pipe.
func (scc *securityContextCloser) Close() error { func (scc *securityContextCloser) Close() (err error) {
return errors.Join( err = errors.Join(
syscall.Close(scc.closeFds[1]), syscall.Close(scc.closeFds[1]),
syscall.Close(scc.closeFds[0]), syscall.Close(scc.closeFds[0]),
// there is still technically a TOCTOU here but this is internal // there is still technically a TOCTOU here but this is internal
@ -134,6 +135,10 @@ func (scc *securityContextCloser) Close() error {
// receives trusted input (e.g. from cmd/hakurei) anyway // receives trusted input (e.g. from cmd/hakurei) anyway
os.Remove(scc.pathname), os.Remove(scc.pathname),
) )
// no need for a finalizer anymore
runtime.SetFinalizer(scc, nil)
return
} }
// BindAndCreate binds a new socket to the specified pathname and pass it to Create. // BindAndCreate binds a new socket to the specified pathname and pass it to Create.
@ -162,6 +167,7 @@ func (securityContext *SecurityContext) BindAndCreate(pathname string, props SPA
if err := syscall.Bind(listenFd, &syscall.SockaddrUnix{Name: pathname}); err != nil { if err := syscall.Bind(listenFd, &syscall.SockaddrUnix{Name: pathname}); err != nil {
return nil, os.NewSyscallError("bind", err) return nil, os.NewSyscallError("bind", err)
} else if err = syscall.Listen(listenFd, 0); err != nil { } else if err = syscall.Listen(listenFd, 0); err != nil {
_ = os.Remove(pathname)
return nil, os.NewSyscallError("listen", err) return nil, os.NewSyscallError("listen", err)
} }
@ -169,6 +175,8 @@ func (securityContext *SecurityContext) BindAndCreate(pathname string, props SPA
_ = os.Remove(pathname) _ = os.Remove(pathname)
return nil, err return nil, err
} }
runtime.SetFinalizer(&scc, (*securityContextCloser).Close)
if err := securityContext.Create(listenFd, scc.closeFds[1], props); err != nil { if err := securityContext.Create(listenFd, scc.closeFds[1], props); err != nil {
_ = scc.Close() _ = scc.Close()
return nil, err return nil, err