Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/sys/unix: pledge_openbsd.go lacks a function to pass nil for both promises and execpromises #36638

Closed
estrogently opened this issue Jan 19, 2020 · 2 comments

Comments

@estrogently
Copy link

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

$ go version
go version go1.13.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="/home/redacted/.cache/go-build"
GOENV="/home/redacted/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="openbsd"
GONOPROXY=""
GONOSUMDB=""
GOOS="openbsd"
GOPATH="/home/redacted/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"
GCCGO="gccgo"
AR="ar"
CC="cc"
CXX="c++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build858990023=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Passing nil to promises or execpromises prevents that value from being changed in the future (see pledge(2). I wanted to prevent both promises and execpromises from being further modified.

What did you expect to see?

For there to be a function to pass nil for both promises and execpromises, akin to unveil_openbsd.go's UnveilBlock().

What did you see instead?

Currently, to prevent future modification of promises and execpromises, you need to call PledgePromises(), which locks down execpromises, followed by PledgeExecpromises(), which locks down promises.

This is rather unwieldy and requires you to re-specify your current promises and execpromises (as passing "" to the above 2 functions would limit you to only being able to call _exit(2)).

@gopherbot gopherbot added this to the Unreleased milestone Jan 19, 2020
@esote
Copy link

esote commented Jan 19, 2020

I think you misunderstand what passing NULL to pledge does. It does not prevent future modification, for example try running:

#include <err.h>
#include <stdio.h>
#include <unistd.h>

int
main(void)
{
	if (pledge(NULL, NULL) == -1) {
		err(1, "pledge");
	}
	if (pledge("stdio", "rpath") == -1) {
		err(1, "pledge");
	}
	puts("hi");
	return 0;
}

This program will execute successfully. From the manual you link:

Passing NULL to promises or execpromises specifies to not change the current value

This behavior is usually used to restrict one of the parameters without changing the other, for example restricting promises without changing the existing execpromises pledges. Therefore passing NULL to both arguments is essentially a no-op (ignoring things like restricting some ioctl requests which a program's first call to pledge does).

As the function documentation says on PledgePromises() and PledgeExecpromises(), these functions leave the other argument untouched.

The blocking behavior of unveil is specific to that syscall. As far as I know, the pledge syscall provides no mechanism to restrict future calls to itself.

@estrogently
Copy link
Author

Ah, my bad, thank you for the education @esote!

@golang golang locked and limited conversation to collaborators Jan 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants