vendor/golang.org/x/sys/unix/pledge_openbsd.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
       
     1 // Copyright 2016 The Go Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style
       
     3 // license that can be found in the LICENSE file.
       
     4 
       
     5 package unix
       
     6 
       
     7 import (
       
     8 	"errors"
       
     9 	"fmt"
       
    10 	"strconv"
       
    11 	"syscall"
       
    12 	"unsafe"
       
    13 )
       
    14 
       
    15 // Pledge implements the pledge syscall.
       
    16 //
       
    17 // The pledge syscall does not accept execpromises on OpenBSD releases
       
    18 // before 6.3.
       
    19 //
       
    20 // execpromises must be empty when Pledge is called on OpenBSD
       
    21 // releases predating 6.3, otherwise an error will be returned.
       
    22 //
       
    23 // For more information see pledge(2).
       
    24 func Pledge(promises, execpromises string) error {
       
    25 	maj, min, err := majmin()
       
    26 	if err != nil {
       
    27 		return err
       
    28 	}
       
    29 
       
    30 	err = pledgeAvailable(maj, min, execpromises)
       
    31 	if err != nil {
       
    32 		return err
       
    33 	}
       
    34 
       
    35 	pptr, err := syscall.BytePtrFromString(promises)
       
    36 	if err != nil {
       
    37 		return err
       
    38 	}
       
    39 
       
    40 	// This variable will hold either a nil unsafe.Pointer or
       
    41 	// an unsafe.Pointer to a string (execpromises).
       
    42 	var expr unsafe.Pointer
       
    43 
       
    44 	// If we're running on OpenBSD > 6.2, pass execpromises to the syscall.
       
    45 	if maj > 6 || (maj == 6 && min > 2) {
       
    46 		exptr, err := syscall.BytePtrFromString(execpromises)
       
    47 		if err != nil {
       
    48 			return err
       
    49 		}
       
    50 		expr = unsafe.Pointer(exptr)
       
    51 	}
       
    52 
       
    53 	_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
       
    54 	if e != 0 {
       
    55 		return e
       
    56 	}
       
    57 
       
    58 	return nil
       
    59 }
       
    60 
       
    61 // PledgePromises implements the pledge syscall.
       
    62 //
       
    63 // This changes the promises and leaves the execpromises untouched.
       
    64 //
       
    65 // For more information see pledge(2).
       
    66 func PledgePromises(promises string) error {
       
    67 	maj, min, err := majmin()
       
    68 	if err != nil {
       
    69 		return err
       
    70 	}
       
    71 
       
    72 	err = pledgeAvailable(maj, min, "")
       
    73 	if err != nil {
       
    74 		return err
       
    75 	}
       
    76 
       
    77 	// This variable holds the execpromises and is always nil.
       
    78 	var expr unsafe.Pointer
       
    79 
       
    80 	pptr, err := syscall.BytePtrFromString(promises)
       
    81 	if err != nil {
       
    82 		return err
       
    83 	}
       
    84 
       
    85 	_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
       
    86 	if e != 0 {
       
    87 		return e
       
    88 	}
       
    89 
       
    90 	return nil
       
    91 }
       
    92 
       
    93 // PledgeExecpromises implements the pledge syscall.
       
    94 //
       
    95 // This changes the execpromises and leaves the promises untouched.
       
    96 //
       
    97 // For more information see pledge(2).
       
    98 func PledgeExecpromises(execpromises string) error {
       
    99 	maj, min, err := majmin()
       
   100 	if err != nil {
       
   101 		return err
       
   102 	}
       
   103 
       
   104 	err = pledgeAvailable(maj, min, execpromises)
       
   105 	if err != nil {
       
   106 		return err
       
   107 	}
       
   108 
       
   109 	// This variable holds the promises and is always nil.
       
   110 	var pptr unsafe.Pointer
       
   111 
       
   112 	exptr, err := syscall.BytePtrFromString(execpromises)
       
   113 	if err != nil {
       
   114 		return err
       
   115 	}
       
   116 
       
   117 	_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0)
       
   118 	if e != 0 {
       
   119 		return e
       
   120 	}
       
   121 
       
   122 	return nil
       
   123 }
       
   124 
       
   125 // majmin returns major and minor version number for an OpenBSD system.
       
   126 func majmin() (major int, minor int, err error) {
       
   127 	var v Utsname
       
   128 	err = Uname(&v)
       
   129 	if err != nil {
       
   130 		return
       
   131 	}
       
   132 
       
   133 	major, err = strconv.Atoi(string(v.Release[0]))
       
   134 	if err != nil {
       
   135 		err = errors.New("cannot parse major version number returned by uname")
       
   136 		return
       
   137 	}
       
   138 
       
   139 	minor, err = strconv.Atoi(string(v.Release[2]))
       
   140 	if err != nil {
       
   141 		err = errors.New("cannot parse minor version number returned by uname")
       
   142 		return
       
   143 	}
       
   144 
       
   145 	return
       
   146 }
       
   147 
       
   148 // pledgeAvailable checks for availability of the pledge(2) syscall
       
   149 // based on the running OpenBSD version.
       
   150 func pledgeAvailable(maj, min int, execpromises string) error {
       
   151 	// If OpenBSD <= 5.9, pledge is not available.
       
   152 	if (maj == 5 && min != 9) || maj < 5 {
       
   153 		return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min)
       
   154 	}
       
   155 
       
   156 	// If OpenBSD <= 6.2 and execpromises is not empty,
       
   157 	// return an error - execpromises is not available before 6.3
       
   158 	if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" {
       
   159 		return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min)
       
   160 	}
       
   161 
       
   162 	return nil
       
   163 }