M cmd/sf/main.go => cmd/sf/main.go +7 -1
@@ 35,7 35,13 @@ func main() {
func run() error {
f := parseFlags()
- // TODO(egtann) pledge+unveil
+ // Restrict sf's view of the filesystem and its access to syscalls
+ unveil(f.file, "r")
+ unveil(f.sslKey, "r")
+ unveil(f.sslCert, "r")
+ unveil(f.sslCA, "r")
+ unveilBlock()
+ pledge("stdio tty inet rpath", "")
// Request database password if not provided as a flag argument
if f.password == "" {
A cmd/sf/security.go => cmd/sf/security.go +12 -0
@@ 0,0 1,12 @@
+// +build !openbsd
+
+package main
+
+// pledge is only supported on OpenBSD.
+func pledge(promises, execPromises string) {}
+
+// unveil is only supported on OpenBSD.
+func unveil(filepath, perm string) {}
+
+// unveilBlock is only supported on OpenBSD.
+func unveilBlock() {}
A cmd/sf/security_openbsd.go => cmd/sf/security_openbsd.go +26 -0
@@ 0,0 1,26 @@
+package main
+
+import "golang.org/x/sys/unix"
+
+// pledge restricts sf to very limited syscalls.
+func pledge(promises, execPromises string) {
+ if err := unix.Pledge(promises, execPromises); err != nil {
+ panic(err)
+ }
+}
+
+// unveil restricts sf to very limited (read-only) filesystem access.
+func unveil(filepath string, perm string) {
+ if filepath == "" {
+ return
+ }
+ if err := unix.Unveil(filepath, perm); err != nil {
+ panic(err)
+ }
+}
+
+func unveilBlock() {
+ if err := unix.UnveilBlock(); err != nil {
+ panic(err)
+ }
+}