8
8
"errors"
9
9
"fmt"
10
10
"strconv"
11
- "syscall"
12
- "unsafe"
13
11
)
14
12
15
13
// Pledge implements the pledge syscall.
@@ -20,42 +18,46 @@ import (
20
18
// execpromises must be empty when Pledge is called on OpenBSD
21
19
// releases predating 6.3, otherwise an error will be returned.
22
20
//
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
+ //
23
25
// For more information see pledge(2).
24
26
func Pledge (promises , execpromises string ) error {
25
27
maj , min , err := majmin ()
26
28
if err != nil {
27
29
return err
28
30
}
29
31
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 != "" )
31
35
if err != nil {
32
36
return err
33
37
}
34
38
35
- pptr , err := syscall . BytePtrFromString (promises )
39
+ _promises , err := BytePtrFromString (promises )
36
40
if err != nil {
37
41
return err
38
42
}
39
43
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
43
47
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 )
47
54
if err != nil {
48
55
return err
49
56
}
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
56
58
}
57
59
58
- return nil
60
+ return pledge ( _promises , _execpromises )
59
61
}
60
62
61
63
// PledgePromises implements the pledge syscall.
@@ -64,62 +66,39 @@ func Pledge(promises, execpromises string) error {
64
66
//
65
67
// For more information see pledge(2).
66
68
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 )
69
+ _promises , err := BytePtrFromString (promises )
81
70
if err != nil {
82
71
return err
83
72
}
84
73
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 )
91
75
}
92
76
93
77
// PledgeExecpromises implements the pledge syscall.
94
78
//
95
79
// This changes the execpromises and leaves the promises untouched.
96
80
//
81
+ // The pledge syscall does not accept execpromises on OpenBSD releases
82
+ // before 6.3.
83
+ //
97
84
// For more information see pledge(2).
98
85
func PledgeExecpromises (execpromises string ) error {
99
86
maj , min , err := majmin ()
100
87
if err != nil {
101
88
return err
102
89
}
103
90
104
- err = pledgeAvailable (maj , min , execpromises )
91
+ err = supportsExecpromises (maj , min , true )
105
92
if err != nil {
106
93
return err
107
94
}
108
95
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 )
113
97
if err != nil {
114
98
return err
115
99
}
116
100
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 )
123
102
}
124
103
125
104
// majmin returns major and minor version number for an OpenBSD system.
@@ -145,17 +124,12 @@ func majmin() (major int, minor int, err error) {
145
124
return
146
125
}
147
126
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 {
156
130
// If OpenBSD <= 6.2 and execpromises is not empty,
157
131
// 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 {
159
133
return fmt .Errorf ("cannot use execpromises on OpenBSD %d.%d" , maj , min )
160
134
}
161
135
0 commit comments