aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-07 17:29:22 +0900
committerOphestra <cat@gensokyo.uk>2025-12-07 17:29:22 +0900
commit7c6fc1128b89ebfc22adc52bac1fdb9205e69150 (patch)
tree8bf0cc27d404efb32ff68e85db27d2b6bfb73632
parent8cdd659239654aa2c18e392d5cde3c31da069b98 (diff)
internal/pipewire: set finalizer on scc
This prevents leaking the socket and pipe fds. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/pipewire/securitycontext.go12
1 files changed, 10 insertions, 2 deletions
diff --git a/internal/pipewire/securitycontext.go b/internal/pipewire/securitycontext.go
index 107fe994..c50665bf 100644
--- a/internal/pipewire/securitycontext.go
+++ b/internal/pipewire/securitycontext.go
@@ -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