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,48 @@ 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 )
31
- if err != nil {
32
- return err
32
+ // OS support for execpromises is required only when execpromises is not
33
+ // the empty string.
34
+ if execpromises != "" {
35
+ err = supportsExecpromises (maj , min )
36
+ if err != nil {
37
+ return err
38
+ }
33
39
}
34
40
35
- pptr , err := syscall . BytePtrFromString (promises )
41
+ promisesBytes , err := BytePtrFromString (promises )
36
42
if err != nil {
37
43
return err
38
44
}
39
45
40
- // This variable will hold either a nil unsafe.Pointer or
41
- // an unsafe.Pointer to a string (execpromises) .
42
- var expr unsafe. Pointer
46
+ // This variable will hold either a nil pointer or a pointer to the
47
+ // NUL-terminated execpromises string.
48
+ var execpromisesBytes * byte
43
49
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 )
50
+ // If we're running on OpenBSD >= 6.3, pass execpromises to the syscall.
51
+ // While an empty execpromises string is required by this API on
52
+ // OpenBSD <= 6.2 and has no effect, the empty execpromises string
53
+ // removes all execpromises on OpenBSD >= 6.3.
54
+ if maj > 6 || (maj == 6 && min >= 3 ) {
55
+ exptr , err := BytePtrFromString (execpromises )
47
56
if err != nil {
48
57
return err
49
58
}
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
59
+ execpromisesBytes = exptr
56
60
}
57
61
58
- return nil
62
+ return pledge ( promisesBytes , execpromisesBytes )
59
63
}
60
64
61
65
// PledgePromises implements the pledge syscall.
@@ -64,62 +68,39 @@ func Pledge(promises, execpromises string) error {
64
68
//
65
69
// For more information see pledge(2).
66
70
func PledgePromises (promises string ) error {
67
- maj , min , err := majmin ()
68
- if err != nil {
69
- return err
70
- }
71
-
72
- err = pledgeAvailable (maj , min , "" )
71
+ promisesBytes , err := BytePtrFromString (promises )
73
72
if err != nil {
74
73
return err
75
74
}
76
75
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
76
+ return pledge (promisesBytes , nil )
91
77
}
92
78
93
79
// PledgeExecpromises implements the pledge syscall.
94
80
//
95
81
// This changes the execpromises and leaves the promises untouched.
96
82
//
83
+ // The pledge syscall does not accept execpromises on OpenBSD releases
84
+ // before 6.3.
85
+ //
97
86
// For more information see pledge(2).
98
87
func PledgeExecpromises (execpromises string ) error {
99
88
maj , min , err := majmin ()
100
89
if err != nil {
101
90
return err
102
91
}
103
92
104
- err = pledgeAvailable (maj , min , execpromises )
93
+ err = supportsExecpromises (maj , min )
105
94
if err != nil {
106
95
return err
107
96
}
108
97
109
- // This variable holds the promises and is always nil.
110
- var pptr unsafe.Pointer
111
-
112
- exptr , err := syscall .BytePtrFromString (execpromises )
98
+ execpromisesBytes , err := BytePtrFromString (execpromises )
113
99
if err != nil {
114
100
return err
115
101
}
116
102
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
103
+ return pledge (nil , execpromisesBytes )
123
104
}
124
105
125
106
// majmin returns major and minor version number for an OpenBSD system.
@@ -145,17 +126,11 @@ func majmin() (major int, minor int, err error) {
145
126
return
146
127
}
147
128
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 != "" {
129
+ // supportsExecpromises checks for availability of the execpromises argument to
130
+ // the pledge(2) syscall based on the running OpenBSD version.
131
+ func supportsExecpromises (maj , min int ) error {
132
+ // execpromises is not available before 6.3
133
+ if maj < 6 || (maj == 6 && min <= 2 ) {
159
134
return fmt .Errorf ("cannot use execpromises on OpenBSD %d.%d" , maj , min )
160
135
}
161
136
0 commit comments