From 8ace2148326d85312a157e19e596978361e9285d Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 5 Oct 2025 03:19:37 +0900 Subject: system/wayland: hang up security-context-v1 internally This should have been an implementation detail and should not be up to the caller to close. Signed-off-by: Ophestra --- system/wayland.go | 33 ++++++++++++++-------- system/wayland_test.go | 76 ++++++++++++++++---------------------------------- 2 files changed, 45 insertions(+), 64 deletions(-) (limited to 'system') diff --git a/system/wayland.go b/system/wayland.go index 7ebb2114..f987967b 100644 --- a/system/wayland.go +++ b/system/wayland.go @@ -20,14 +20,17 @@ type waylandConn interface { // Wayland maintains a wayland socket with security-context-v1 attached via [wayland]. // The socket stops accepting connections once the pipe referred to by sync is closed. // The socket is pathname only and is destroyed on revert. -func (sys *I) Wayland(syncFd **os.File, dst, src *container.Absolute, appID, instanceID string) *I { - sys.ops = append(sys.ops, &waylandOp{syncFd, dst.String(), src.String(), appID, instanceID, new(wayland.Conn)}) +func (sys *I) Wayland(dst, src *container.Absolute, appID, instanceID string) *I { + sys.ops = append(sys.ops, &waylandOp{nil, + dst.String(), src.String(), + appID, instanceID, + new(wayland.Conn)}) return sys } // waylandOp implements [I.Wayland]. type waylandOp struct { - sync **os.File + sync *os.File dst, src string appID, instanceID string @@ -37,11 +40,6 @@ type waylandOp struct { func (w *waylandOp) Type() hst.Enablement { return Process } func (w *waylandOp) apply(sys *I) error { - if w.sync == nil { - // this is a misuse of the API; do not return a wrapped error - return errors.New("invalid sync") - } - if err := w.conn.Attach(w.src); err != nil { return newOpError("wayland", err, false) } else { @@ -51,7 +49,7 @@ func (w *waylandOp) apply(sys *I) error { if sp, err := w.conn.Bind(w.dst, w.appID, w.instanceID); err != nil { return newOpError("wayland", err, false) } else { - *w.sync = sp + w.sync = sp sys.msg.Verbosef("wayland listening on %q", w.dst) if err = sys.chmod(w.dst, 0); err != nil { return newOpError("wayland", err, false) @@ -61,13 +59,24 @@ func (w *waylandOp) apply(sys *I) error { } func (w *waylandOp) revert(sys *I, _ *Criteria) error { + var ( + hangupErr error + closeErr error + removeErr error + ) + + sys.msg.Verbosef("detaching from wayland on %q", w.src) + if w.sync != nil { + hangupErr = w.sync.Close() + } + closeErr = w.conn.Close() + sys.msg.Verbosef("removing wayland socket on %q", w.dst) if err := sys.remove(w.dst); err != nil && !errors.Is(err, os.ErrNotExist) { - return newOpError("wayland", err, true) + removeErr = err } - sys.msg.Verbosef("detaching from wayland on %q", w.src) - return newOpError("wayland", w.conn.Close(), true) + return newOpError("wayland", errors.Join(hangupErr, closeErr, removeErr), true) } func (w *waylandOp) Is(o Op) bool { diff --git a/system/wayland_test.go b/system/wayland_test.go index 9e06cfae..d6a3b93b 100644 --- a/system/wayland_test.go +++ b/system/wayland_test.go @@ -87,17 +87,7 @@ func (conn *stubWaylandConn) Close() error { func TestWaylandOp(t *testing.T) { checkOpBehaviour(t, []opBehaviourTestCase{ - {"invalid sync", 0xdeadbeef, 0xff, &waylandOp{ - nil, - "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", - "/run/user/1971/wayland-0", - "org.chromium.Chromium", - "ebf083d1b175911782d413369b64ce7c", - nil, - }, nil, errors.New("invalid sync"), nil, nil}, - - {"attach", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"attach", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -108,8 +98,7 @@ func TestWaylandOp(t *testing.T) { attachErr: stub.UniqueError(5)}, }, nil, &OpError{Op: "wayland", Err: stub.UniqueError(5)}, nil, nil}, - {"bind", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"bind", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -122,8 +111,7 @@ func TestWaylandOp(t *testing.T) { call("verbosef", stub.ExpectArgs{"wayland attached on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), }, &OpError{Op: "wayland", Err: stub.UniqueError(4)}, nil, nil}, - {"chmod", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"chmod", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -137,8 +125,7 @@ func TestWaylandOp(t *testing.T) { call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, stub.UniqueError(3)), }, &OpError{Op: "wayland", Err: stub.UniqueError(3)}, nil, nil}, - {"aclUpdate", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"aclUpdate", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -153,8 +140,7 @@ func TestWaylandOp(t *testing.T) { call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, stub.UniqueError(2)), }, &OpError{Op: "wayland", Err: stub.UniqueError(2)}, nil, nil}, - {"remove", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"remove", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -168,12 +154,12 @@ func TestWaylandOp(t *testing.T) { call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ + call("verbosef", stub.ExpectArgs{"detaching from wayland on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), call("verbosef", stub.ExpectArgs{"removing wayland socket on %q", []any{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}}, nil, nil), call("remove", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}, nil, stub.UniqueError(1)), - }, &OpError{Op: "wayland", Err: stub.UniqueError(1), Revert: true}}, + }, &OpError{Op: "wayland", Err: errors.Join(stub.UniqueError(1)), Revert: true}}, - {"close", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"close", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -188,13 +174,12 @@ func TestWaylandOp(t *testing.T) { call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ + call("verbosef", stub.ExpectArgs{"detaching from wayland on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), call("verbosef", stub.ExpectArgs{"removing wayland socket on %q", []any{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}}, nil, nil), call("remove", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}, nil, nil), - call("verbosef", stub.ExpectArgs{"detaching from wayland on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), - }, &OpError{Op: "wayland", Err: stub.UniqueError(0), Revert: true}}, + }, &OpError{Op: "wayland", Err: errors.Join(stub.UniqueError(0)), Revert: true}}, - {"success", 0xdeadbeef, 0xff, &waylandOp{ - new(*os.File), + {"success", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -208,23 +193,21 @@ func TestWaylandOp(t *testing.T) { call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ + call("verbosef", stub.ExpectArgs{"detaching from wayland on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), call("verbosef", stub.ExpectArgs{"removing wayland socket on %q", []any{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}}, nil, nil), call("remove", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"}, nil, nil), - call("verbosef", stub.ExpectArgs{"detaching from wayland on %q", []any{"/run/user/1971/wayland-0"}}, nil, nil), }, nil}, }) checkOpsBuilder(t, "Wayland", []opsBuilderTestCase{ {"chromium", 0xcafe, func(_ *testing.T, sys *I) { sys.Wayland( - new(*os.File), m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c", ) - }, []Op{&waylandOp{ - new(*os.File), + }, []Op{&waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -234,15 +217,13 @@ func TestWaylandOp(t *testing.T) { }) checkOpIs(t, []opIsTestCase{ - {"dst differs", &waylandOp{ - new(*os.File), + {"dst differs", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7d/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c", new(wayland.Conn), - }, &waylandOp{ - new(*os.File), + }, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -250,15 +231,13 @@ func TestWaylandOp(t *testing.T) { new(wayland.Conn), }, false}, - {"src differs", &waylandOp{ - new(*os.File), + {"src differs", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-1", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c", new(wayland.Conn), - }, &waylandOp{ - new(*os.File), + }, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -266,15 +245,13 @@ func TestWaylandOp(t *testing.T) { new(wayland.Conn), }, false}, - {"appID differs", &waylandOp{ - new(*os.File), + {"appID differs", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium", "ebf083d1b175911782d413369b64ce7c", new(wayland.Conn), - }, &waylandOp{ - new(*os.File), + }, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -282,15 +259,13 @@ func TestWaylandOp(t *testing.T) { new(wayland.Conn), }, false}, - {"instanceID differs", &waylandOp{ - new(*os.File), + {"instanceID differs", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7d", new(wayland.Conn), - }, &waylandOp{ - new(*os.File), + }, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -298,15 +273,13 @@ func TestWaylandOp(t *testing.T) { new(wayland.Conn), }, false}, - {"equals", &waylandOp{ - new(*os.File), + {"equals", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c", new(wayland.Conn), - }, &waylandOp{ - new(*os.File), + }, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", @@ -316,8 +289,7 @@ func TestWaylandOp(t *testing.T) { }) checkOpMeta(t, []opMetaTestCase{ - {"chromium", &waylandOp{ - new(*os.File), + {"chromium", &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", -- cgit v1.3.1