From 83ec58afc763ff89d9664876ed2e95fb5842985a Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 12 Dec 2024 21:37:02 +0300 Subject: [PATCH] Use unveil(2) on OpenBSD (#1194) After #1175 removed ioctl(2) fallback code shelling out to ifconfig(8), there is no code left (compiled on OpenBSD) that would fork(2) or execve(2). Drop the ability to run any executable file to double down on this, thus reducing the attack surface of this this experimental, internet facing daemon running as root. pledge(2) is doable, but needs more polish. unveil(2), however, is as simple as it gets. On other systems, this code is a NOOP, but can still help to implement similar safety belts. --- cmd/yggdrasil/main.go | 16 ++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 19 insertions(+) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 3ec6414c..b3cbecf0 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -14,6 +14,8 @@ import ( "strings" "syscall" + "suah.dev/protect" + "github.com/gologme/log" gsyslog "github.com/hashicorp/go-syslog" "github.com/hjson/hjson-go/v4" @@ -39,6 +41,20 @@ type node struct { // The main function is responsible for configuring and starting Yggdrasil. func main() { + // Not all operations are coverable with pledge(2), so immediately + // limit file system access with unveil(2), effectively preventing + // "proc exec" promises right from the start: + // + // - read arbitrary config file + // - create/write arbitrary log file + // - read/write/chmod/remove admin socket, if at all + if err := protect.Unveil("/", "rwc"); err != nil { + panic(fmt.Sprintf("unveil: / rwc: %v", err)) + } + if err := protect.UnveilBlock(); err != nil { + panic(fmt.Sprintf("unveil: %v", err)) + } + genconf := flag.Bool("genconf", false, "print a new config to stdout") useconf := flag.Bool("useconf", false, "read HJSON/JSON config from stdin") useconffile := flag.String("useconffile", "", "read HJSON/JSON config from specified file path") diff --git a/go.mod b/go.mod index a2909018..5608f588 100644 --- a/go.mod +++ b/go.mod @@ -45,4 +45,5 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/olekukonko/tablewriter v0.0.5 github.com/vishvananda/netns v0.0.4 // indirect + suah.dev/protect v1.2.4 ) diff --git a/go.sum b/go.sum index d62e2ddb..061a0769 100644 --- a/go.sum +++ b/go.sum @@ -112,3 +112,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= +suah.dev/protect v1.2.4 h1:iVZG/zQB63FKNpITDYM/cXoAeCTIjCiXHuFVByJFDzg= +suah.dev/protect v1.2.4/go.mod h1:vVrquYO3u1Ep9Ez2z8x+6N6/czm+TBmWKZfiXU2tb54=