diff --git a/unix/pledge_openbsd.go b/unix/pledge_openbsd.go index eb48294b2..a614929fd 100644 --- a/unix/pledge_openbsd.go +++ b/unix/pledge_openbsd.go @@ -14,43 +14,28 @@ import ( // 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. +// This changes both the promises and execpromises; use PledgePromises or +// PledgeExecpromises to only change the promises or execpromises +// respectively. // // For more information see pledge(2). func Pledge(promises, execpromises string) error { - maj, min, err := majmin() - if err != nil { + if err := pledgeAvailable(); err != nil { return err } - err = pledgeAvailable(maj, min, execpromises) + pptr, err := syscall.BytePtrFromString(promises) if err != nil { return err } - pptr, err := syscall.BytePtrFromString(promises) + exptr, err := syscall.BytePtrFromString(execpromises) 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 - } - expr = unsafe.Pointer(exptr) - } - - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), + uintptr(unsafe.Pointer(exptr)), 0) if e != 0 { return e } @@ -64,13 +49,7 @@ func Pledge(promises, execpromises string) error { // // For more information see pledge(2). func PledgePromises(promises string) error { - maj, min, err := majmin() - if err != nil { - return err - } - - err = pledgeAvailable(maj, min, "") - if err != nil { + if err := pledgeAvailable(); err != nil { return err } @@ -82,7 +61,8 @@ func PledgePromises(promises string) error { return err } - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), + uintptr(expr), 0) if e != 0 { return e } @@ -96,13 +76,7 @@ func PledgePromises(promises string) error { // // For more information see pledge(2). func PledgeExecpromises(execpromises string) error { - maj, min, err := majmin() - if err != nil { - return err - } - - err = pledgeAvailable(maj, min, execpromises) - if err != nil { + if err := pledgeAvailable(); err != nil { return err } @@ -114,7 +88,8 @@ func PledgeExecpromises(execpromises string) error { return err } - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0) + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), + uintptr(unsafe.Pointer(exptr)), 0) if e != 0 { return e } @@ -147,16 +122,15 @@ func majmin() (major int, minor int, err error) { // pledgeAvailable checks for availability of the pledge(2) syscall // based on the running OpenBSD version. -func pledgeAvailable(maj, min int, execpromises string) error { - // 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) +func pledgeAvailable() error { + maj, min, err := majmin() + if err != nil { + return err } - // 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) + // Require OpenBSD 6.4 as a minimum. + if maj < 6 || (maj == 6 && min <= 3) { + return fmt.Errorf("cannot call Pledge on OpenBSD %d.%d", maj, min) } return nil diff --git a/unix/unveil_openbsd.go b/unix/unveil_openbsd.go index 168d5ae77..2a885187d 100644 --- a/unix/unveil_openbsd.go +++ b/unix/unveil_openbsd.go @@ -5,6 +5,7 @@ package unix import ( + "fmt" "syscall" "unsafe" ) @@ -14,6 +15,9 @@ import ( // Note that the special case of blocking further // unveil calls is handled by UnveilBlock. func Unveil(path string, flags string) error { + if err := supportsUnveil(); err != nil { + return err + } pathPtr, err := syscall.BytePtrFromString(path) if err != nil { return err @@ -32,6 +36,9 @@ func Unveil(path string, flags string) error { // UnveilBlock blocks future unveil calls. // For more information see unveil(2). func UnveilBlock() error { + if err := supportsUnveil(); err != nil { + return err + } // Both pointers must be nil. var pathUnsafe, flagsUnsafe unsafe.Pointer _, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(pathUnsafe), uintptr(flagsUnsafe), 0) @@ -40,3 +47,19 @@ func UnveilBlock() error { } return nil } + +// supportsUnveil checks for availability of the unveil(2) system call based +// on the running OpenBSD version. +func supportsUnveil() error { + maj, min, err := majmin() + if err != nil { + return err + } + + // unveil is not available before 6.4 + if maj < 6 || (maj == 6 && min <= 3) { + return fmt.Errorf("cannot call Unveil on OpenBSD %d.%d", maj, min) + } + + return nil +}