Commit 98c5dad5 authored by Gianguido Sora`'s avatar Gianguido Sora` Committed by Ian Lance Taylor

unix: update the OpenBSD pledge interface to handle execpromises

The current Pledge function still takes into account the deprecated
"paths" argument, which has been replaced by "execpromises".
This change has been committed to OpenBSD on the 11 December 2017:
https://marc.info/?l=openbsd-tech&m=151302727506669.
This commit updates the Pledge function interface to reflect this
change.

Fixes golang/go#26824

Change-Id: Id6255b0432cf0a33e680e342dd23c7b02d0aa78f
Reviewed-on: https://go-review.googlesource.com/127762
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent f0d5e330
......@@ -8,6 +8,9 @@
package unix
import (
"errors"
"fmt"
"strconv"
"syscall"
"unsafe"
)
......@@ -16,23 +19,77 @@ const (
_SYS_PLEDGE = 108
)
// Pledge implements the pledge syscall. For more information see pledge(2).
func Pledge(promises string, paths []string) error {
promisesPtr, err := syscall.BytePtrFromString(promises)
// Pledge implements the pledge syscall.
//
// The pledge syscall does not accept execpromises on OpenBSD releases
// before 6.3.
//
// execpromises must be empty when Pledge is called on OpenBSD
// releases predating 6.3, otherwise an error will be returned.
//
// For more information see pledge(2).
func Pledge(promises, execpromises string) error {
maj, min, err := majmin()
if err != nil {
return err
}
promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil)
if paths != nil {
var pathsPtr []*byte
if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil {
// If OpenBSD <= 5.9, pledge is not available.
if (maj == 5 && min != 9) || maj < 5 {
return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min)
}
// If OpenBSD <= 6.2 and execpromises is not empty
// return an error - execpromises is not available before 6.3
if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" {
return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min)
}
pptr, err := syscall.BytePtrFromString(promises)
if err != nil {
return err
}
// This variable will hold either a nil unsafe.Pointer or
// an unsafe.Pointer to a string (execpromises).
var expr unsafe.Pointer
// If we're running on OpenBSD > 6.2, pass execpromises to the syscall.
if maj > 6 || (maj == 6 && min > 2) {
exptr, err := syscall.BytePtrFromString(execpromises)
if err != nil {
return err
}
pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
expr = unsafe.Pointer(exptr)
}
_, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
_, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
if e != 0 {
return e
}
return nil
}
// majmin returns major and minor version number for an OpenBSD system.
func majmin() (major int, minor int, err error) {
var v Utsname
err = Uname(&v)
if err != nil {
return
}
major, err = strconv.Atoi(string(v.Release[0]))
if err != nil {
err = errors.New("cannot parse major version number returned by uname")
return
}
minor, err = strconv.Atoi(string(v.Release[2]))
if err != nil {
err = errors.New("cannot parse minor version number returned by uname")
return
}
return
}
......@@ -87,7 +87,7 @@ func TestMain(m *testing.M) {
func init() {
testProcs["pledge"] = testProc{
func() {
fmt.Println(unix.Pledge("", nil))
fmt.Println(unix.Pledge("", ""))
os.Exit(0)
},
func() error {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment