gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

pledge_openbsd.go (3746B)


      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 }