pledge 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG +4 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +19 -15
- data/ext/pledge/pledge.c +24 -9
- data/spec/pledge_spec.rb +26 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7369f71bb2bfdbbea7dd07d98c86f443b8c0a09ddaf13090c6c0a379c2fe6eed
|
4
|
+
data.tar.gz: bea75bb0d79544311c633aeb04ad7bcb3d2061ace0c6f9f0829e05dd387068e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4031731b34fe1c2497cfa84ffad17b698ada329362cbb0f8730ea2bfa4f094c0429150b92364a8764d04eef1397be3cdb7d70145ccc9ea88b6e0dadb425d36b7
|
7
|
+
data.tar.gz: 3509a67789e3876149e8880bc031fdb0d5df2bf111cd65b7f112132b1dd64696ff38ef9f70efc854d5ba99eb4c83d1256b4d68ba5805e879725fc5e6ed14a735
|
data/CHANGELOG
CHANGED
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -8,7 +8,8 @@ use a wide variety of operations on initialization, but
|
|
8
8
|
a fewer number after initialization (when user input will
|
9
9
|
be accepted).
|
10
10
|
|
11
|
-
|
11
|
+
pledge(2) is supported on OpenBSD 5.9+. pledge(2) supports a second
|
12
|
+
argument for execpromises on OpenBSD 6.3+.
|
12
13
|
|
13
14
|
== Usage
|
14
15
|
|
@@ -20,7 +21,7 @@ Then you can use +Pledge.pledge+ as the interface to the pledge(2)
|
|
20
21
|
system call. You pass +Pledge.pledge+ a string containing tokens
|
21
22
|
for the operations you would like to allow (called promises).
|
22
23
|
For example, if you want to give the process the ability to read
|
23
|
-
from the
|
24
|
+
from the file system, but not write to the file system or
|
24
25
|
allow network access:
|
25
26
|
|
26
27
|
Pledge.pledge("rpath")
|
@@ -34,6 +35,18 @@ filesystem access:
|
|
34
35
|
|
35
36
|
Pledge.pledge("inet unix dns")
|
36
37
|
|
38
|
+
If you want to use pledging in a console application such as
|
39
|
+
irb or pry, you must include the tty promise:
|
40
|
+
|
41
|
+
Pledge.pledge("tty rpath")
|
42
|
+
|
43
|
+
You can pass a second string argument containing tokens for
|
44
|
+
the operations you would like to allow in spawned processes
|
45
|
+
(called execpromises). To allow spawning processes that have
|
46
|
+
read/write filesystem access only, but not network access:
|
47
|
+
|
48
|
+
Pledge.pledge("proc exec rpath", "stdio rpath wpath cpath")
|
49
|
+
|
37
50
|
+Pledge+ is a module that extends itself, you can include it
|
38
51
|
in other classes:
|
39
52
|
|
@@ -43,12 +56,12 @@ in other classes:
|
|
43
56
|
== Options
|
44
57
|
|
45
58
|
See the pledge(2) man page for a description of the allowed
|
46
|
-
promises in the
|
59
|
+
promises in the strings passed to +Pledge.pledge+.
|
47
60
|
|
48
61
|
Using an unsupported promise will raise an exception. The "stdio"
|
49
|
-
promise is added automatically
|
50
|
-
|
51
|
-
|
62
|
+
promise is added automatically to the current process's promises,
|
63
|
+
as ruby does not function without it, but it is not added to
|
64
|
+
the execpromises (as you can execute non-ruby programs).
|
52
65
|
|
53
66
|
== Reporting issues/bugs
|
54
67
|
|
@@ -85,15 +98,6 @@ task. This will compile the library if not already compiled.
|
|
85
98
|
|
86
99
|
rake
|
87
100
|
|
88
|
-
== Known Issues
|
89
|
-
|
90
|
-
* You cannot create new threads after running +Pledge.pledge+, as
|
91
|
-
it uses syscalls that are not currently allowed by pledge(2). +fork+
|
92
|
-
still works, assuming you are using the +proc+ pledge.
|
93
|
-
|
94
|
-
* You cannot currently test +Pledge.pledge+ in irb/pry, as they use an
|
95
|
-
ioctl that is not currently allowed by pledge(2).
|
96
|
-
|
97
101
|
== Author
|
98
102
|
|
99
103
|
Jeremy Evans <code@jeremyevans.net>
|
data/ext/pledge/pledge.c
CHANGED
@@ -6,16 +6,31 @@ static VALUE ePledgeInvalidPromise;
|
|
6
6
|
static VALUE ePledgePermissionIncreaseAttempt;
|
7
7
|
static VALUE ePledgeError;
|
8
8
|
|
9
|
-
static VALUE rb_pledge(VALUE
|
10
|
-
|
11
|
-
|
9
|
+
static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
10
|
+
VALUE promises = Qnil;
|
11
|
+
VALUE execpromises = Qnil;
|
12
|
+
const char * prom = NULL;
|
13
|
+
const char * execprom = NULL;
|
12
14
|
|
13
|
-
|
14
|
-
rb_str_cat2(promises, " stdio");
|
15
|
-
promises = rb_funcall(promises, rb_intern("strip"), 0);
|
16
|
-
SafeStringValue(promises);
|
15
|
+
rb_scan_args(argc, argv, "11", &promises, &execpromises);
|
17
16
|
|
18
|
-
if (
|
17
|
+
if (!NIL_P(promises)) {
|
18
|
+
SafeStringValue(promises);
|
19
|
+
promises = rb_str_dup(promises);
|
20
|
+
|
21
|
+
/* required for ruby to work */
|
22
|
+
rb_str_cat2(promises, " stdio");
|
23
|
+
promises = rb_funcall(promises, rb_intern("strip"), 0);
|
24
|
+
SafeStringValue(promises);
|
25
|
+
prom = RSTRING_PTR(promises);
|
26
|
+
}
|
27
|
+
|
28
|
+
if (!NIL_P(execpromises)) {
|
29
|
+
SafeStringValue(execpromises);
|
30
|
+
execprom = RSTRING_PTR(execpromises);
|
31
|
+
}
|
32
|
+
|
33
|
+
if (pledge(prom, execprom) != 0) {
|
19
34
|
switch(errno) {
|
20
35
|
case EINVAL:
|
21
36
|
rb_raise(ePledgeInvalidPromise, "invalid promise in promises string");
|
@@ -32,7 +47,7 @@ static VALUE rb_pledge(VALUE pledge_class, VALUE promises) {
|
|
32
47
|
void Init_pledge(void) {
|
33
48
|
VALUE cPledge;
|
34
49
|
cPledge = rb_define_module("Pledge");
|
35
|
-
rb_define_method(cPledge, "pledge", rb_pledge, 1);
|
50
|
+
rb_define_method(cPledge, "pledge", rb_pledge, -1);
|
36
51
|
rb_extend_object(cPledge, cPledge);
|
37
52
|
ePledgeError = rb_define_class_under(cPledge, "Error", rb_eStandardError);
|
38
53
|
ePledgeInvalidPromise = rb_define_class_under(cPledge, "InvalidPromise", ePledgeError);
|
data/spec/pledge_spec.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require './lib/pledge'
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
+
ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
|
4
5
|
gem 'minitest'
|
5
6
|
require 'minitest/autorun'
|
6
7
|
|
7
8
|
RUBY = ENV['RUBY'] || 'ruby'
|
8
9
|
|
9
10
|
describe "Pledge.pledge" do
|
11
|
+
def execpledged(promises, execpromises, code)
|
12
|
+
system(RUBY, '-I', 'lib', '-r', 'pledge', '-e', "Pledge.pledge(#{promises.inspect}, #{execpromises.inspect}); #{code}")
|
13
|
+
end
|
14
|
+
|
10
15
|
def _pledged(status, promises, code)
|
11
16
|
system(RUBY, '-I', 'lib', '-r', 'pledge', '-e', "Pledge.pledge(#{promises.inspect}); #{code}").must_equal status
|
12
17
|
end
|
@@ -109,4 +114,25 @@ describe "Pledge.pledge" do
|
|
109
114
|
end
|
110
115
|
us.accept.read.must_equal 't'
|
111
116
|
end
|
117
|
+
|
118
|
+
it "should raise ArgumentError if given in invalid number of arguments" do
|
119
|
+
proc{Pledge.pledge()}.must_raise ArgumentError
|
120
|
+
proc{Pledge.pledge("", "", "")}.must_raise ArgumentError
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should handle both promises and execpromises arguments" do
|
124
|
+
execpledged("proc exec rpath", "stdio rpath", "exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE') ? 0 : 1)").must_equal true
|
125
|
+
execpledged("proc exec", "stdio rpath", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE') ? 0 : 1)").must_equal false
|
126
|
+
execpledged("proc exec rpath", "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE') ? 0 : 1)").must_equal false
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should handle nil arguments" do
|
130
|
+
Pledge.pledge(nil).must_be_nil
|
131
|
+
Pledge.pledge(nil, nil).must_be_nil
|
132
|
+
execpledged("proc exec rpath", nil, "`cat MIT-LICENSE`").must_equal true
|
133
|
+
execpledged("", nil, "`cat MIT-LICENSE`").must_equal false
|
134
|
+
execpledged(nil, "stdio rpath", "`cat MIT-LICENSE`").must_equal true
|
135
|
+
execpledged(nil, "stdio", "File.read('MIT-LICENSE')").must_equal true
|
136
|
+
execpledged(nil, "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE') ? 0 : 1)").must_equal false
|
137
|
+
end
|
112
138
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pledge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
pledge exposes OpenBSD's pledge(2) system call to ruby, allowing a
|
@@ -60,8 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
requirements: []
|
63
|
-
|
64
|
-
rubygems_version: 2.5.1
|
63
|
+
rubygems_version: 3.0.3
|
65
64
|
signing_key:
|
66
65
|
specification_version: 4
|
67
66
|
summary: Restrict system operations on OpenBSD
|