From 38e92edb8efd7cc74031d013a13af5c1c8ddd284 Mon Sep 17 00:00:00 2001 From: Ophestra Umiker Date: Fri, 6 Dec 2024 04:20:15 +0900 Subject: [PATCH] system/wayland: integrate security-context-v1 Had to pass the sync fd through sys. The rest are just part of a standard Op. Signed-off-by: Ophestra Umiker --- internal/system/op.go | 6 +++ internal/system/wayland.go | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 internal/system/wayland.go diff --git a/internal/system/op.go b/internal/system/op.go index 7d29377..d2ca5dd 100644 --- a/internal/system/op.go +++ b/internal/system/op.go @@ -2,6 +2,7 @@ package system import ( "errors" + "os" "sync" "git.ophivana.moe/security/fortify/internal/fmsg" @@ -56,6 +57,7 @@ func TypeString(e Enablement) string { type I struct { uid int ops []Op + sp *os.File state [2]bool lock sync.Mutex @@ -65,6 +67,10 @@ func (sys *I) UID() int { return sys.uid } +func (sys *I) Sync() *os.File { + return sys.sp +} + func (sys *I) Equal(v *I) bool { if v == nil || sys.uid != v.uid || len(sys.ops) != len(v.ops) { return false diff --git a/internal/system/wayland.go b/internal/system/wayland.go new file mode 100644 index 0000000..36a7fa6 --- /dev/null +++ b/internal/system/wayland.go @@ -0,0 +1,80 @@ +package system + +import ( + "errors" + "fmt" + "os" + + "git.ophivana.moe/security/fortify/acl" + "git.ophivana.moe/security/fortify/internal/fmsg" + "git.ophivana.moe/security/fortify/wl" +) + +// Wayland sets up a wayland socket with a security context attached. +func (sys *I) Wayland(dst, src, appID, instanceID string) *I { + sys.lock.Lock() + defer sys.lock.Unlock() + + sys.ops = append(sys.ops, Wayland{[2]string{dst, src}, new(wl.Conn), appID, instanceID}) + + return sys +} + +type Wayland struct { + pair [2]string + conn *wl.Conn + + appID, instanceID string +} + +func (w Wayland) Type() Enablement { + return Process +} + +func (w Wayland) apply(sys *I) error { + if err := w.conn.Attach(w.pair[1]); err != nil { + return fmsg.WrapErrorSuffix(err, + fmt.Sprintf("cannot attach to wayland on %q:", w.pair[1])) + } else { + fmsg.VPrintf("wayland attached on %q", w.pair[1]) + } + + if sp, err := w.conn.Bind(w.pair[0], w.appID, w.instanceID); err != nil { + return fmsg.WrapErrorSuffix(err, + fmt.Sprintf("cannot bind to socket on %q:", w.pair[0])) + } else { + sys.sp = sp + fmsg.VPrintf("wayland listening on %q", w.pair[0]) + return fmsg.WrapErrorSuffix(errors.Join(os.Chmod(w.pair[0], 0), acl.UpdatePerm(w.pair[0], sys.uid, acl.Read, acl.Write, acl.Execute)), + fmt.Sprintf("cannot chmod socket on %q:", w.pair[0])) + } +} + +func (w Wayland) revert(_ *I, ec *Criteria) error { + if ec.hasType(w) { + fmsg.VPrintf("removing wayland socket on %q", w.pair[0]) + if err := os.Remove(w.pair[0]); err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + fmsg.VPrintf("detaching from wayland on %q", w.pair[1]) + return fmsg.WrapErrorSuffix(w.conn.Close(), + fmt.Sprintf("cannot detach from wayland on %q:", w.pair[1])) + } else { + fmsg.VPrintf("skipping wayland cleanup on %q", w.pair[0]) + return nil + } +} + +func (w Wayland) Is(o Op) bool { + w0, ok := o.(Wayland) + return ok && w.pair == w0.pair +} + +func (w Wayland) Path() string { + return w.pair[0] +} + +func (w Wayland) String() string { + return fmt.Sprintf("wayland socket at %q", w.pair[0]) +}