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"
"io"
"os"
"runtime"
"syscall"
)
@ -125,8 +126,8 @@ type securityContextCloser struct {
}
// Close closes both ends of the pipe.
func (scc *securityContextCloser) Close() error {
return errors.Join(
func (scc *securityContextCloser) Close() (err error) {
err = errors.Join(
syscall.Close(scc.closeFds[1]),
syscall.Close(scc.closeFds[0]),
// 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
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.
@ -162,6 +167,7 @@ func (securityContext *SecurityContext) BindAndCreate(pathname string, props SPA
if err := syscall.Bind(listenFd, &syscall.SockaddrUnix{Name: pathname}); err != nil {
return nil, os.NewSyscallError("bind", err)
} else if err = syscall.Listen(listenFd, 0); err != nil {
_ = os.Remove(pathname)
return nil, os.NewSyscallError("listen", err)
}
@ -169,6 +175,8 @@ func (securityContext *SecurityContext) BindAndCreate(pathname string, props SPA
_ = os.Remove(pathname)
return nil, err
}
runtime.SetFinalizer(&scc, (*securityContextCloser).Close)
if err := securityContext.Create(listenFd, scc.closeFds[1], props); err != nil {
_ = scc.Close()
return nil, err