aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-23 03:24:37 +0900
committerOphestra <cat@gensokyo.uk>2025-02-23 03:24:37 +0900
commiteda4d612c2e64321766e1074a698caeae843102a (patch)
treec492042ffd52930c8578884ec2800a25690bae3a
parent2e7e16068372a0c0b42bd6b3da2433134c91a495 (diff)
fortify: keep external files alive
This should eliminate sporadic failures, like the known double close in "seccomp". Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--helper/proc/pipe.go12
-rw-r--r--helper/seccomp/export.go7
-rw-r--r--wl/conn.go1
-rw-r--r--wl/wayland-bind.c2
-rw-r--r--wl/wayland-bind.h2
-rw-r--r--wl/wl.go2
6 files changed, 21 insertions, 5 deletions
diff --git a/helper/proc/pipe.go b/helper/proc/pipe.go
index 92ffe693..838c4ae4 100644
--- a/helper/proc/pipe.go
+++ b/helper/proc/pipe.go
@@ -5,6 +5,7 @@ import (
"errors"
"io"
"os"
+ "runtime"
)
// NewWriterTo returns a [File] that receives content from wt on fulfillment.
@@ -25,13 +26,20 @@ func (f *writeToFile) Fulfill(ctx context.Context, dispatchErr func(error)) erro
f.Set(r)
done := make(chan struct{})
- go func() { _, err = f.wt.WriteTo(w); dispatchErr(err); dispatchErr(w.Close()); close(done) }()
+ go func() {
+ _, err = f.wt.WriteTo(w)
+ dispatchErr(err)
+ dispatchErr(w.Close())
+ close(done)
+ runtime.KeepAlive(r)
+ }()
go func() {
select {
case <-done:
dispatchErr(nil)
case <-ctx.Done():
dispatchErr(w.Close()) // this aborts WriteTo with file already closed
+ runtime.KeepAlive(r)
}
}()
@@ -83,6 +91,7 @@ func (f *statFile) Fulfill(ctx context.Context, dispatchErr func(error)) error {
default:
panic("unreachable")
}
+ runtime.KeepAlive(w)
}()
go func() {
@@ -91,6 +100,7 @@ func (f *statFile) Fulfill(ctx context.Context, dispatchErr func(error)) error {
dispatchErr(nil)
case <-ctx.Done():
dispatchErr(r.Close()) // this aborts Read with file already closed
+ runtime.KeepAlive(w)
}
}()
diff --git a/helper/seccomp/export.go b/helper/seccomp/export.go
index 52ec4144..9efee3b4 100644
--- a/helper/seccomp/export.go
+++ b/helper/seccomp/export.go
@@ -27,7 +27,12 @@ func (e *exporter) prepare() error {
}
ec := make(chan error, 1)
- go func(fd uintptr) { ec <- exportFilter(fd, e.opts); close(ec); _ = e.closeWrite() }(e.w.Fd())
+ go func(fd uintptr) {
+ ec <- exportFilter(fd, e.opts)
+ close(ec)
+ _ = e.closeWrite()
+ runtime.KeepAlive(e.w)
+ }(e.w.Fd())
e.exportErr = ec
runtime.SetFinalizer(e, (*exporter).closeWrite)
})
diff --git a/wl/conn.go b/wl/conn.go
index 82c0587b..1a7cba65 100644
--- a/wl/conn.go
+++ b/wl/conn.go
@@ -94,6 +94,7 @@ func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID st
// keep socket alive until done is requested
<-done
+ runtime.KeepAlive(syncPipe[1].Fd())
}); err != nil {
setupDone <- err
}
diff --git a/wl/wayland-bind.c b/wl/wayland-bind.c
index a177a378..01e8b882 100644
--- a/wl/wayland-bind.c
+++ b/wl/wayland-bind.c
@@ -23,7 +23,7 @@ static const struct wl_registry_listener registry_listener = {
.global_remove = registry_handle_global_remove,
};
-int32_t bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd) {
+int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd) {
int32_t res = 0; // refer to resErr for meaning
struct wl_display *display;
diff --git a/wl/wayland-bind.h b/wl/wayland-bind.h
index 67898fc6..720dfe4e 100644
--- a/wl/wayland-bind.h
+++ b/wl/wayland-bind.h
@@ -1,3 +1,3 @@
#include <stdint.h>
-int32_t bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd); \ No newline at end of file
+int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd); \ No newline at end of file
diff --git a/wl/wl.go b/wl/wl.go
index da1ed2c8..51ad1fd2 100644
--- a/wl/wl.go
+++ b/wl/wl.go
@@ -29,7 +29,7 @@ func bindWaylandFd(socketPath string, fd uintptr, appID, instanceID string, sync
if hasNull(appID) || hasNull(instanceID) {
return ErrContainsNull
}
- res := C.bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFD))
+ res := C.f_bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFD))
return resErr[int32(res)]
}