pledge_openbsd.go raw

   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  )
  12  
  13  // Pledge implements the pledge syscall.
  14  //
  15  // This changes both the promises and execpromises; use PledgePromises or
  16  // PledgeExecpromises to only change the promises or execpromises
  17  // respectively.
  18  //
  19  // For more information see pledge(2).
  20  func Pledge(promises, execpromises string) error {
  21  	if err := pledgeAvailable(); err != nil {
  22  		return err
  23  	}
  24  
  25  	pptr, err := BytePtrFromString(promises)
  26  	if err != nil {
  27  		return err
  28  	}
  29  
  30  	exptr, err := BytePtrFromString(execpromises)
  31  	if err != nil {
  32  		return err
  33  	}
  34  
  35  	return pledge(pptr, exptr)
  36  }
  37  
  38  // PledgePromises implements the pledge syscall.
  39  //
  40  // This changes the promises and leaves the execpromises untouched.
  41  //
  42  // For more information see pledge(2).
  43  func PledgePromises(promises string) error {
  44  	if err := pledgeAvailable(); err != nil {
  45  		return err
  46  	}
  47  
  48  	pptr, err := BytePtrFromString(promises)
  49  	if err != nil {
  50  		return err
  51  	}
  52  
  53  	return pledge(pptr, nil)
  54  }
  55  
  56  // PledgeExecpromises implements the pledge syscall.
  57  //
  58  // This changes the execpromises and leaves the promises untouched.
  59  //
  60  // For more information see pledge(2).
  61  func PledgeExecpromises(execpromises string) error {
  62  	if err := pledgeAvailable(); err != nil {
  63  		return err
  64  	}
  65  
  66  	exptr, err := BytePtrFromString(execpromises)
  67  	if err != nil {
  68  		return err
  69  	}
  70  
  71  	return pledge(nil, exptr)
  72  }
  73  
  74  // majmin returns major and minor version number for an OpenBSD system.
  75  func majmin() (major int, minor int, err error) {
  76  	var v Utsname
  77  	err = Uname(&v)
  78  	if err != nil {
  79  		return
  80  	}
  81  
  82  	major, err = strconv.Atoi(string(v.Release[0]))
  83  	if err != nil {
  84  		err = errors.New("cannot parse major version number returned by uname")
  85  		return
  86  	}
  87  
  88  	minor, err = strconv.Atoi(string(v.Release[2]))
  89  	if err != nil {
  90  		err = errors.New("cannot parse minor version number returned by uname")
  91  		return
  92  	}
  93  
  94  	return
  95  }
  96  
  97  // pledgeAvailable checks for availability of the pledge(2) syscall
  98  // based on the running OpenBSD version.
  99  func pledgeAvailable() error {
 100  	maj, min, err := majmin()
 101  	if err != nil {
 102  		return err
 103  	}
 104  
 105  	// Require OpenBSD 6.4 as a minimum.
 106  	if maj < 6 || (maj == 6 && min <= 3) {
 107  		return fmt.Errorf("cannot call Pledge on OpenBSD %d.%d", maj, min)
 108  	}
 109  
 110  	return nil
 111  }
 112