Skip to content

x/sys/unix: OpenBSD's Pledge and Unveil functions can be annulled #60322

@codesoap

Description

@codesoap

What version of Go are you using (go version)?

$ go version
go version go1.20.1 openbsd/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/path/to/.cache/go-build"
GOENV="/path/to/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="openbsd"
GOINSECURE=""
GOMODCACHE="/path/to/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="openbsd"
GOPATH="/path/to/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/openbsd_amd64"
GOVCS=""
GOVERSION="go1.20.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="cc"
CXX="c++"
CGO_ENABLED="1"
GOMOD="/path/to/foo/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1212173938=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I ran this program:

package main

import "foo/bar"
import "golang.org/x/sys/unix"

func main() {
        if err := unix.Pledge("", ""); err != nil {
		panic(err)
	}
        bar.Greet()
}

Where the package bar contains this source file:

package bar

func init()  { println("Initializing bar.") }
func Greet() { println("Greetings from bar!") }

What did you expect to see?

I didn't really expect it, but ideally the program would exit immediately, because the unix.Pledge call didn't allow the use of standard IO and bar.init is printing something to the standard output.

In C programs, pledge is often called as the first thing in the main function, to prevent any code (written by the author themself or the author of a used library) to use undesired syscalls. Because in Go the init function of used libraries/packages are always executed before the init function and variable declarations of the main package, I see no way to replicate this C pattern in Go. Thus unix.Pledge cannot provide the same safety guarantees in Go as in C.

I suspect this is a problem that cannot be solved without a change in the language. I think there should at least be a warning in the documentation of the Pledge, PledgeExecpromises and PledgePromises, but also Unveil and UnveilBlock functions.

If there is a way to force Go to execute unix.Pledge as the first thing in a program, I'm gladly taking instructions on how to do this.

What did you see instead?

The program ran the init function of the bar package, before running unix.Pledge:

$ go run .
Initializing bar.
signal: abort trap (core dumped)

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-OpenBSDcompiler/runtimeIssues related to the Go compiler and/or runtime.help wanted

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions