88 "errors"
99 "fmt"
1010 "strconv"
11- "syscall"
12- "unsafe"
1311)
1412
1513// Pledge implements the pledge syscall.
@@ -20,42 +18,46 @@ import (
2018// execpromises must be empty when Pledge is called on OpenBSD
2119// releases predating 6.3, otherwise an error will be returned.
2220//
21+ // On OpenBSD 6.3 and later, an empty execpromises removes all
22+ // execpromises from the process. Use PledgePromises to only set
23+ // promises without setting execpromises.
24+ //
2325// For more information see pledge(2).
2426func Pledge (promises , execpromises string ) error {
2527 maj , min , err := majmin ()
2628 if err != nil {
2729 return err
2830 }
2931
30- err = pledgeAvailable (maj , min , execpromises )
32+ // OS support for execpromises is required only when execpromises is not
33+ // the empty string.
34+ err = supportsExecpromises (maj , min , execpromises != "" )
3135 if err != nil {
3236 return err
3337 }
3438
35- pptr , err := syscall . BytePtrFromString (promises )
39+ _promises , err := BytePtrFromString (promises )
3640 if err != nil {
3741 return err
3842 }
3943
40- // This variable will hold either a nil unsafe.Pointer or
41- // an unsafe.Pointer to a string (execpromises) .
42- var expr unsafe. Pointer
44+ // This variable will hold either a nil pointer or a pointer to the
45+ // NUL-terminated execpromises string.
46+ var _execpromises * byte
4347
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 )
48+ // If we're running on OpenBSD >= 6.3, pass execpromises to the syscall.
49+ // While an empty execpromises string is required by this API on
50+ // OpenBSD <= 6.2 and has no effect, the empty execpromises string
51+ // removes all execpromises on OpenBSD >= 6.3.
52+ if maj > 6 || (maj == 6 && min >= 3 ) {
53+ exptr , err := BytePtrFromString (execpromises )
4754 if err != nil {
4855 return err
4956 }
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
57+ _execpromises = exptr
5658 }
5759
58- return nil
60+ return pledge ( _promises , _execpromises )
5961}
6062
6163// PledgePromises implements the pledge syscall.
@@ -64,62 +66,39 @@ func Pledge(promises, execpromises string) error {
6466//
6567// For more information see pledge(2).
6668func 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 )
69+ _promises , err := BytePtrFromString (promises )
8170 if err != nil {
8271 return err
8372 }
8473
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
74+ return pledge (_promises , nil )
9175}
9276
9377// PledgeExecpromises implements the pledge syscall.
9478//
9579// This changes the execpromises and leaves the promises untouched.
9680//
81+ // The pledge syscall does not accept execpromises on OpenBSD releases
82+ // before 6.3.
83+ //
9784// For more information see pledge(2).
9885func PledgeExecpromises (execpromises string ) error {
9986 maj , min , err := majmin ()
10087 if err != nil {
10188 return err
10289 }
10390
104- err = pledgeAvailable (maj , min , execpromises )
91+ err = supportsExecpromises (maj , min , true )
10592 if err != nil {
10693 return err
10794 }
10895
109- // This variable holds the promises and is always nil.
110- var pptr unsafe.Pointer
111-
112- exptr , err := syscall .BytePtrFromString (execpromises )
96+ _execpromises , err := BytePtrFromString (execpromises )
11397 if err != nil {
11498 return err
11599 }
116100
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
101+ return pledge (nil , _execpromises )
123102}
124103
125104// majmin returns major and minor version number for an OpenBSD system.
@@ -145,17 +124,12 @@ func majmin() (major int, minor int, err error) {
145124 return
146125}
147126
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-
127+ // supportsExecpromises checks for availability of the execpromises argument to
128+ // the pledge(2) syscall based on the running OpenBSD version.
129+ func supportsExecpromises (maj , min int , required bool ) error {
156130 // If OpenBSD <= 6.2 and execpromises is not empty,
157131 // return an error - execpromises is not available before 6.3
158- if (maj < 6 || (maj == 6 && min <= 2 )) && execpromises != "" {
132+ if (maj < 6 || (maj == 6 && min <= 2 )) && required {
159133 return fmt .Errorf ("cannot use execpromises on OpenBSD %d.%d" , maj , min )
160134 }
161135
0 commit comments